]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264_slice.c
Merge commit '050324d020f843ce333276ebb6f27cc6026f37d0'
[ffmpeg] / libavcodec / h264_slice.c
index 39b3722d450c93ede0d423f52df48929f647618c..ac3c50ce515ec716db7f3f5b7df0d0a4e9bd9ae6 100644 (file)
@@ -232,8 +232,6 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
     if (ret < 0)
         goto fail;
 
-    h->linesize   = pic->f.linesize[0];
-    h->uvlinesize = pic->f.linesize[1];
     pic->crop     = h->sps.crop;
     pic->crop_top = h->sps.crop_top;
     pic->crop_left= h->sps.crop_left;
@@ -248,7 +246,7 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
             pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;
         }
     }
-    if (!h->avctx->hwaccel && CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY && pic->f.data[2]) {
+    if (CONFIG_GRAY && !h->avctx->hwaccel && h->flags & CODEC_FLAG_GRAY && pic->f.data[2]) {
         int h_chroma_shift, v_chroma_shift;
         av_pix_fmt_get_chroma_sub_sample(pic->f.format,
                                          &h_chroma_shift, &v_chroma_shift);
@@ -460,11 +458,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
          h->sps.chroma_format_idc != h1->sps.chroma_format_idc ||
          h->sps.colorspace        != h1->sps.colorspace)) {
 
-        /* set bits_per_raw_sample to the previous value. the check for changed
-         * bit depth in h264_set_parameter_from_sps() uses it and sets it to
-         * the current value */
-        h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
-
         h->width     = h1->width;
         h->height    = h1->height;
         h->mb_height = h1->mb_height;
@@ -496,10 +489,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
         h->cur_chroma_format_idc = h1->cur_chroma_format_idc;
 #endif
     }
-    /* update linesize on resize for h264. The h264 decoder doesn't
-     * necessarily call ff_mpv_frame_start in the new thread */
-    h->linesize   = h1->linesize;
-    h->uvlinesize = h1->uvlinesize;
 
     /* copy block_offset since frame_start may not be called */
     memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
@@ -594,6 +583,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
             return ret;
     }
 
+    h->enable_er       = h1->enable_er;
     h->workaround_bugs = h1->workaround_bugs;
     h->low_delay       = h1->low_delay;
     h->droppable       = h1->droppable;
@@ -717,23 +707,26 @@ static int h264_frame_start(H264Context *h)
     if ((ret = ff_h264_ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0)
         return ret;
 
-    if (CONFIG_ERROR_RESILIENCE) {
+    for (i = 0; i < h->nb_slice_ctx; i++) {
+        h->slice_ctx[i].linesize   = h->cur_pic_ptr->f.linesize[0];
+        h->slice_ctx[i].uvlinesize = h->cur_pic_ptr->f.linesize[1];
+    }
+
+    if (CONFIG_ERROR_RESILIENCE && h->enable_er) {
         ff_er_frame_start(&h->slice_ctx[0].er);
         ff_h264_set_erpic(&h->slice_ctx[0].er.last_pic, NULL);
         ff_h264_set_erpic(&h->slice_ctx[0].er.next_pic, NULL);
     }
 
-    assert(h->linesize && h->uvlinesize);
-
     for (i = 0; i < 16; i++) {
-        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
-        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3);
     }
     for (i = 0; i < 16; i++) {
         h->block_offset[16 + i]      =
-        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + 16 + i] =
-        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3);
     }
 
     /* We mark the current picture as non-reference after allocating it, so
@@ -893,7 +886,7 @@ static void implicit_weight_table(const H264Context *h, H264SliceContext *sl, in
         int poc0 = sl->ref_list[0][ref0].poc;
         for (ref1 = ref_start; ref1 < ref_count1; ref1++) {
             int w = 32;
-            if (!sl->ref_list[0][ref0].long_ref && !sl->ref_list[1][ref1].long_ref) {
+            if (!sl->ref_list[0][ref0].parent->long_ref && !sl->ref_list[1][ref1].parent->long_ref) {
                 int poc1 = sl->ref_list[1][ref1].poc;
                 int td   = av_clip_int8(poc1 - poc0);
                 if (td) {
@@ -1213,11 +1206,21 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
     first_mb_in_slice = get_ue_golomb_long(&sl->gb);
 
     if (first_mb_in_slice == 0) { // FIXME better field boundary detection
-        if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
-            ff_h264_field_end(h, sl, 1);
+        if (h->current_slice) {
+            if (h->cur_pic_ptr && FIELD_PICTURE(h) && h->first_field) {
+                ff_h264_field_end(h, sl, 1);
+                h->current_slice = 0;
+            } else if (h->cur_pic_ptr && !FIELD_PICTURE(h) && !h->first_field && h->nal_unit_type  == NAL_IDR_SLICE) {
+                av_log(h, AV_LOG_WARNING, "Broken frame packetizing\n");
+                ff_h264_field_end(h, sl, 1);
+                h->current_slice = 0;
+                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
+                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
+                h->cur_pic_ptr = NULL;
+            } else
+                return AVERROR_INVALIDDATA;
         }
 
-        h->current_slice = 0;
         if (!h->first_field) {
             if (h->cur_pic_ptr && !h->droppable) {
                 ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
@@ -1306,7 +1309,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
 
         if (h->mb_width  != h->sps.mb_width ||
             h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||
-            h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+            h->cur_bit_depth_luma    != h->sps.bit_depth_luma ||
             h->cur_chroma_format_idc != h->sps.chroma_format_idc
         )
             needs_reinit = 1;
@@ -1328,12 +1331,13 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
     must_reinit = (h->context_initialized &&
                     (   16*h->sps.mb_width != h->avctx->coded_width
                      || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != h->avctx->coded_height
-                     || h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma
+                     || h->cur_bit_depth_luma    != h->sps.bit_depth_luma
                      || h->cur_chroma_format_idc != h->sps.chroma_format_idc
                      || h->mb_width  != h->sps.mb_width
                      || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag)
                     ));
-    if (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0)))
+    if (h->avctx->pix_fmt == AV_PIX_FMT_NONE
+        || (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0))))
         must_reinit = 1;
 
     if (first_slice && av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio))
@@ -1869,9 +1873,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
         for (i = 0; i < 16; i++) {
             id_list[i] = 60;
             if (j < sl->list_count && i < sl->ref_count[j] &&
-                sl->ref_list[j][i].f.buf[0]) {
+                sl->ref_list[j][i].parent->f.buf[0]) {
                 int k;
-                AVBuffer *buf = sl->ref_list[j][i].f.buf[0]->buffer;
+                AVBuffer *buf = sl->ref_list[j][i].parent->f.buf[0]->buffer;
                 for (k = 0; k < h->short_ref_count; k++)
                     if (h->short_ref[k]->f.buf[0]->buffer == buf) {
                         id_list[i] = k;
@@ -2198,26 +2202,26 @@ static void loop_filter(const H264Context *h, H264SliceContext *sl, int start_x,
                 sl->mb_x = mb_x;
                 sl->mb_y = mb_y;
                 dest_y  = h->cur_pic.f.data[0] +
-                          ((mb_x << pixel_shift) + mb_y * h->linesize) * 16;
+                          ((mb_x << pixel_shift) + mb_y * sl->linesize) * 16;
                 dest_cb = h->cur_pic.f.data[1] +
                           (mb_x << pixel_shift) * (8 << CHROMA444(h)) +
-                          mb_y * h->uvlinesize * block_h;
+                          mb_y * sl->uvlinesize * block_h;
                 dest_cr = h->cur_pic.f.data[2] +
                           (mb_x << pixel_shift) * (8 << CHROMA444(h)) +
-                          mb_y * h->uvlinesize * block_h;
+                          mb_y * sl->uvlinesize * block_h;
                 // FIXME simplify above
 
                 if (MB_FIELD(sl)) {
-                    linesize   = sl->mb_linesize   = h->linesize   * 2;
-                    uvlinesize = sl->mb_uvlinesize = h->uvlinesize * 2;
+                    linesize   = sl->mb_linesize   = sl->linesize   * 2;
+                    uvlinesize = sl->mb_uvlinesize = sl->uvlinesize * 2;
                     if (mb_y & 1) { // FIXME move out of this function?
-                        dest_y  -= h->linesize   * 15;
-                        dest_cb -= h->uvlinesize * (block_h - 1);
-                        dest_cr -= h->uvlinesize * (block_h - 1);
+                        dest_y  -= sl->linesize   * 15;
+                        dest_cb -= sl->uvlinesize * (block_h - 1);
+                        dest_cr -= sl->uvlinesize * (block_h - 1);
                     }
                 } else {
-                    linesize   = sl->mb_linesize   = h->linesize;
-                    uvlinesize = sl->mb_uvlinesize = h->uvlinesize;
+                    linesize   = sl->mb_linesize   = sl->linesize;
+                    uvlinesize = sl->mb_uvlinesize = sl->uvlinesize;
                 }
                 backup_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize,
                                  uvlinesize, 0);
@@ -2290,6 +2294,9 @@ static void er_add_slice(H264SliceContext *sl,
                          int startx, int starty,
                          int endx, int endy, int status)
 {
+    if (!sl->h264->enable_er)
+        return;
+
     if (CONFIG_ERROR_RESILIENCE) {
         ERContext *er = &sl->er;
 
@@ -2304,13 +2311,16 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
     int lf_x_start = sl->mb_x;
     int ret;
 
-    ret = alloc_scratch_buffers(sl, h->linesize);
+    sl->linesize   = h->cur_pic_ptr->f.linesize[0];
+    sl->uvlinesize = h->cur_pic_ptr->f.linesize[1];
+
+    ret = alloc_scratch_buffers(sl, sl->linesize);
     if (ret < 0)
         return ret;
 
     sl->mb_skip_run = -1;
 
-    av_assert0(h->block_offset[15] == (4 * ((scan8[15] - scan8[0]) & 7) << h->pixel_shift) + 4 * h->linesize * ((scan8[15] - scan8[0]) >> 3));
+    av_assert0(h->block_offset[15] == (4 * ((scan8[15] - scan8[0]) & 7) << h->pixel_shift) + 4 * sl->linesize * ((scan8[15] - scan8[0]) >> 3));
 
     sl->is_complex = FRAME_MBAFF(h) || h->picture_structure != PICT_FRAME ||
                      avctx->codec_id != AV_CODEC_ID_H264 ||