Merge commit 'a12d3188cbec15e22070e139fa5cc541da07e2c3'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 21:08:19 +0000 (22:08 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 22:05:34 +0000 (23:05 +0100)
* commit 'a12d3188cbec15e22070e139fa5cc541da07e2c3':
  h264: use a smaller struct for the ref lists

Conflicts:
libavcodec/h264_direct.c
libavcodec/h264_mb.c
libavcodec/h264_picture.c
libavcodec/h264_refs.c

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

Simple merge
@@@ -77,14 -69,6 +77,14 @@@ static void h264_er_decode_mb(void *opa
       * practice then correct remapping should be added. */
      if (ref >= sl->ref_count[0])
          ref = 0;
-     if (!sl->ref_list[0][ref].f.data[0]) {
++    if (!sl->ref_list[0][ref].data[0]) {
 +        av_log(h->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
 +        ref = 0;
 +    }
 +    if ((sl->ref_list[0][ref].reference&3) != 3) {
 +        av_log(h->avctx, AV_LOG_DEBUG, "Reference invalid\n");
 +        return;
 +    }
      fill_rectangle(&h->cur_pic.ref_index[0][4 * sl->mb_xy],
                     2, 2, 2, ref, 1);
      fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
@@@ -325,14 -294,19 +325,25 @@@ typedef struct H264Picture 
      int needs_realloc;      ///< picture needs to be reallocated (eg due to a frame size change)
      int reference;
      int recovered;          ///< picture at IDR or recovery point + recovery count
 +    int invalid_gap;
 +    int sei_recovery_frame_cnt;
 +
 +    int crop;
 +    int crop_left;
 +    int crop_top;
  } H264Picture;
  
+ typedef struct H264Ref {
+     uint8_t *data[3];
+     int linesize[3];
+     int reference;
+     int poc;
+     int pic_id;
+     H264Picture *parent;
+ } H264Ref;
  typedef struct H264SliceContext {
      struct H264Context *h264;
      GetBitContext gb;
@@@ -155,11 -159,11 +159,11 @@@ void ff_h264_direct_ref_list_init(cons
      }
  }
  
--static void await_reference_mb_row(const H264Context *const h, H264Picture *ref,
++static void await_reference_mb_row(const H264Context *const h, H264Ref *ref,
                                     int mb_y)
  {
      int ref_field         = ref->reference - 1;
--    int ref_field_picture = ref->field_picture;
++    int ref_field_picture = ref->parent->field_picture;
      int ref_height        = 16 * h->mb_height >> ref_field_picture;
  
      if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_FRAME))
      /* FIXME: It can be safe to access mb stuff
       * even if pixels aren't deblocked yet. */
  
--    ff_thread_await_progress(&ref->tf,
++    ff_thread_await_progress(&ref->parent->tf,
                               FFMIN(16 * mb_y >> ref_field_picture,
                                     ref_height - 1),
                               ref_field_picture && ref_field);
@@@ -317,12 -320,12 +321,12 @@@ single_col
          }
      }
  
 -    await_reference_mb_row(h, sl->ref_list[1][0].parent, mb_y);
 +    await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
  
-     l1mv0  = (void*)&sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
-     l1mv1  = (void*)&sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
-     l1ref0 = &sl->ref_list[1][0].ref_index[0][4 * mb_xy];
-     l1ref1 = &sl->ref_list[1][0].ref_index[1][4 * mb_xy];
 -    l1mv0  = &sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
 -    l1mv1  = &sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
++    l1mv0  = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
++    l1mv1  = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
+     l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
+     l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
      if (!b8_stride) {
          if (sl->mb_y & 1) {
              l1ref0 += 2;
@@@ -476,10 -479,10 +480,10 @@@ static void pred_temp_direct_motion(con
  
      assert(sl->ref_list[1][0].reference & 3);
  
 -    await_reference_mb_row(h, sl->ref_list[1][0].parent,
 +    await_reference_mb_row(h, &sl->ref_list[1][0],
                             sl->mb_y + !!IS_INTERLACED(*mb_type));
  
-     if (IS_INTERLACED(sl->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+     if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
          if (!IS_INTERLACED(*mb_type)) {                    //     AFR/FR    -> AFL/FL
              mb_y  = (sl->mb_y & ~1) + sl->col_parity;
              mb_xy = sl->mb_x +
@@@ -541,12 -544,12 +545,12 @@@ single_col
          }
      }
  
 -    await_reference_mb_row(h, sl->ref_list[1][0].parent, mb_y);
 +    await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
  
-     l1mv0  = (void*)&sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
-     l1mv1  = (void*)&sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
-     l1ref0 = &sl->ref_list[1][0].ref_index[0][4 * mb_xy];
-     l1ref1 = &sl->ref_list[1][0].ref_index[1][4 * mb_xy];
 -    l1mv0  = &sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
 -    l1mv1  = &sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
++    l1mv0  = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
++    l1mv1  = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
+     l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
+     l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
      if (!b8_stride) {
          if (sl->mb_y & 1) {
              l1ref0 += 2;
@@@ -215,8 -215,8 +215,8 @@@ static av_always_inline void mc_dir_par
      const int mx      = sl->mv_cache[list][scan8[n]][0] + src_x_offset * 8;
      int my            = sl->mv_cache[list][scan8[n]][1] + src_y_offset * 8;
      const int luma_xy = (mx & 3) + ((my & 3) << 2);
 -    ptrdiff_t offset  = ((mx >> 2) << pixel_shift) + (my >> 2) * sl->mb_linesize;
 +    ptrdiff_t offset  = (mx >> 2) * (1 << pixel_shift) + (my >> 2) * sl->mb_linesize;
-     uint8_t *src_y    = pic->f.data[0] + offset;
+     uint8_t *src_y    = pic->data[0] + offset;
      uint8_t *src_cb, *src_cr;
      int extra_width  = 0;
      int extra_height = 0;
          emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);
      }
  
-     src_cb = pic->f.data[1] + ((mx >> 3) * (1 << pixel_shift)) +
 -    src_cb = pic->data[1] + ((mx >> 3) << pixel_shift) +
++    src_cb = pic->data[1] + ((mx >> 3) * (1 << pixel_shift)) +
               (my >> ysh) * sl->mb_uvlinesize;
-     src_cr = pic->f.data[2] + ((mx >> 3) * (1 << pixel_shift)) +
 -    src_cr = pic->data[2] + ((mx >> 3) << pixel_shift) +
++    src_cr = pic->data[2] + ((mx >> 3) * (1 << pixel_shift)) +
               (my >> ysh) * sl->mb_uvlinesize;
  
      if (emu) {
@@@ -489,8 -483,8 +489,8 @@@ static av_always_inline void prefetch_m
      if (refn >= 0) {
          const int mx  = (sl->mv_cache[list][scan8[0]][0] >> 2) + 16 * sl->mb_x + 8;
          const int my  = (sl->mv_cache[list][scan8[0]][1] >> 2) + 16 * sl->mb_y;
-         uint8_t **src = sl->ref_list[list][refn].f.data;
+         uint8_t **src = sl->ref_list[list][refn].data;
 -        int off       = (mx << pixel_shift) +
 +        int off       =  mx * (1<< pixel_shift) +
                          (my + (sl->mb_x & 3) * 4) * sl->mb_linesize +
                          (64 << pixel_shift);
          h->vdsp.prefetch(src[0] + off, h->linesize, 4);
@@@ -196,27 -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)) {
 -        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) {
 +        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);
-             COPY_PICTURE(&sl->ref_list[0][0], &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]);
++            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]);
++            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);
-             memset(&sl->ref_list[0][0], 0, sizeof(h->last_pic_for_ec));
 +        if (use_last_pic)
++            memset(&sl->ref_list[0][0], 0, sizeof(sl->ref_list[0][0]));
      }
  #endif /* CONFIG_ERROR_RESILIENCE */
  
@@@ -136,10 -143,9 +146,10 @@@ int ff_h264_fill_default_ref_list(H264C
              len += build_def_list(h->default_ref_list[list] + len,
                                    FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
                                    h->long_ref, 16, 1, h->picture_structure);
 +            av_assert0(len <= 32);
  
              if (len < sl->ref_count[list])
-                 memset(&h->default_ref_list[list][len], 0, sizeof(H264Picture) * (sl->ref_count[list] - len));
+                 memset(&h->default_ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len));
              lens[list] = len;
          }
  
          len += build_def_list(h->default_ref_list[0] + len,
                                FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
                                h-> long_ref, 16, 1, h->picture_structure);
 +        av_assert0(len <= 32);
  
          if (len < sl->ref_count[0])
-             memset(&h->default_ref_list[0][len], 0, sizeof(H264Picture) * (sl->ref_count[0] - len));
+             memset(&h->default_ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len));
      }
  #ifdef TRACE
      for (i = 0; i < sl->ref_count[0]; i++) {
@@@ -322,19 -324,13 +329,19 @@@ int ff_h264_decode_ref_pic_list_reorder
      }
      for (list = 0; list < sl->list_count; list++) {
          for (index = 0; index < sl->ref_count[list]; index++) {
-             if (   !sl->ref_list[list][index].f.buf[0]
 -            if (!sl->ref_list[list][index].parent) {
 -                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
 -                if (h->default_ref_list[list][0].parent)
++            if (   !sl->ref_list[list][index].parent
 +                || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) {
 +                int i;
 +                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
 +                for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++)
 +                    h->last_pocs[i] = INT_MIN;
-                 if (h->default_ref_list[list][0].f.buf[0]
++                if (h->default_ref_list[list][0].parent
 +                    && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3))
-                     COPY_PICTURE(&sl->ref_list[list][index], &h->default_ref_list[list][0]);
+                     sl->ref_list[list][index] = h->default_ref_list[list][0];
                  else
                      return -1;
              }
-             av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].f.buf[0]) > 0);
++            av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f.buf[0]) > 0);
          }
      }
  
  void ff_h264_fill_mbaff_ref_list(H264Context *h, H264SliceContext *sl)
  {
      int list, i, j;
 -    for (list = 0; list < sl->list_count; list++) { //FIXME try list_count
 +    for (list = 0; list < sl->list_count; list++) {
          for (i = 0; i < sl->ref_count[list]; i++) {
-             H264Picture *frame = &sl->ref_list[list][i];
-             H264Picture *field = &sl->ref_list[list][16 + 2 * i];
-             COPY_PICTURE(field, frame);
+             H264Ref *frame = &sl->ref_list[list][i];
+             H264Ref *field = &sl->ref_list[list][16 + 2 * i];
+             field[0] = *frame;
              for (j = 0; j < 3; j++)
-                 field[0].f.linesize[j] <<= 1;
+                 field[0].linesize[j] <<= 1;
              field[0].reference = PICT_TOP_FIELD;
-             field[0].poc       = field[0].field_poc[0];
-             COPY_PICTURE(field + 1, field);
+             field[0].poc       = field[0].parent->field_poc[0];
+             field[1] = field[0];
              for (j = 0; j < 3; j++)
-                 field[1].f.data[j] += frame->f.linesize[j];
+                 field[1].data[j] += frame->parent->f.linesize[j];
              field[1].reference = PICT_BOTTOM_FIELD;
-             field[1].poc       = field[1].field_poc[1];
+             field[1].poc       = field[1].parent->field_poc[1];
  
              sl->luma_weight[16 + 2 * i][list][0] = sl->luma_weight[16 + 2 * i + 1][list][0] = sl->luma_weight[i][list][0];
              sl->luma_weight[16 + 2 * i][list][1] = sl->luma_weight[16 + 2 * i + 1][list][1] = sl->luma_weight[i][list][1];
Simple merge
Simple merge