Merge commit '741b494fa8cd28a7d096349bac183893c236e3f9'
authorHendrik Leppkes <h.leppkes@gmail.com>
Thu, 17 Dec 2015 11:45:28 +0000 (12:45 +0100)
committerHendrik Leppkes <h.leppkes@gmail.com>
Thu, 17 Dec 2015 11:45:28 +0000 (12:45 +0100)
* commit '741b494fa8cd28a7d096349bac183893c236e3f9':
  h264: eliminate default_ref_list

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
1  2 
libavcodec/h264.h
libavcodec/h264_refs.c
libavcodec/h264_slice.c

Simple merge
@@@ -122,18 -119,9 +122,18 @@@ static int add_sorted(H264Picture **sor
      return out_i;
  }
  
- int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl)
 +static int mismatches_ref(H264Context *h, H264Picture *pic)
 +{
 +    AVFrame *f = pic->f;
 +    return (h->cur_pic_ptr->f->width  != f->width ||
 +            h->cur_pic_ptr->f->height != f->height ||
 +            h->cur_pic_ptr->f->format != f->format);
 +}
 +
+ static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl)
  {
      int i, len;
 +    int j;
  
      if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
          H264Picture *sorted[32];
          for (list = 0; list < 2; list++) {
              len  = add_sorted(sorted,       h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);
              len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);
 -            assert(len <= 32);
 +            av_assert0(len <= 32);
  
-             len  = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+             len  = build_def_list(sl->ref_list[list], FF_ARRAY_ELEMS(sl->ref_list[0]),
                                    sorted, len, 0, h->picture_structure);
-             len += build_def_list(h->default_ref_list[list] + len,
-                                   FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+             len += build_def_list(sl->ref_list[list] + len,
+                                   FF_ARRAY_ELEMS(sl->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(H264Ref) * (sl->ref_count[list] - len));
+                 memset(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len));
              lens[list] = len;
          }
  
              }
          }
      } else {
-         len  = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+         len  = build_def_list(sl->ref_list[0], FF_ARRAY_ELEMS(sl->ref_list[0]),
                                h->short_ref, h->short_ref_count, 0, h->picture_structure);
-         len += build_def_list(h->default_ref_list[0] + len,
-                               FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+         len += build_def_list(sl->ref_list[0] + len,
+                               FF_ARRAY_ELEMS(sl->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(H264Ref) * (sl->ref_count[0] - len));
+             memset(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len));
      }
  #ifdef TRACE
      for (i = 0; i < sl->ref_count[0]; i++) {
          }
      }
  #endif
-             if (h->default_ref_list[j][i].parent) {
-                 if (mismatches_ref(h, h->default_ref_list[j][i].parent)) {
 +
 +    for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) {
 +        for (i = 0; i < sl->ref_count[j]; i++) {
-                     memset(&h->default_ref_list[j][i], 0, sizeof(h->default_ref_list[j][i]));
++            if (sl->ref_list[j][i].parent) {
++                if (mismatches_ref(h, sl->ref_list[j][i].parent)) {
 +                    av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n");
-     return 0;
++                    memset(&sl->ref_list[j][i], 0, sizeof(sl->ref_list[j][i]));
 +                }
 +            }
 +        }
 +    }
  }
  
  static void print_short_term(H264Context *h);
@@@ -350,19 -323,10 +348,15 @@@ 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].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);
+                 av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
 +                for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++)
 +                    h->last_pocs[i] = INT_MIN;
-                 if (h->default_ref_list[list][0].parent
-                     && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3))
-                     sl->ref_list[list][index] = h->default_ref_list[list][0];
-                 else
-                     return -1;
+                 return -1;
              }
 +            av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f->buf[0]) > 0);
          }
      }
  
@@@ -529,13 -487,6 +523,12 @@@ void ff_h264_remove_all_refs(H264Contex
          h->short_ref[i] = NULL;
      }
      h->short_ref_count = 0;
-     memset(h->default_ref_list, 0, sizeof(h->default_ref_list));
 +
 +    for (i = 0; i < h->nb_slice_ctx; i++) {
 +        H264SliceContext *sl = &h->slice_ctx[i];
 +        sl->list_count = sl->ref_count[0] = sl->ref_count[1] = 0;
 +        memset(sl->ref_list, 0, sizeof(sl->ref_list));
 +    }
  }
  
  /**
@@@ -1658,16 -1416,6 +1654,15 @@@ int ff_h264_decode_slice_header(H264Con
          } else {
              release_unused_pictures(h, 0);
          }
-         h->last_slice_type = -1;
 +        /* Some macroblocks can be accessed before they're available in case
 +        * of lost slices, MBAFF or threading. */
 +        if (FIELD_PICTURE(h)) {
 +            for(i = (h->picture_structure == PICT_BOTTOM_FIELD); i<h->mb_height; i++)
 +                memset(h->slice_table + i*h->mb_stride, -1, (h->mb_stride - (i+1==h->mb_height)) * sizeof(*h->slice_table));
 +        } else {
 +            memset(h->slice_table, -1,
 +                (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
 +        }
      }
  
      if (!h->setup_finished)
                            h->pps.chroma_qp_index_offset[1]) +
                     6 * (h->sps.bit_depth_luma - 8);
  
-     h->last_slice_type = slice_type;
-     memcpy(h->last_ref_count, sl->ref_count, sizeof(h->last_ref_count));
      sl->slice_num       = ++h->current_slice;
 -    if (sl->slice_num >= MAX_SLICES) {
 -        av_log(h->avctx, AV_LOG_ERROR,
 -               "Too many slices, increase MAX_SLICES and recompile\n");
 +
 +    if (sl->slice_num)
 +        h->slice_row[(sl->slice_num-1)&(MAX_SLICES-1)]= sl->resync_mb_y;
 +    if (   h->slice_row[sl->slice_num&(MAX_SLICES-1)] + 3 >= sl->resync_mb_y
 +        && h->slice_row[sl->slice_num&(MAX_SLICES-1)] <= sl->resync_mb_y
 +        && sl->slice_num >= MAX_SLICES) {
 +        //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case
 +        av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", sl->slice_num, MAX_SLICES);
      }
  
      for (j = 0; j < 2; j++) {