]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264dec.c
audiodsp: x86: Remove pointless header file
[ffmpeg] / libavcodec / h264dec.c
index 1086eab8d3fc0a99b2bdee9a1463bdc091c386cf..330a74dcb4a14c5b95fd5ebb945cc32ded48e0f7 100644 (file)
@@ -478,7 +478,7 @@ static void flush_dpb(AVCodecContext *avctx)
 static int get_last_needed_nal(H264Context *h)
 {
     int nals_needed = 0;
-    int i;
+    int i, ret;
 
     for (i = 0; i < h->pkt.nb_nals; i++) {
         H2645NAL *nal = &h->pkt.nals[i];
@@ -496,7 +496,14 @@ static int get_last_needed_nal(H264Context *h)
         case H264_NAL_DPA:
         case H264_NAL_IDR_SLICE:
         case H264_NAL_SLICE:
-            init_get_bits(&gb, nal->data + 1, (nal->size - 1) * 8);
+            ret = init_get_bits8(&gb, nal->data + 1, nal->size - 1);
+            if (ret < 0) {
+                av_log(h->avctx, AV_LOG_ERROR, "Invalid zero-sized VCL NAL unit\n");
+                if (h->avctx->err_recognition & AV_EF_EXPLODE)
+                    return ret;
+
+                break;
+            }
             if (!get_ue_golomb(&gb))
                 nals_needed = i;
         }
@@ -523,7 +530,24 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR,
                "Error splitting the input into NAL units.\n");
-        return ret;
+
+        /* There are samples in the wild with mp4-style extradata, but Annex B
+         * data in the packets. If we fail parsing the packet as mp4, try it again
+         * as Annex B. */
+        if (h->is_avc && !(avctx->err_recognition & AV_EF_EXPLODE)) {
+            int err = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, 0, 0,
+                                            avctx->codec_id);
+            if (err >= 0) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "The stream seems to contain AVCC extradata with Annex B "
+                       "formatted data, which is invalid.");
+                h->is_avc = 0;
+                ret       = 0;
+            }
+        }
+
+        if (ret < 0)
+            return ret;
     }
 
     if (avctx->active_thread_type & FF_THREAD_FRAME)
@@ -550,16 +574,17 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
                 break;
 
             if (avctx->active_thread_type & FF_THREAD_FRAME && !h->avctx->hwaccel &&
-                i >= nals_needed) {
+                i >= nals_needed && !h->setup_finished && h->cur_pic_ptr) {
                 ff_thread_finish_setup(avctx);
                 h->setup_finished = 1;
             }
 
             max_slice_ctx = avctx->hwaccel ? 1 : h->nb_slice_ctx;
             if (h->nb_slice_ctx_queued == max_slice_ctx) {
-                if (avctx->hwaccel)
+                if (avctx->hwaccel) {
                     ret = avctx->hwaccel->decode_slice(avctx, nal->raw_data, nal->raw_size);
-                else
+                    h->nb_slice_ctx_queued = 0;
+                } else
                     ret = ff_h264_execute_decode_slices(h);
                 if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                     goto end;