Merge commit 'a4d34e218f548d381e09c483e8dc6ad18a8d571c'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 3 Apr 2015 22:49:57 +0000 (00:49 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 3 Apr 2015 22:52:54 +0000 (00:52 +0200)
* commit 'a4d34e218f548d381e09c483e8dc6ad18a8d571c':
  h264: disable ER by default

Conflicts:
libavcodec/h264.c
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

@@@ -700,8 -667,12 +700,14 @@@ av_cold int ff_h264_decode_init(AVCodec
  
      avctx->internal->allocate_progress = 1;
  
 +    ff_h264_flush_change(h);
 +
+     if (h->enable_er) {
+         av_log(avctx, AV_LOG_WARNING,
+                "Error resilience is enabled. It is unsafe and unsupported and may crash. "
+                "Use it at your own risk\n");
+     }
      return 0;
  }
  
@@@ -1925,6 -1793,20 +1931,22 @@@ static av_cold int h264_decode_end(AVCo
      return 0;
  }
  
 -    .class_name = "h264",
+ #define OFFSET(x) offsetof(H264Context, x)
+ #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+ static const AVOption h264_options[] = {
++    {"is_avc", "is avc", offsetof(H264Context, is_avc), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
++    {"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 4, 0},
+     { "enable_er", "Enable error resilience on damaged frames (unsafe)", OFFSET(enable_er), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD },
+     { NULL },
+ };
+ static const AVClass h264_class = {
++    .class_name = "H264 Decoder",
+     .item_name  = av_default_item_name,
+     .option     = h264_options,
+     .version    = LIBAVUTIL_VERSION_INT,
+ };
  static const AVProfile profiles[] = {
      { FF_PROFILE_H264_BASELINE,             "Baseline"              },
      { FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline"  },
@@@ -781,13 -726,9 +781,15 @@@ typedef struct H264Context 
      int initial_cpb_removal_delay[32];  ///< Initial timestamps for CPBs
  
      int cur_chroma_format_idc;
 +    int cur_bit_depth_luma;
 +    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;
  
+     int enable_er;
      AVBufferPool *qscale_table_pool;
      AVBufferPool *mb_type_pool;
      AVBufferPool *motion_val_pool;
@@@ -196,30 -184,13 +196,30 @@@ 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) && h->current_slice && !h->sps.new) {
 -    if (!FIELD_PICTURE(h) && h->enable_er) {
 -        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].parent : NULL);
 -        h264_set_erpic(&sl->er.next_pic,
 -                       sl->ref_count[1] ? sl->ref_list[1][0].parent : NULL);
++    if (!FIELD_PICTURE(h) && h->current_slice && !h->sps.new && h->enable_er) {
 +        int use_last_pic = h->last_pic_for_ec.f.buf[0] && !sl->ref_count[0];
 +
 +        ff_h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr);
 +
 +        if (use_last_pic) {
 +            ff_h264_set_erpic(&sl->er.last_pic, &h->last_pic_for_ec);
 +            sl->ref_list[0][0].parent = &h->last_pic_for_ec;
 +            memcpy(sl->ref_list[0][0].data, h->last_pic_for_ec.f.data, sizeof(sl->ref_list[0][0].data));
 +            memcpy(sl->ref_list[0][0].linesize, h->last_pic_for_ec.f.linesize, sizeof(sl->ref_list[0][0].linesize));
 +            sl->ref_list[0][0].reference = h->last_pic_for_ec.reference;
 +        } else if (sl->ref_count[0]) {
 +            ff_h264_set_erpic(&sl->er.last_pic, sl->ref_list[0][0].parent);
 +        } else
 +            ff_h264_set_erpic(&sl->er.last_pic, NULL);
 +
 +        if (sl->ref_count[1])
 +            ff_h264_set_erpic(&sl->er.next_pic, sl->ref_list[1][0].parent);
 +
 +        sl->er.ref_count = sl->ref_count[0];
 +
          ff_er_frame_end(&sl->er);
 +        if (use_last_pic)
 +            memset(&sl->ref_list[0][0], 0, sizeof(sl->ref_list[0][0]));
      }
  #endif /* CONFIG_ERROR_RESILIENCE */
  
@@@ -706,16 -634,8 +707,16 @@@ static int h264_frame_start(H264Contex
      if ((ret = ff_h264_ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0)
          return ret;
  
 -    if (CONFIG_ERROR_RESILIENCE && h->enable_er)
 +    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) {
++    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);
 +    }
  
      for (i = 0; i < 16; i++) {
          h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3);
@@@ -2283,11 -2059,15 +2284,14 @@@ 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 (!sl->h264->enable_er)
+         return;
 -    er->ref_count = sl->ref_count[0];
 -    ff_er_add_slice(er, startx, starty, endx, endy, status);
 -#endif
 +    if (CONFIG_ERROR_RESILIENCE) {
 +        ERContext *er = &sl->er;
 +
 +        ff_er_add_slice(er, startx, starty, endx, endy, status);
 +    }
  }
  
  static int decode_slice(struct AVCodecContext *avctx, void *arg)