Merge commit '95eb35f30513e335990ad0d5dca6ddc318477291'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 13:59:58 +0000 (14:59 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 14:18:10 +0000 (15:18 +0100)
* commit '95eb35f30513e335990ad0d5dca6ddc318477291':
  h264: move the ref lists variables into the per-slice context

Conflicts:
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_direct.c
libavcodec/h264_mb.c
libavcodec/h264_picture.c
libavcodec/h264_refs.c
libavcodec/h264_slice.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
17 files changed:
1  2 
libavcodec/dxva2_h264.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_direct.c
libavcodec/h264_loopfilter.c
libavcodec/h264_mb.c
libavcodec/h264_mb_template.c
libavcodec/h264_mvpred.h
libavcodec/h264_parser.c
libavcodec/h264_picture.c
libavcodec/h264_refs.c
libavcodec/h264_slice.c
libavcodec/vaapi_h264.c
libavcodec/vdpau.c
libavcodec/vdpau_h264.c

Simple merge
@@@ -75,16 -67,8 +75,16 @@@ static void h264_er_decode_mb(void *opa
       * differ between slices. We take the easy approach and ignore
       * it for now. If this turns out to have any relevance in
       * practice then correct remapping should be added. */
-     if (ref >= h->ref_count[0])
+     if (ref >= sl->ref_count[0])
          ref = 0;
-     if (!h->ref_list[0][ref].f.data[0]) {
++    if (!sl->ref_list[0][ref].f.data[0]) {
 +        av_log(h->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
 +        ref = 0;
 +    }
-     if ((h->ref_list[0][ref].reference&3) != 3) {
++    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 * h->mb_xy],
                     2, 2, 2, ref, 1);
      fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
@@@ -1117,9 -1093,6 +1118,10 @@@ void ff_h264_flush_change(H264Context *
      ff_h264_reset_sei(h);
      h->recovery_frame = -1;
      h->frame_recovered = 0;
-     h->list_count = 0;
 +    h->current_slice = 0;
 +    h->mmco_reset = 1;
++    for (i = 0; i < h->nb_slice_ctx; i++)
++        h->slice_ctx[i].list_count = 0;
  }
  
  /* forget old pics after a seek */
@@@ -1315,18 -1276,13 +1317,18 @@@ int ff_set_ref_count(H264Context *h, H2
  
          if (num_ref_idx_active_override_flag) {
              ref_count[0] = get_ue_golomb(&h->gb) + 1;
 -            if (ref_count[0] < 1)
 -                return AVERROR_INVALIDDATA;
              if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
                  ref_count[1] = get_ue_golomb(&h->gb) + 1;
 -                if (ref_count[1] < 1)
 -                    return AVERROR_INVALIDDATA;
 -            }
 +            } else
 +                // full range is spec-ok in this case, even for frames
 +                ref_count[1] = 1;
 +        }
 +
 +        if (ref_count[0]-1 > max[0] || ref_count[1]-1 > max[1]){
 +            av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", ref_count[0]-1, max[0], ref_count[1]-1, max[1]);
-             h->ref_count[0] = h->ref_count[1] = 0;
-             h->list_count   = 0;
++            sl->ref_count[0] = sl->ref_count[1] = 0;
++            sl->list_count   = 0;
 +            return AVERROR_INVALIDDATA;
          }
  
          if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
          ref_count[0] = ref_count[1] = 0;
      }
  
-     if (list_count != h->list_count ||
-         ref_count[0] != h->ref_count[0] ||
-         ref_count[1] != h->ref_count[1]) {
-         h->ref_count[0] = ref_count[0];
-         h->ref_count[1] = ref_count[1];
-         h->list_count   = list_count;
 -    max_refs = h->picture_structure == PICT_FRAME ? 16 : 32;
 -
 -    if (ref_count[0] > max_refs || ref_count[1] > max_refs) {
 -        av_log(h->avctx, AV_LOG_ERROR, "reference overflow\n");
 -        sl->ref_count[0] = sl->ref_count[1] = 0;
 -        return AVERROR_INVALIDDATA;
 -    }
 -
+     if (list_count   != sl->list_count   ||
+         ref_count[0] != sl->ref_count[0] ||
+         ref_count[1] != sl->ref_count[1]) {
+         sl->ref_count[0] = ref_count[0];
+         sl->ref_count[1] = ref_count[1];
+         sl->list_count   = list_count;
          return 1;
      }
  
@@@ -1698,11 -1641,10 +1700,11 @@@ again
                  context_count = 0;
              }
  
 -            if (err < 0) {
 -                av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
 +            if (err < 0 || err == SLICE_SKIPED) {
 +                if (err < 0)
 +                    av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
-                 h->ref_count[0] = h->ref_count[1] = h->list_count = 0;
+                 sl->ref_count[0] = sl->ref_count[1] = sl->list_count = 0;
 -            } else if (err == 1) {
 +            } else if (err == SLICE_SINGLETHREAD) {
                  /* Slice could not be decoded in parallel mode, copy down
                   * NAL unit stuff to context 0 and restart. Note that
                   * rbsp_buffer is not transferred, but since we no longer
@@@ -1875,11 -1774,10 +1877,11 @@@ static int h264_decode_frame(AVCodecCon
          if (avctx->flags2 & CODEC_FLAG2_CHUNKS)
              decode_postinit(h, 1);
  
-         ff_h264_field_end(h, 0);
+         ff_h264_field_end(h, &h->slice_ctx[0], 0);
  
 +        /* Wait for second field. */
          *got_frame = 0;
 -        if (h->next_output_pic && ((avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT) ||
 +        if (h->next_output_pic && (
                                     h->next_output_pic->recovered)) {
              if (!h->next_output_pic->recovered)
                  h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT;
@@@ -1120,35 -1048,7 +1122,35 @@@ static av_always_inline int get_dct8x8_
                    0x0001000100010001ULL));
  }
  
- int ff_h264_field_end(H264Context *h, int in_setup);
 +static inline int find_start_code(const uint8_t *buf, int buf_size,
 +                           int buf_index, int next_avc)
 +{
 +    uint32_t state = -1;
 +
 +    buf_index = avpriv_find_start_code(buf + buf_index, buf + next_avc + 1, &state) - buf - 1;
 +
 +    return FFMIN(buf_index, buf_size);
 +}
 +
 +static inline int get_avc_nalsize(H264Context *h, const uint8_t *buf,
 +                           int buf_size, int *buf_index)
 +{
 +    int i, nalsize = 0;
 +
 +    if (*buf_index >= buf_size - h->nal_length_size)
 +        return -1;
 +
 +    for (i = 0; i < h->nal_length_size; i++)
 +        nalsize = ((unsigned)nalsize << 8) | buf[(*buf_index)++];
 +    if (nalsize <= 0 || nalsize > buf_size - *buf_index) {
 +        av_log(h->avctx, AV_LOG_ERROR,
 +               "AVC: nal size %d\n", nalsize);
 +        return -1;
 +    }
 +    return nalsize;
 +}
 +
+ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup);
  
  int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src);
  void ff_h264_unref_picture(H264Context *h, H264Picture *pic);
@@@ -2051,9 -2048,6 +2051,9 @@@ decode_intra_mb
          return 0;
      }
  
-     local_ref_count[0] = h->ref_count[0] << MB_MBAFF(h);
-     local_ref_count[1] = h->ref_count[1] << MB_MBAFF(h);
++    local_ref_count[0] = sl->ref_count[0] << MB_MBAFF(h);
++    local_ref_count[1] = sl->ref_count[1] << MB_MBAFF(h);
 +
      fill_decode_caches(h, sl, mb_type);
  
      if( IS_INTRA( mb_type ) ) {
      } else {
          int list, i;
          if(IS_16X16(mb_type)){
-             for(list=0; list<h->list_count; list++){
+             for (list = 0; list < sl->list_count; list++) {
                  if(IS_DIR(mb_type, 0, list)){
 -                    int ref, rc = sl->ref_count[list] << MB_MBAFF(h);
 -                    if (rc > 1) {
 +                    int ref;
 +                    if (local_ref_count[list] > 1) {
                          ref= decode_cabac_mb_ref(h, sl, list, 0);
 -                        if (ref >= (unsigned) rc) {
 -                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
 +                        if (ref >= (unsigned)local_ref_count[list]) {
 +                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                              return -1;
                          }
                      }else
              }
          }
          else if(IS_16X8(mb_type)){
-             for(list=0; list<h->list_count; list++){
+             for (list = 0; list < sl->list_count; list++) {
                      for(i=0; i<2; i++){
                          if(IS_DIR(mb_type, i, list)){
 -                            int ref, rc = sl->ref_count[list] << MB_MBAFF(h);
 -                            if (rc > 1) {
 +                            int ref;
 +                            if (local_ref_count[list] > 1) {
                                  ref= decode_cabac_mb_ref(h, sl, list, 8 * i);
 -                                if (ref >= (unsigned) rc) {
 -                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
 +                                if (ref >= (unsigned)local_ref_count[list]) {
 +                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                      return -1;
                                  }
                              }else
                  }
              }
          }else{
 -            assert(IS_8X16(mb_type));
 +            av_assert2(IS_8X16(mb_type));
-             for(list=0; list<h->list_count; list++){
+             for (list = 0; list < sl->list_count; list++) {
                      for(i=0; i<2; i++){
                          if(IS_DIR(mb_type, i, list)){ //FIXME optimize
 -                            int ref, rc = sl->ref_count[list] << MB_MBAFF(h);
 -                            if (rc > 1) {
 +                            int ref;
 +                            if (local_ref_count[list] > 1) {
                                  ref= decode_cabac_mb_ref(h, sl, list, 4 * i);
 -                                if (ref >= (unsigned) rc) {
 -                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
 +                                if (ref >= (unsigned)local_ref_count[list]) {
 +                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                      return -1;
                                  }
                              }else
@@@ -794,9 -786,6 +794,9 @@@ decode_intra_mb
          return 0;
      }
  
-     local_ref_count[0] = h->ref_count[0] << MB_MBAFF(h);
-     local_ref_count[1] = h->ref_count[1] << MB_MBAFF(h);
++    local_ref_count[0] = sl->ref_count[0] << MB_MBAFF(h);
++    local_ref_count[1] = sl->ref_count[1] << MB_MBAFF(h);
 +
      fill_decode_neighbors(h, sl, mb_type);
      fill_decode_caches(h, sl, mb_type);
  
              }
          }
  
-         for(list=0; list<h->list_count; list++){
+         for (list = 0; list < sl->list_count; list++) {
 -            int ref_count = IS_REF0(mb_type) ? 1 : sl->ref_count[list] << MB_MBAFF(h);
 +            int ref_count = IS_REF0(mb_type) ? 1 : local_ref_count[list];
              for(i=0; i<4; i++){
                  if(IS_DIRECT(sl->sub_mb_type[i])) continue;
                  if(IS_DIR(sl->sub_mb_type[i], 0, list)){
          int list, mx, my, i;
           //FIXME we should set ref_idx_l? to 0 if we use that later ...
          if(IS_16X16(mb_type)){
-             for(list=0; list<h->list_count; list++){
+             for (list = 0; list < sl->list_count; list++) {
                      unsigned int val;
                      if(IS_DIR(mb_type, 0, list)){
 -                        int rc = sl->ref_count[list] << MB_MBAFF(h);
 -                        if (rc == 1) {
 +                        if(local_ref_count[list]==1){
                              val= 0;
 -                        } else if (rc == 2) {
 +                        } else if(local_ref_count[list]==2){
                              val= get_bits1(&h->gb)^1;
                          }else{
                              val= get_ue_golomb_31(&h->gb);
                  }
              }
          }else{
 -            assert(IS_8X16(mb_type));
 +            av_assert2(IS_8X16(mb_type));
-             for(list=0; list<h->list_count; list++){
+             for (list = 0; list < sl->list_count; list++) {
                      for(i=0; i<2; i++){
                          unsigned int val;
                          if(IS_DIR(mb_type, i, list)){ //FIXME optimize
@@@ -231,7 -233,6 +233,7 @@@ static void pred_spatial_direct_motion(
                  else
                      mv[list] = AV_RN32A(C);
              }
-             av_assert2(ref[list] < (h->ref_count[list] << !!FRAME_MBAFF(h)));
++            av_assert2(ref[list] < (sl->ref_count[list] << !!FRAME_MBAFF(h)));
          } else {
              int mask = ~(MB_TYPE_L0 << (2 * list));
              mv[list]  = 0;
@@@ -315,12 -316,12 +317,12 @@@ single_col
          }
      }
  
-     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
+     await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
  
-     l1mv0  = (void*)&h->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
-     l1mv1  = (void*)&h->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
-     l1ref0 = &h->ref_list[1][0].ref_index[0][4 * mb_xy];
-     l1ref1 = &h->ref_list[1][0].ref_index[1][4 * mb_xy];
 -    l1mv0  = &sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
 -    l1mv1  = &sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
++    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];
      if (!b8_stride) {
          if (h->mb_y & 1) {
              l1ref0 += 2;
@@@ -539,12 -540,12 +541,12 @@@ single_col
          }
      }
  
-     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
+     await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
  
-     l1mv0  = (void*)&h->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
-     l1mv1  = (void*)&h->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
-     l1ref0 = &h->ref_list[1][0].ref_index[0][4 * mb_xy];
-     l1ref1 = &h->ref_list[1][0].ref_index[1][4 * mb_xy];
 -    l1mv0  = &sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
 -    l1mv1  = &sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
++    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];
      if (!b8_stride) {
          if (h->mb_y & 1) {
              l1ref0 += 2;
Simple merge
@@@ -490,8 -484,8 +490,8 @@@ static av_always_inline void prefetch_m
      if (refn >= 0) {
          const int mx  = (sl->mv_cache[list][scan8[0]][0] >> 2) + 16 * h->mb_x + 8;
          const int my  = (sl->mv_cache[list][scan8[0]][1] >> 2) + 16 * h->mb_y;
-         uint8_t **src = h->ref_list[list][refn].f.data;
+         uint8_t **src = sl->ref_list[list][refn].f.data;
 -        int off       = (mx << pixel_shift) +
 +        int off       =  mx * (1<< pixel_shift) +
                          (my + (h->mb_x & 3) * 4) * sl->mb_linesize +
                          (64 << pixel_shift);
          h->vdsp.prefetch(src[0] + off, h->linesize, 4);
Simple merge
Simple merge
Simple merge
@@@ -149,10 -141,10 +149,10 @@@ void ff_h264_set_erpic(ERPicture *dst, 
  
      dst->mb_type = src->mb_type;
      dst->field_picture = src->field_picture;
 -}
  #endif /* CONFIG_ERROR_RESILIENCE */
 +}
  
- int ff_h264_field_end(H264Context *h, int in_setup)
+ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup)
  {
      AVCodecContext *const avctx = h->avctx;
      int err = 0;
       * 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(&h->er.cur_pic, h->cur_pic_ptr);
 -        h264_set_erpic(&h->er.last_pic,
 -                       sl->ref_count[0] ? &sl->ref_list[0][0] : NULL);
 -        h264_set_erpic(&h->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] && !h->ref_count[0];
++        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);
 +
 +        if (use_last_pic) {
 +            ff_h264_set_erpic(&h->er.last_pic, &h->last_pic_for_ec);
-             COPY_PICTURE(&h->ref_list[0][0], &h->last_pic_for_ec);
-         } else if (h->ref_count[0]) {
-             ff_h264_set_erpic(&h->er.last_pic, &h->ref_list[0][0]);
++            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]);
 +        } else
 +            ff_h264_set_erpic(&h->er.last_pic, NULL);
 +
-         if (h->ref_count[1])
-             ff_h264_set_erpic(&h->er.next_pic, &h->ref_list[1][0]);
++        if (sl->ref_count[1])
++            ff_h264_set_erpic(&h->er.next_pic, &sl->ref_list[1][0]);
 +
-         h->er.ref_count = h->ref_count[0];
++        h->er.ref_count = sl->ref_count[0];
 +
          ff_er_frame_end(&h->er);
-             memset(&h->ref_list[0][0], 0, sizeof(h->last_pic_for_ec));
 +        if (use_last_pic)
++            memset(&sl->ref_list[0][0], 0, sizeof(h->last_pic_for_ec));
      }
  #endif /* CONFIG_ERROR_RESILIENCE */
  
@@@ -136,10 -140,9 +136,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 < h->ref_count[list])
-                 memset(&h->default_ref_list[list][len], 0, sizeof(H264Picture) * (h->ref_count[list] - len));
+             if (len < sl->ref_count[list])
+                 memset(&h->default_ref_list[list][len], 0, sizeof(H264Picture) * (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 < h->ref_count[0])
-             memset(&h->default_ref_list[0][len], 0, sizeof(H264Picture) * (h->ref_count[0] - len));
+         if (len < sl->ref_count[0])
+             memset(&h->default_ref_list[0][len], 0, sizeof(H264Picture) * (sl->ref_count[0] - len));
      }
  #ifdef TRACE
-     for (i = 0; i < h->ref_count[0]; i++) {
+     for (i = 0; i < sl->ref_count[0]; i++) {
          tprintf(h->avctx, "List0: %s fn:%d 0x%p\n",
                  (h->default_ref_list[0][i].long_ref ? "LT" : "ST"),
                  h->default_ref_list[0][i].pic_id,
@@@ -320,21 -322,15 +320,21 @@@ int ff_h264_decode_ref_pic_list_reorder
              }
          }
      }
-     for (list = 0; list < h->list_count; list++) {
-         for (index = 0; index < h->ref_count[list]; index++) {
-             if (   !h->ref_list[list][index].f.buf[0]
-                 || (!FIELD_PICTURE(h) && (h->ref_list[list][index].reference&3) != 3)) {
+     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]) {
 -                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
 -                if (h->default_ref_list[list][0].f.buf[0])
++            if (   !sl->ref_list[list][index].f.buf[0]
++                || (!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]
 +                    && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3))
-                     COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]);
+                     COPY_PICTURE(&sl->ref_list[list][index], &h->default_ref_list[list][0]);
                  else
                      return -1;
              }
-             av_assert0(av_buffer_get_ref_count(h->ref_list[list][index].f.buf[0]) > 0);
++            av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].f.buf[0]) > 0);
          }
      }
  
  void ff_h264_fill_mbaff_ref_list(H264Context *h, H264SliceContext *sl)
  {
      int list, i, j;
-     for (list = 0; list < h->list_count; list++) {
-         for (i = 0; i < h->ref_count[list]; i++) {
-             H264Picture *frame = &h->ref_list[list][i];
-             H264Picture *field = &h->ref_list[list][16 + 2 * i];
 -    for (list = 0; list < 2; 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);
              for (j = 0; j < 3; j++)
                  field[0].f.linesize[j] <<= 1;
@@@ -496,9 -487,6 +496,10 @@@ void ff_h264_remove_all_refs(H264Contex
          h->short_ref[i] = NULL;
      }
      h->short_ref_count = 0;
-     memset(h->ref_list, 0, sizeof(h->ref_list));
 +
 +    memset(h->default_ref_list, 0, sizeof(h->default_ref_list));
++    for (i = 0; i < h->nb_slice_ctx; i++)
++        memset(h->slice_ctx[i].ref_list, 0, sizeof(h->slice_ctx[i].ref_list));
  }
  
  /**
@@@ -1797,19 -1595,16 +1797,19 @@@ int ff_h264_decode_slice_header(H264Con
      ret = ff_set_ref_count(h, sl);
      if (ret < 0)
          return ret;
 -    else if (ret == 1)
 -        default_ref_list_done = 0;
  
 -    if (!default_ref_list_done)
 +    if (slice_type != AV_PICTURE_TYPE_I &&
 +        (h0->current_slice == 0 ||
 +         slice_type != h0->last_slice_type ||
-          memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) {
++         memcmp(h0->last_ref_count, sl->ref_count, sizeof(sl->ref_count)))) {
 +
          ff_h264_fill_default_ref_list(h, sl);
 +    }
  
      if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
-        ret = ff_h264_decode_ref_pic_list_reordering(h);
+        ret = ff_h264_decode_ref_pic_list_reordering(h, sl);
         if (ret < 0) {
-            h->ref_count[1] = h->ref_count[0] = 0;
+            sl->ref_count[1] = sl->ref_count[0] = 0;
             return ret;
         }
      }
                     6 * (h->sps.bit_depth_luma - 8);
  
      h0->last_slice_type = slice_type;
-     memcpy(h0->last_ref_count, h0->ref_count, sizeof(h0->last_ref_count));
++    memcpy(h0->last_ref_count, sl->ref_count, sizeof(h0->last_ref_count));
      sl->slice_num       = ++h0->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)
 +        h0->slice_row[(sl->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y;
 +    if (   h0->slice_row[sl->slice_num&(MAX_SLICES-1)] + 3 >= h->resync_mb_y
 +        && h0->slice_row[sl->slice_num&(MAX_SLICES-1)] <= h->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++) {
          ref2frm[18 + 1] = -1;
          for (i = 16; i < 48; i++)
              ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] +
-                              (h->ref_list[j][i].reference & 3);
+                              (sl->ref_list[j][i].reference & 3);
      }
  
 +    h0->au_pps_id = pps_id;
 +    h->sps.new =
 +    h0->sps_buffers[h->pps.sps_id]->new = 0;
 +    h->current_sps_id = h->pps.sps_id;
 +
      if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
          av_log(h->avctx, AV_LOG_DEBUG,
                 "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
@@@ -2057,7 -1836,7 +2057,7 @@@ static av_always_inline void fill_filte
          if (USES_LIST(top_type, list)) {
              const int b_xy  = h->mb2b_xy[top_xy] + 3 * b_stride;
              const int b8_xy = 4 * top_xy + 2;
-             int (*ref2frm)[64] = (void*)(h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2));
 -            int (*ref2frm)[64] = sl->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2);
++            int (*ref2frm)[64] = (void*)(sl->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2));
              AV_COPY128(mv_dst - 1 * 8, h->cur_pic.motion_val[list][b_xy + 0]);
              ref_cache[0 - 1 * 8] =
              ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 0]];
              if (USES_LIST(left_type[LTOP], list)) {
                  const int b_xy  = h->mb2b_xy[left_xy[LTOP]] + 3;
                  const int b8_xy = 4 * left_xy[LTOP] + 1;
-                 int (*ref2frm)[64] =(void*)( h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2));
 -                int (*ref2frm)[64] = sl->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2);
++                int (*ref2frm)[64] =(void*)( sl->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2));
                  AV_COPY32(mv_dst - 1 +  0, h->cur_pic.motion_val[list][b_xy + b_stride * 0]);
                  AV_COPY32(mv_dst - 1 +  8, h->cur_pic.motion_val[list][b_xy + b_stride * 1]);
                  AV_COPY32(mv_dst - 1 + 16, h->cur_pic.motion_val[list][b_xy + b_stride * 2]);
  
      {
          int8_t *ref = &h->cur_pic.ref_index[list][4 * mb_xy];
-         int (*ref2frm)[64] = (void*)(h->ref2frm[sl->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2));
 -        int (*ref2frm)[64] = sl->ref2frm[sl->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2);
++        int (*ref2frm)[64] = (void*)(sl->ref2frm[sl->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2));
          uint32_t ref01 = (pack16to32(ref2frm[list][ref[0]], ref2frm[list][ref[1]]) & 0x00FF00FF) * 0x0101;
          uint32_t ref23 = (pack16to32(ref2frm[list][ref[2]], ref2frm[list][ref[3]]) & 0x00FF00FF) * 0x0101;
          AV_WN32A(&ref_cache[0 * 8], ref01);
@@@ -2376,23 -2155,25 +2376,24 @@@ static void decode_finish_row(H264Conte
          top    = 0;
      }
  
-     ff_h264_draw_horiz_band(h, top, height);
+     ff_h264_draw_horiz_band(h, sl, top, height);
  
 -    if (h->droppable)
 +    if (h->droppable || h->er.error_occurred)
          return;
  
      ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1,
                                h->picture_structure == PICT_BOTTOM_FIELD);
  }
  
- static void er_add_slice(H264Context *h, int startx, int starty,
+ static void er_add_slice(H264Context *h, H264SliceContext *sl,
+                          int startx, int starty,
                           int endx, int endy, int status)
  {
 -#if CONFIG_ERROR_RESILIENCE
 -    ERContext *er = &h->er;
 +    if (CONFIG_ERROR_RESILIENCE) {
 +        ERContext *er = &h->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)
                      loop_filter(h, sl, lf_x_start, h->mb_x + 1);
                  return 0;
              }
 -            if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
 +            if (h->cabac.bytestream > h->cabac.bytestream_end + 2 )
 +                av_log(h->avctx, AV_LOG_DEBUG, "bytestream overread %"PTRDIFF_SPECIFIER"\n", h->cabac.bytestream_end - h->cabac.bytestream);
 +            if (ret < 0 || h->cabac.bytestream > h->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",
                         h->mb_x, h->mb_y,
                         h->cabac.bytestream_end - h->cabac.bytestream);
-                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                 er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, h->mb_x,
                               h->mb_y, ER_MB_ERROR);
                  return AVERROR_INVALIDDATA;
              }
                      tprintf(h->avctx, "slice end %d %d\n",
                              get_bits_count(&h->gb), h->gb.size_in_bits);
  
 -                    if (get_bits_left(&h->gb) == 0) {
 +                    if (   get_bits_left(&h->gb) == 0
 +                        || get_bits_left(&h->gb) > 0 && !(h->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
-                         er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                         er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y,
                                       h->mb_x - 1, h->mb_y, ER_MB_END);
  
                          return 0;
                      } else {
-                         er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                         er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y,
 -                                     h->mb_x - 1, h->mb_y, ER_MB_END);
 +                                     h->mb_x, h->mb_y, ER_MB_END);
  
                          return AVERROR_INVALIDDATA;
                      }
Simple merge
@@@ -355,343 -318,6 +355,343 @@@ int ff_vdpau_add_buffer(struct vdpau_pi
      return 0;
  }
  
-     ff_h264_draw_horiz_band(h, 0, h->avctx->height);
 +/* Obsolete non-hwaccel VDPAU support below... */
 +
 +void ff_vdpau_h264_set_reference_frames(H264Context *h)
 +{
 +    struct vdpau_render_state *render, *render_ref;
 +    VdpReferenceFrameH264 *rf, *rf2;
 +    H264Picture *pic;
 +    int i, list, pic_frame_idx;
 +
 +    render = (struct vdpau_render_state *)h->cur_pic_ptr->f.data[0];
 +    assert(render);
 +
 +    rf = &render->info.h264.referenceFrames[0];
 +#define H264_RF_COUNT FF_ARRAY_ELEMS(render->info.h264.referenceFrames)
 +
 +    for (list = 0; list < 2; ++list) {
 +        H264Picture **lp = list ? h->long_ref : h->short_ref;
 +        int ls = list ? 16 : h->short_ref_count;
 +
 +        for (i = 0; i < ls; ++i) {
 +            pic = lp[i];
 +            if (!pic || !pic->reference)
 +                continue;
 +            pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
 +
 +            render_ref = (struct vdpau_render_state *)pic->f.data[0];
 +            assert(render_ref);
 +
 +            rf2 = &render->info.h264.referenceFrames[0];
 +            while (rf2 != rf) {
 +                if (
 +                    (rf2->surface == render_ref->surface)
 +                    && (rf2->is_long_term == pic->long_ref)
 +                    && (rf2->frame_idx == pic_frame_idx)
 +                )
 +                    break;
 +                ++rf2;
 +            }
 +            if (rf2 != rf) {
 +                rf2->top_is_reference    |= (pic->reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
 +                rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
 +                continue;
 +            }
 +
 +            if (rf >= &render->info.h264.referenceFrames[H264_RF_COUNT])
 +                continue;
 +
 +            rf->surface             = render_ref->surface;
 +            rf->is_long_term        = pic->long_ref;
 +            rf->top_is_reference    = (pic->reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
 +            rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
 +            rf->field_order_cnt[0]  = pic->field_poc[0];
 +            rf->field_order_cnt[1]  = pic->field_poc[1];
 +            rf->frame_idx           = pic_frame_idx;
 +
 +            ++rf;
 +        }
 +    }
 +
 +    for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf) {
 +        rf->surface             = VDP_INVALID_HANDLE;
 +        rf->is_long_term        = 0;
 +        rf->top_is_reference    = 0;
 +        rf->bottom_is_reference = 0;
 +        rf->field_order_cnt[0]  = 0;
 +        rf->field_order_cnt[1]  = 0;
 +        rf->frame_idx           = 0;
 +    }
 +}
 +
 +void ff_vdpau_add_data_chunk(uint8_t *data, const uint8_t *buf, int buf_size)
 +{
 +    struct vdpau_render_state *render = (struct vdpau_render_state*)data;
 +    assert(render);
 +
 +    render->bitstream_buffers= av_fast_realloc(
 +        render->bitstream_buffers,
 +        &render->bitstream_buffers_allocated,
 +        sizeof(*render->bitstream_buffers)*(render->bitstream_buffers_used + 1)
 +    );
 +
 +    render->bitstream_buffers[render->bitstream_buffers_used].struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
 +    render->bitstream_buffers[render->bitstream_buffers_used].bitstream       = buf;
 +    render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = buf_size;
 +    render->bitstream_buffers_used++;
 +}
 +
 +#if CONFIG_H264_VDPAU_DECODER
 +void ff_vdpau_h264_picture_start(H264Context *h)
 +{
 +    struct vdpau_render_state *render;
 +    int i;
 +
 +    render = (struct vdpau_render_state *)h->cur_pic_ptr->f.data[0];
 +    assert(render);
 +
 +    for (i = 0; i < 2; ++i) {
 +        int foc = h->cur_pic_ptr->field_poc[i];
 +        if (foc == INT_MAX)
 +            foc = 0;
 +        render->info.h264.field_order_cnt[i] = foc;
 +    }
 +
 +    render->info.h264.frame_num = h->frame_num;
 +}
 +
 +void ff_vdpau_h264_picture_complete(H264Context *h)
 +{
 +    struct vdpau_render_state *render;
 +
 +    render = (struct vdpau_render_state *)h->cur_pic_ptr->f.data[0];
 +    assert(render);
 +
 +    render->info.h264.slice_count = h->current_slice;
 +    if (render->info.h264.slice_count < 1)
 +        return;
 +
 +    render->info.h264.is_reference                           = (h->cur_pic_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE;
 +    render->info.h264.field_pic_flag                         = h->picture_structure != PICT_FRAME;
 +    render->info.h264.bottom_field_flag                      = h->picture_structure == PICT_BOTTOM_FIELD;
 +    render->info.h264.num_ref_frames                         = h->sps.ref_frame_count;
 +    render->info.h264.mb_adaptive_frame_field_flag           = h->sps.mb_aff && !render->info.h264.field_pic_flag;
 +    render->info.h264.constrained_intra_pred_flag            = h->pps.constrained_intra_pred;
 +    render->info.h264.weighted_pred_flag                     = h->pps.weighted_pred;
 +    render->info.h264.weighted_bipred_idc                    = h->pps.weighted_bipred_idc;
 +    render->info.h264.frame_mbs_only_flag                    = h->sps.frame_mbs_only_flag;
 +    render->info.h264.transform_8x8_mode_flag                = h->pps.transform_8x8_mode;
 +    render->info.h264.chroma_qp_index_offset                 = h->pps.chroma_qp_index_offset[0];
 +    render->info.h264.second_chroma_qp_index_offset          = h->pps.chroma_qp_index_offset[1];
 +    render->info.h264.pic_init_qp_minus26                    = h->pps.init_qp - 26;
 +    render->info.h264.num_ref_idx_l0_active_minus1           = h->pps.ref_count[0] - 1;
 +    render->info.h264.num_ref_idx_l1_active_minus1           = h->pps.ref_count[1] - 1;
 +    render->info.h264.log2_max_frame_num_minus4              = h->sps.log2_max_frame_num - 4;
 +    render->info.h264.pic_order_cnt_type                     = h->sps.poc_type;
 +    render->info.h264.log2_max_pic_order_cnt_lsb_minus4      = h->sps.poc_type ? 0 : h->sps.log2_max_poc_lsb - 4;
 +    render->info.h264.delta_pic_order_always_zero_flag       = h->sps.delta_pic_order_always_zero_flag;
 +    render->info.h264.direct_8x8_inference_flag              = h->sps.direct_8x8_inference_flag;
 +    render->info.h264.entropy_coding_mode_flag               = h->pps.cabac;
 +    render->info.h264.pic_order_present_flag                 = h->pps.pic_order_present;
 +    render->info.h264.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
 +    render->info.h264.redundant_pic_cnt_present_flag         = h->pps.redundant_pic_cnt_present;
 +    memcpy(render->info.h264.scaling_lists_4x4, h->pps.scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4));
 +    memcpy(render->info.h264.scaling_lists_8x8[0], h->pps.scaling_matrix8[0], sizeof(render->info.h264.scaling_lists_8x8[0]));
 +    memcpy(render->info.h264.scaling_lists_8x8[1], h->pps.scaling_matrix8[3], sizeof(render->info.h264.scaling_lists_8x8[0]));
 +
++    ff_h264_draw_horiz_band(h, &h->slice_ctx[0], 0, h->avctx->height);
 +    render->bitstream_buffers_used = 0;
 +}
 +#endif /* CONFIG_H264_VDPAU_DECODER */
 +
 +#if CONFIG_MPEG_VDPAU_DECODER || CONFIG_MPEG1_VDPAU_DECODER
 +void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
 +                                    int buf_size, int slice_count)
 +{
 +    struct vdpau_render_state *render, *last, *next;
 +    int i;
 +
 +    if (!s->current_picture_ptr) return;
 +
 +    render = (struct vdpau_render_state *)s->current_picture_ptr->f->data[0];
 +    assert(render);
 +
 +    /* fill VdpPictureInfoMPEG1Or2 struct */
 +    render->info.mpeg.picture_structure          = s->picture_structure;
 +    render->info.mpeg.picture_coding_type        = s->pict_type;
 +    render->info.mpeg.intra_dc_precision         = s->intra_dc_precision;
 +    render->info.mpeg.frame_pred_frame_dct       = s->frame_pred_frame_dct;
 +    render->info.mpeg.concealment_motion_vectors = s->concealment_motion_vectors;
 +    render->info.mpeg.intra_vlc_format           = s->intra_vlc_format;
 +    render->info.mpeg.alternate_scan             = s->alternate_scan;
 +    render->info.mpeg.q_scale_type               = s->q_scale_type;
 +    render->info.mpeg.top_field_first            = s->top_field_first;
 +    render->info.mpeg.full_pel_forward_vector    = s->full_pel[0]; // MPEG-1 only.  Set 0 for MPEG-2
 +    render->info.mpeg.full_pel_backward_vector   = s->full_pel[1]; // MPEG-1 only.  Set 0 for MPEG-2
 +    render->info.mpeg.f_code[0][0]               = s->mpeg_f_code[0][0]; // For MPEG-1 fill both horiz. & vert.
 +    render->info.mpeg.f_code[0][1]               = s->mpeg_f_code[0][1];
 +    render->info.mpeg.f_code[1][0]               = s->mpeg_f_code[1][0];
 +    render->info.mpeg.f_code[1][1]               = s->mpeg_f_code[1][1];
 +    for (i = 0; i < 64; ++i) {
 +        render->info.mpeg.intra_quantizer_matrix[i]     = s->intra_matrix[i];
 +        render->info.mpeg.non_intra_quantizer_matrix[i] = s->inter_matrix[i];
 +    }
 +
 +    render->info.mpeg.forward_reference          = VDP_INVALID_HANDLE;
 +    render->info.mpeg.backward_reference         = VDP_INVALID_HANDLE;
 +
 +    switch(s->pict_type){
 +    case  AV_PICTURE_TYPE_B:
 +        next = (struct vdpau_render_state *)s->next_picture.f->data[0];
 +        assert(next);
 +        render->info.mpeg.backward_reference     = next->surface;
 +        // no return here, going to set forward prediction
 +    case  AV_PICTURE_TYPE_P:
 +        last = (struct vdpau_render_state *)s->last_picture.f->data[0];
 +        if (!last) // FIXME: Does this test make sense?
 +            last = render; // predict second field from the first
 +        render->info.mpeg.forward_reference      = last->surface;
 +    }
 +
 +    ff_vdpau_add_data_chunk(s->current_picture_ptr->f->data[0], buf, buf_size);
 +
 +    render->info.mpeg.slice_count                = slice_count;
 +
 +    if (slice_count)
 +        ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
 +    render->bitstream_buffers_used               = 0;
 +}
 +#endif /* CONFIG_MPEG_VDPAU_DECODER || CONFIG_MPEG1_VDPAU_DECODER */
 +
 +#if CONFIG_VC1_VDPAU_DECODER
 +void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
 +                                 int buf_size)
 +{
 +    VC1Context *v = s->avctx->priv_data;
 +    struct vdpau_render_state *render, *last, *next;
 +
 +    render = (struct vdpau_render_state *)s->current_picture.f->data[0];
 +    assert(render);
 +
 +    /*  fill LvPictureInfoVC1 struct */
 +    render->info.vc1.frame_coding_mode  = v->fcm ? v->fcm + 1 : 0;
 +    render->info.vc1.postprocflag       = v->postprocflag;
 +    render->info.vc1.pulldown           = v->broadcast;
 +    render->info.vc1.interlace          = v->interlace;
 +    render->info.vc1.tfcntrflag         = v->tfcntrflag;
 +    render->info.vc1.finterpflag        = v->finterpflag;
 +    render->info.vc1.psf                = v->psf;
 +    render->info.vc1.dquant             = v->dquant;
 +    render->info.vc1.panscan_flag       = v->panscanflag;
 +    render->info.vc1.refdist_flag       = v->refdist_flag;
 +    render->info.vc1.quantizer          = v->quantizer_mode;
 +    render->info.vc1.extended_mv        = v->extended_mv;
 +    render->info.vc1.extended_dmv       = v->extended_dmv;
 +    render->info.vc1.overlap            = v->overlap;
 +    render->info.vc1.vstransform        = v->vstransform;
 +    render->info.vc1.loopfilter         = v->s.loop_filter;
 +    render->info.vc1.fastuvmc           = v->fastuvmc;
 +    render->info.vc1.range_mapy_flag    = v->range_mapy_flag;
 +    render->info.vc1.range_mapy         = v->range_mapy;
 +    render->info.vc1.range_mapuv_flag   = v->range_mapuv_flag;
 +    render->info.vc1.range_mapuv        = v->range_mapuv;
 +    /* Specific to simple/main profile only */
 +    render->info.vc1.multires           = v->multires;
 +    render->info.vc1.syncmarker         = v->resync_marker;
 +    render->info.vc1.rangered           = v->rangered | (v->rangeredfrm << 1);
 +    render->info.vc1.maxbframes         = v->s.max_b_frames;
 +
 +    render->info.vc1.deblockEnable      = v->postprocflag & 1;
 +    render->info.vc1.pquant             = v->pq;
 +
 +    render->info.vc1.forward_reference  = VDP_INVALID_HANDLE;
 +    render->info.vc1.backward_reference = VDP_INVALID_HANDLE;
 +
 +    if (v->bi_type)
 +        render->info.vc1.picture_type = 4;
 +    else
 +        render->info.vc1.picture_type = s->pict_type - 1 + s->pict_type / 3;
 +
 +    switch(s->pict_type){
 +    case  AV_PICTURE_TYPE_B:
 +        next = (struct vdpau_render_state *)s->next_picture.f->data[0];
 +        assert(next);
 +        render->info.vc1.backward_reference = next->surface;
 +        // no break here, going to set forward prediction
 +    case  AV_PICTURE_TYPE_P:
 +        last = (struct vdpau_render_state *)s->last_picture.f->data[0];
 +        if (!last) // FIXME: Does this test make sense?
 +            last = render; // predict second field from the first
 +        render->info.vc1.forward_reference = last->surface;
 +    }
 +
 +    ff_vdpau_add_data_chunk(s->current_picture_ptr->f->data[0], buf, buf_size);
 +
 +    render->info.vc1.slice_count          = 1;
 +
 +    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
 +    render->bitstream_buffers_used        = 0;
 +}
 +#endif /* (CONFIG_VC1_VDPAU_DECODER */
 +
 +#if CONFIG_MPEG4_VDPAU_DECODER
 +void ff_vdpau_mpeg4_decode_picture(Mpeg4DecContext *ctx, const uint8_t *buf,
 +                                   int buf_size)
 +{
 +    MpegEncContext *s = &ctx->m;
 +    struct vdpau_render_state *render, *last, *next;
 +    int i;
 +
 +    if (!s->current_picture_ptr) return;
 +
 +    render = (struct vdpau_render_state *)s->current_picture_ptr->f->data[0];
 +    assert(render);
 +
 +    /* fill VdpPictureInfoMPEG4Part2 struct */
 +    render->info.mpeg4.trd[0]                            = s->pp_time;
 +    render->info.mpeg4.trb[0]                            = s->pb_time;
 +    render->info.mpeg4.trd[1]                            = s->pp_field_time >> 1;
 +    render->info.mpeg4.trb[1]                            = s->pb_field_time >> 1;
 +    render->info.mpeg4.vop_time_increment_resolution     = s->avctx->time_base.den;
 +    render->info.mpeg4.vop_coding_type                   = 0;
 +    render->info.mpeg4.vop_fcode_forward                 = s->f_code;
 +    render->info.mpeg4.vop_fcode_backward                = s->b_code;
 +    render->info.mpeg4.resync_marker_disable             = !ctx->resync_marker;
 +    render->info.mpeg4.interlaced                        = !s->progressive_sequence;
 +    render->info.mpeg4.quant_type                        = s->mpeg_quant;
 +    render->info.mpeg4.quarter_sample                    = s->quarter_sample;
 +    render->info.mpeg4.short_video_header                = s->avctx->codec->id == AV_CODEC_ID_H263;
 +    render->info.mpeg4.rounding_control                  = s->no_rounding;
 +    render->info.mpeg4.alternate_vertical_scan_flag      = s->alternate_scan;
 +    render->info.mpeg4.top_field_first                   = s->top_field_first;
 +    for (i = 0; i < 64; ++i) {
 +        render->info.mpeg4.intra_quantizer_matrix[i]     = s->intra_matrix[i];
 +        render->info.mpeg4.non_intra_quantizer_matrix[i] = s->inter_matrix[i];
 +    }
 +    render->info.mpeg4.forward_reference                 = VDP_INVALID_HANDLE;
 +    render->info.mpeg4.backward_reference                = VDP_INVALID_HANDLE;
 +
 +    switch (s->pict_type) {
 +    case AV_PICTURE_TYPE_B:
 +        next = (struct vdpau_render_state *)s->next_picture.f->data[0];
 +        assert(next);
 +        render->info.mpeg4.backward_reference     = next->surface;
 +        render->info.mpeg4.vop_coding_type        = 2;
 +        // no break here, going to set forward prediction
 +    case AV_PICTURE_TYPE_P:
 +        last = (struct vdpau_render_state *)s->last_picture.f->data[0];
 +        assert(last);
 +        render->info.mpeg4.forward_reference      = last->surface;
 +    }
 +
 +    ff_vdpau_add_data_chunk(s->current_picture_ptr->f->data[0], buf, buf_size);
 +
 +    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
 +    render->bitstream_buffers_used = 0;
 +}
 +#endif /* CONFIG_MPEG4_VDPAU_DECODER */
 +
  int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile)
  {
  #define PROFILE(prof)                      \
Simple merge