]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / h264.c
index 85787f40d15dd1145c4323981d18d29ac85db64e..0c840183b405b1c4fd1664bc941b3f2a8654f477 100644 (file)
@@ -1615,7 +1615,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
        || (h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > INT_MIN && h->last_pocs[MAX_DELAYED_PIC_COUNT-1] - h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > 2))
         out_of_order = FFMAX(out_of_order, 1);
     if(s->avctx->has_b_frames < out_of_order && !h->sps.bitstream_restriction_flag){
-        av_log(s->avctx, AV_LOG_WARNING, "Increasing reorder buffer to %d\n", out_of_order);
+        av_log(s->avctx, AV_LOG_VERBOSE, "Increasing reorder buffer to %d\n", out_of_order);
         s->avctx->has_b_frames = out_of_order;
         s->low_delay = 0;
     }
@@ -2719,19 +2719,19 @@ static void init_scan_tables(H264Context *h)
 #undef T
     }
     if (h->sps.transform_bypass) { // FIXME same ugly
-        h->zigzag_scan_q0          = zigzag_scan;
-        h->zigzag_scan8x8_q0       = ff_zigzag_direct;
-        h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc;
-        h->field_scan_q0           = field_scan;
-        h->field_scan8x8_q0        = field_scan8x8;
-        h->field_scan8x8_cavlc_q0  = field_scan8x8_cavlc;
+        memcpy(h->zigzag_scan_q0          , zigzag_scan             , sizeof(h->zigzag_scan_q0         ));
+        memcpy(h->zigzag_scan8x8_q0       , ff_zigzag_direct        , sizeof(h->zigzag_scan8x8_q0      ));
+        memcpy(h->zigzag_scan8x8_cavlc_q0 , zigzag_scan8x8_cavlc    , sizeof(h->zigzag_scan8x8_cavlc_q0));
+        memcpy(h->field_scan_q0           , field_scan              , sizeof(h->field_scan_q0          ));
+        memcpy(h->field_scan8x8_q0        , field_scan8x8           , sizeof(h->field_scan8x8_q0       ));
+        memcpy(h->field_scan8x8_cavlc_q0  , field_scan8x8_cavlc     , sizeof(h->field_scan8x8_cavlc_q0 ));
     } else {
-        h->zigzag_scan_q0          = h->zigzag_scan;
-        h->zigzag_scan8x8_q0       = h->zigzag_scan8x8;
-        h->zigzag_scan8x8_cavlc_q0 = h->zigzag_scan8x8_cavlc;
-        h->field_scan_q0           = h->field_scan;
-        h->field_scan8x8_q0        = h->field_scan8x8;
-        h->field_scan8x8_cavlc_q0  = h->field_scan8x8_cavlc;
+        memcpy(h->zigzag_scan_q0          , h->zigzag_scan          , sizeof(h->zigzag_scan_q0         ));
+        memcpy(h->zigzag_scan8x8_q0       , h->zigzag_scan8x8       , sizeof(h->zigzag_scan8x8_q0      ));
+        memcpy(h->zigzag_scan8x8_cavlc_q0 , h->zigzag_scan8x8_cavlc , sizeof(h->zigzag_scan8x8_cavlc_q0));
+        memcpy(h->field_scan_q0           , h->field_scan           , sizeof(h->field_scan_q0          ));
+        memcpy(h->field_scan8x8_q0        , h->field_scan8x8        , sizeof(h->field_scan8x8_q0       ));
+        memcpy(h->field_scan8x8_cavlc_q0  , h->field_scan8x8_cavlc  , sizeof(h->field_scan8x8_cavlc_q0 ));
     }
 }
 
@@ -2969,7 +2969,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     s->width  = 16 * s->mb_width;
     s->height = 16 * s->mb_height;
 
-
     if(must_reinit) {
         free_tables(h, 0);
         flush_dpb(s->avctx);
@@ -2983,9 +2982,19 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                    "Cannot (re-)initialize context during parallel decoding.\n");
             return -1;
         }
-        avcodec_set_dimensions(s->avctx, s->width, s->height);
-        s->avctx->width  -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
-        s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
+        if(   FFALIGN(s->avctx->width , 16                                 ) == s->width
+           && FFALIGN(s->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == s->height
+           && !h->sps.crop_right && !h->sps.crop_bottom
+           && (s->avctx->width != s->width || s->avctx->height && s->height)
+        ) {
+            av_log(h->s.avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n");
+            s->avctx->coded_width  = s->width;
+            s->avctx->coded_height = s->height;
+        } else{
+            avcodec_set_dimensions(s->avctx, s->width, s->height);
+            s->avctx->width  -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
+            s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
+        }
         s->avctx->sample_aspect_ratio = h->sps.sar;
         av_assert0(s->avctx->sample_aspect_ratio.den);
 
@@ -3374,7 +3383,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     h->ref_count[1] = h->pps.ref_count[1];
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
-        unsigned max = s->picture_structure == PICT_FRAME ? 15 : 31;
+        unsigned max[2];
+        max[0] = max[1] = s->picture_structure == PICT_FRAME ? 15 : 31;
 
         if (h->slice_type_nos == AV_PICTURE_TYPE_B)
             h->direct_spatial_mv_pred = get_bits1(&s->gb);
@@ -3384,10 +3394,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
             h->ref_count[0] = get_ue_golomb(&s->gb) + 1;
             if (h->slice_type_nos == AV_PICTURE_TYPE_B)
                 h->ref_count[1] = get_ue_golomb(&s->gb) + 1;
+            else
+                // full range is spec-ok in this case, even for frames
+                max[1] = 31;
         }
 
-        if (h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){
-            av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
+        if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){
+            av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]);
             h->ref_count[0] = h->ref_count[1] = 1;
             return AVERROR_INVALIDDATA;
         }
@@ -4032,7 +4045,9 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                     loop_filter(h, lf_x_start, s->mb_x + 1);
                 return 0;
             }
-            if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
+            if (h->cabac.bytestream > h->cabac.bytestream_end + 2 )
+                av_log(h->s.avctx, AV_LOG_DEBUG, "bytestream overread %td\n", h->cabac.bytestream_end - h->cabac.bytestream);
+            if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 4) {
                 av_log(h->s.avctx, AV_LOG_ERROR,
                        "error while decoding MB %d %d, bytestream (%td)\n",
                        s->mb_x, s->mb_y,
@@ -4399,6 +4414,9 @@ again:
                 init_get_bits(&hx->inter_gb, ptr, bit_length);
                 hx->inter_gb_ptr = &hx->inter_gb;
 
+                av_log(h->s.avctx, AV_LOG_ERROR, "Partitioned H.264 support is incomplete\n");
+                return AVERROR_PATCHWELCOME;
+
                 if (hx->redundant_pic_count == 0 &&
                     hx->intra_gb_ptr &&
                     hx->s.data_partitioning &&