Merge commit '582683b6ac798ed2a004a4e2121b7bd47892bbfd'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 19:00:34 +0000 (20:00 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 19:00:34 +0000 (20:00 +0100)
* commit '582683b6ac798ed2a004a4e2121b7bd47892bbfd':
  h264: move remaining ER stuff into the per-slice context

Conflicts:
libavcodec/h264.h
libavcodec/h264_picture.c
libavcodec/h264_slice.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_picture.c
libavcodec/h264_slice.c

@@@ -1905,14 -1778,6 +1904,14 @@@ static int h264_decode_frame(AVCodecCon
              if (ret < 0)
                  return ret;
              *got_frame = 1;
-                 ff_print_debug_info2(h->avctx, pict, h->er.mbskip_table,
 +            if (CONFIG_MPEGVIDEO) {
++                ff_print_debug_info2(h->avctx, pict, NULL,
 +                                    h->next_output_pic->mb_type,
 +                                    h->next_output_pic->qscale_table,
 +                                    h->next_output_pic->motion_val,
 +                                    &h->low_delay,
 +                                    h->mb_width, h->mb_height, h->mb_stride, 1);
 +            }
          }
      }
  
@@@ -769,12 -715,6 +770,11 @@@ typedef struct H264Context 
      int initial_cpb_removal_delay[32];  ///< Initial timestamps for CPBs
  
      int cur_chroma_format_idc;
-     int16_t *dc_val_base;
 +    int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
 +
 +    uint8_t parse_history[6];
 +    int parse_history_count;
 +    int parse_last_mb;
  
      AVBufferPool *qscale_table_pool;
      AVBufferPool *mb_type_pool;
@@@ -196,27 -184,13 +196,27 @@@ int ff_h264_field_end(H264Context *h, H
       * past end by one (callers fault) and resync_mb_y != 0
       * causes problems for the first MB line, too.
       */
 -    if (!FIELD_PICTURE(h)) {
 -        h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr);
 -        h264_set_erpic(&sl->er.last_pic,
 -                       sl->ref_count[0] ? &sl->ref_list[0][0] : NULL);
 -        h264_set_erpic(&sl->er.next_pic,
 -                       sl->ref_count[1] ? &sl->ref_list[1][0] : NULL);
 +    if (!FIELD_PICTURE(h) && h->current_slice && !h->sps.new) {
 +        int use_last_pic = h->last_pic_for_ec.f.buf[0] && !sl->ref_count[0];
 +
-         ff_h264_set_erpic(&h->er.cur_pic, h->cur_pic_ptr);
++        ff_h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr);
 +
 +        if (use_last_pic) {
-             ff_h264_set_erpic(&h->er.last_pic, &h->last_pic_for_ec);
++            ff_h264_set_erpic(&sl->er.last_pic, &h->last_pic_for_ec);
 +            COPY_PICTURE(&sl->ref_list[0][0], &h->last_pic_for_ec);
 +        } else if (sl->ref_count[0]) {
-             ff_h264_set_erpic(&h->er.last_pic, &sl->ref_list[0][0]);
++            ff_h264_set_erpic(&sl->er.last_pic, &sl->ref_list[0][0]);
 +        } else
-             ff_h264_set_erpic(&h->er.last_pic, NULL);
++            ff_h264_set_erpic(&sl->er.last_pic, NULL);
 +
 +        if (sl->ref_count[1])
-             ff_h264_set_erpic(&h->er.next_pic, &sl->ref_list[1][0]);
++            ff_h264_set_erpic(&sl->er.next_pic, &sl->ref_list[1][0]);
 +
-         h->er.ref_count = sl->ref_count[0];
++        sl->er.ref_count = sl->ref_count[0];
 +
-         ff_er_frame_end(&h->er);
+         ff_er_frame_end(&sl->er);
 +        if (use_last_pic)
 +            memset(&sl->ref_list[0][0], 0, sizeof(h->last_pic_for_ec));
      }
  #endif /* CONFIG_ERROR_RESILIENCE */
  
@@@ -538,16 -501,14 +538,15 @@@ int ff_h264_update_thread_context(AVCod
          for (i = 0; i < MAX_PPS_COUNT; i++)
              av_freep(h->pps_buffers + i);
  
 -        memcpy(h, h1, sizeof(*h1));
 +        av_freep(&h->rbsp_buffer);
 +        ff_h264_unref_picture(h, &h->last_pic_for_ec);
 +        memcpy(h, h1, sizeof(H264Context));
 +
          memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
          memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
 -        h->context_initialized = 0;
  
-         memset(&h->er, 0, sizeof(h->er));
          memset(&h->cur_pic, 0, sizeof(h->cur_pic));
 -        av_frame_unref(&h->cur_pic.f);
 -        h->cur_pic.tf.f = &h->cur_pic.f;
 +        memset(&h->last_pic_for_ec, 0, sizeof(h->last_pic_for_ec));
  
          h->slice_ctx = orig_slice_ctx;
  
@@@ -740,18 -668,11 +740,18 @@@ static int h264_frame_start(H264Contex
  
      h->cur_pic_ptr = pic;
      ff_h264_unref_picture(h, &h->cur_pic);
-         ff_h264_set_erpic(&h->er.cur_pic, NULL);
 +    if (CONFIG_ERROR_RESILIENCE) {
++        ff_h264_set_erpic(&h->slice_ctx[0].er.cur_pic, NULL);
 +    }
 +
      if ((ret = ff_h264_ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0)
          return ret;
  
 -    if (CONFIG_ERROR_RESILIENCE)
 +    if (CONFIG_ERROR_RESILIENCE) {
-         ff_er_frame_start(&h->er);
-         ff_h264_set_erpic(&h->er.last_pic, NULL);
-         ff_h264_set_erpic(&h->er.next_pic, NULL);
+         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);
  
@@@ -1202,10 -1098,10 +1202,10 @@@ static int h264_slice_header_init(H264C
      h->slice_context_count = nb_slices;
  
      if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
-         ret = ff_h264_context_init(h);
+         ret = ff_h264_slice_context_init(h, &h->slice_ctx[0]);
          if (ret < 0) {
              av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
 -            return ret;
 +            goto fail;
          }
      } else {
          for (i = 1; i < h->slice_context_count; i++) {
          }
  
          for (i = 0; i < h->slice_context_count; i++)
-             if ((ret = ff_h264_context_init(h->thread_context[i])) < 0) {
+             if ((ret = ff_h264_slice_context_init(h, &h->slice_ctx[i])) < 0) {
                  av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
 -                return ret;
 +                goto fail;
              }
      }
  
@@@ -2371,7 -2147,7 +2371,7 @@@ static void decode_finish_row(H264Conte
  
      ff_h264_draw_horiz_band(h, sl, top, height);
  
-     if (h->droppable || h->er.error_occurred)
 -    if (h->droppable)
++    if (h->droppable || sl->er.error_occurred)
          return;
  
      ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1,
@@@ -2382,11 -2158,12 +2382,11 @@@ static void er_add_slice(H264SliceConte
                           int startx, int starty,
                           int endx, int endy, int status)
  {
 -#if CONFIG_ERROR_RESILIENCE
 -    ERContext *er = &sl->er;
 +    if (CONFIG_ERROR_RESILIENCE) {
-         ERContext *er = &h->er;
++        ERContext *er = &sl->er;
  
 -    er->ref_count = sl->ref_count[0];
 -    ff_er_add_slice(er, startx, starty, endx, endy, status);
 -#endif
 +        ff_er_add_slice(er, startx, starty, endx, endy, status);
 +    }
  }
  
  static int decode_slice(struct AVCodecContext *avctx, void *arg)
                       avctx->codec_id != AV_CODEC_ID_H264 ||
                       (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY));
  
-     if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && h->er.error_status_table) {
++    if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && sl->er.error_status_table) {
 +        const int start_i  = av_clip(sl->resync_mb_x + sl->resync_mb_y * h->mb_width, 0, h->mb_num - 1);
 +        if (start_i) {
-             int prev_status = h->er.error_status_table[h->er.mb_index2xy[start_i - 1]];
++            int prev_status = sl->er.error_status_table[sl->er.mb_index2xy[start_i - 1]];
 +            prev_status &= ~ VP_START;
 +            if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END))
-                 h->er.error_occurred = 1;
++                sl->er.error_occurred = 1;
 +        }
 +    }
 +
      if (h->pps.cabac) {
          /* realign */
          align_get_bits(&sl->gb);
                      loop_filter(h, sl, lf_x_start, sl->mb_x + 1);
                  return 0;
              }
 -            if (ret < 0 || sl->cabac.bytestream > sl->cabac.bytestream_end + 2) {
 +            if (sl->cabac.bytestream > sl->cabac.bytestream_end + 2 )
 +                av_log(h->avctx, AV_LOG_DEBUG, "bytestream overread %"PTRDIFF_SPECIFIER"\n", sl->cabac.bytestream_end - sl->cabac.bytestream);
 +            if (ret < 0 || sl->cabac.bytestream > sl->cabac.bytestream_end + 4) {
                  av_log(h->avctx, AV_LOG_ERROR,
 -                       "error while decoding MB %d %d, bytestream %td\n",
 +                       "error while decoding MB %d %d, bytestream %"PTRDIFF_SPECIFIER"\n",
                         sl->mb_x, sl->mb_y,
                         sl->cabac.bytestream_end - sl->cabac.bytestream);
-                 er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
+                 er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
                               sl->mb_y, ER_MB_ERROR);
                  return AVERROR_INVALIDDATA;
              }
                      tprintf(h->avctx, "slice end %d %d\n",
                              get_bits_count(&sl->gb), sl->gb.size_in_bits);
  
 -                    if (get_bits_left(&sl->gb) == 0) {
 +                    if (   get_bits_left(&sl->gb) == 0
 +                        || get_bits_left(&sl->gb) > 0 && !(h->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
-                         er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y,
+                         er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y,
                                       sl->mb_x - 1, sl->mb_y, ER_MB_END);
  
                          return 0;
                      } else {
-                         er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y,
+                         er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y,
 -                                     sl->mb_x - 1, sl->mb_y, ER_MB_END);
 +                                     sl->mb_x, sl->mb_y, ER_MB_END);
  
                          return AVERROR_INVALIDDATA;
                      }
@@@ -2591,13 -2350,9 +2591,14 @@@ int ff_h264_execute_decode_slices(H264C
          h->mb_y = h->slice_ctx[0].mb_y;
          return ret;
      } else {
 +        av_assert0(context_count > 0);
          for (i = 1; i < context_count; i++) {
 -            sl->er.error_count = 0;
 +            hx                 = h->thread_context[i];
+             sl                 = &h->slice_ctx[i];
-                 hx->er.error_count = 0;
 +            if (CONFIG_ERROR_RESILIENCE) {
++                sl->er.error_count = 0;
 +            }
 +            hx->x264_build     = h->x264_build;
          }
  
          avctx->execute(avctx, decode_slice, h->slice_ctx,
          h->mb_y              = sl->mb_y;
          h->droppable         = hx->droppable;
          h->picture_structure = hx->picture_structure;
 -        for (i = 1; i < context_count; i++)
 -            h->slice_ctx[0].er.error_count += h->slice_ctx[i].er.error_count;
 +        if (CONFIG_ERROR_RESILIENCE) {
 +            for (i = 1; i < context_count; i++)
-                 h->er.error_count += h->thread_context[i]->er.error_count;
++                h->slice_ctx[0].er.error_count += h->slice_ctx[i].er.error_count;
 +        }
      }
  
      return 0;