Merge commit '56febc993b928ccc039a32158ca60b234c311875'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 13:30:19 +0000 (14:30 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Mar 2015 13:30:19 +0000 (14:30 +0100)
* commit '56febc993b928ccc039a32158ca60b234c311875':
  h264: move the slice type variables into the per-slice context

Conflicts:
libavcodec/h264.c
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_slice.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
14 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_mb.c
libavcodec/h264_mvpred.h
libavcodec/h264_parser.c
libavcodec/h264_refs.c
libavcodec/h264_slice.c
libavcodec/svq3.c
libavcodec/vaapi_h264.c
libavcodec/vdpau.c

@@@ -275,10 -275,10 +275,10 @@@ static void fill_slice_long(AVCodecCont
              }
          }
      }
 -    slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
 +    slice->slice_qs_delta    = 0; /* XXX not implemented by FFmpeg */
      slice->slice_qp_delta    = sl->qscale - h->pps.init_qp;
      slice->redundant_pic_cnt = h->redundant_pic_count;
-     if (h->slice_type == AV_PICTURE_TYPE_B)
+     if (sl->slice_type == AV_PICTURE_TYPE_B)
          slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
      slice->cabac_init_idc = h->pps.cabac ? h->cabac_init_idc : 0;
      if (h->deblocking_filter < 2)
@@@ -1296,40 -1259,32 +1296,40 @@@ int ff_h264_set_parameter_from_sps(H264
      return 0;
  }
  
- int ff_set_ref_count(H264Context *h)
+ int ff_set_ref_count(H264Context *h, H264SliceContext *sl)
  {
      int ref_count[2], list_count;
 -    int num_ref_idx_active_override_flag, max_refs;
 +    int num_ref_idx_active_override_flag;
  
      // set defaults, might be overridden a few lines later
      ref_count[0] = h->pps.ref_count[0];
      ref_count[1] = h->pps.ref_count[1];
  
-     if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
+     if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
 +        unsigned max[2];
 +        max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31;
 +
-         if (h->slice_type_nos == AV_PICTURE_TYPE_B)
+         if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
              h->direct_spatial_mv_pred = get_bits1(&h->gb);
          num_ref_idx_active_override_flag = get_bits1(&h->gb);
  
          if (num_ref_idx_active_override_flag) {
              ref_count[0] = get_ue_golomb(&h->gb) + 1;
-             if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
 -            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;
 +            return AVERROR_INVALIDDATA;
          }
  
-         if (h->slice_type_nos == AV_PICTURE_TYPE_B)
+         if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
              list_count = 2;
          else
              list_count = 1;
@@@ -1578,18 -1537,9 +1578,18 @@@ again
                  if ((err = ff_h264_decode_slice_header(hx, sl, h)))
                      break;
  
 -                if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
 -                    h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) &
 -                                        ((1 << h->sps.log2_max_frame_num) - 1);
 +                if (h->sei_recovery_frame_cnt >= 0) {
-                     if (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I)
++                    if (h->frame_num != h->sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I)
 +                        h->valid_recovery_point = 1;
 +
 +                    if (   h->recovery_frame < 0
 +                        || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt) {
 +                        h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) &
 +                                            ((1 << h->sps.log2_max_frame_num) - 1);
 +
 +                        if (!h->valid_recovery_point)
 +                            h->recovery_frame = h->frame_num;
 +                    }
                  }
  
                  h->cur_pic_ptr->f.key_frame |=
@@@ -879,10 -819,10 +880,10 @@@ int ff_h264_decode_mb_cabac(H264Contex
  
  void ff_h264_init_cabac_states(H264Context *h, H264SliceContext *sl);
  
 -void h264_init_dequant_tables(H264Context *h);
 +void ff_h264_init_dequant_tables(H264Context *h);
  
  void ff_h264_direct_dist_scale_factor(H264Context *const h);
- void ff_h264_direct_ref_list_init(H264Context *const h);
+ void ff_h264_direct_ref_list_init(H264Context *const h, H264SliceContext *sl);
  void ff_h264_pred_direct_motion(H264Context *const h, H264SliceContext *sl,
                                  int *mb_type);
  
@@@ -1158,12 -1057,9 +1159,12 @@@ int ff_h264_set_parameter_from_sps(H264
  void ff_h264_draw_horiz_band(H264Context *h, int y, int height);
  int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
  int ff_pred_weight_table(H264Context *h, H264SliceContext *sl);
- int ff_set_ref_count(H264Context *h);
+ int ff_set_ref_count(H264Context *h, H264SliceContext *sl);
  
  int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Context *h0);
 +#define SLICE_SINGLETHREAD 1
 +#define SLICE_SKIPED 2
 +
  int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count);
  int ff_h264_update_thread_context(AVCodecContext *dst,
                                    const AVCodecContext *src);
@@@ -1282,8 -1282,9 +1282,9 @@@ void ff_h264_init_cabac_states(H264Cont
      }
  }
  
- static int decode_cabac_field_decoding_flag(H264Context *h) {
+ static int decode_cabac_field_decoding_flag(H264Context *h, H264SliceContext *sl)
+ {
 -    const long mbb_xy = h->mb_xy - 2L*h->mb_stride;
 +    const int mbb_xy = h->mb_xy - 2*h->mb_stride;
  
      unsigned long ctx = 0;
  
@@@ -1947,9 -1947,9 +1950,9 @@@ int ff_h264_decode_mb_cabac(H264Contex
  
      fill_decode_neighbors(h, sl, -(MB_FIELD(h)));
  
-     if( h->slice_type_nos == AV_PICTURE_TYPE_B ) {
+     if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
          int ctx = 0;
-         av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_B);
 -        assert(sl->slice_type_nos == AV_PICTURE_TYPE_B);
++        av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_B);
  
          if (!IS_DIRECT(sl->left_type[LTOP] - 1))
              ctx++;
          }
      } else {
          mb_type = decode_cabac_intra_mb_type(h, sl, 3, 1);
-         if(h->slice_type == AV_PICTURE_TYPE_SI && mb_type)
+         if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)
              mb_type--;
-         av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_I);
 -        assert(sl->slice_type_nos == AV_PICTURE_TYPE_I);
++        av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_I);
  decode_intra_mb:
          partition_count = 0;
          cbp= i_mb_type_info[mb_type].cbp;
@@@ -716,9 -708,9 +716,9 @@@ int ff_h264_decode_mb_cavlc(H264Contex
      tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
      cbp = 0; /* avoid warning. FIXME: find a solution without slowing
                  down the code */
-     if(h->slice_type_nos != AV_PICTURE_TYPE_I){
+     if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
          if(h->mb_skip_run==-1)
 -            h->mb_skip_run= get_ue_golomb(&h->gb);
 +            h->mb_skip_run= get_ue_golomb_long(&h->gb);
  
          if (h->mb_skip_run--) {
              if(FRAME_MBAFF(h) && (h->mb_y&1) == 0){
              goto decode_intra_mb;
          }
      }else{
-        av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_I);
-         if(h->slice_type == AV_PICTURE_TYPE_SI && mb_type)
 -       assert(sl->slice_type_nos == AV_PICTURE_TYPE_I);
++       av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_I);
+         if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)
              mb_type--;
  decode_intra_mb:
          if(mb_type > 25){
                  sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
              }
          }else{
-             av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
 -            assert(sl->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
++            av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
              for(i=0; i<4; i++){
                  h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                  if(h->sub_mb_type[i] >=4){
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1326,31 -1212,26 +1326,31 @@@ int ff_h264_decode_slice_header(H264Con
      }
      if (slice_type > 4) {
          slice_type -= 5;
-         h->slice_type_fixed = 1;
+         sl->slice_type_fixed = 1;
      } else
-         h->slice_type_fixed = 0;
+         sl->slice_type_fixed = 0;
  
      slice_type = golomb_to_pict_type[slice_type];
-     h->slice_type     = slice_type;
-     h->slice_type_nos = slice_type & 3;
 -    if (slice_type == AV_PICTURE_TYPE_I ||
 -        (h0->current_slice != 0 && slice_type == h0->last_slice_type)) {
 -        default_ref_list_done = 1;
 -    }
+     sl->slice_type     = slice_type;
+     sl->slice_type_nos = slice_type & 3;
  
      if (h->nal_unit_type  == NAL_IDR_SLICE &&
-         h->slice_type_nos != AV_PICTURE_TYPE_I) {
+         sl->slice_type_nos != AV_PICTURE_TYPE_I) {
          av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n");
          return AVERROR_INVALIDDATA;
      }
  
-         (h->avctx->skip_frame >= AVDISCARD_BIDIR  && h->slice_type_nos == AV_PICTURE_TYPE_B) ||
-         (h->avctx->skip_frame >= AVDISCARD_NONINTRA && h->slice_type_nos != AV_PICTURE_TYPE_I) ||
 +    if (
 +        (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) ||
++        (h->avctx->skip_frame >= AVDISCARD_BIDIR  && sl->slice_type_nos == AV_PICTURE_TYPE_B) ||
++        (h->avctx->skip_frame >= AVDISCARD_NONINTRA && sl->slice_type_nos != AV_PICTURE_TYPE_I) ||
 +        (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE) ||
 +         h->avctx->skip_frame >= AVDISCARD_ALL) {
 +         return SLICE_SKIPED;
 +     }
 +
      // to make a few old functions happy, it's wrong though
-     h->pict_type = h->slice_type;
+     h->pict_type = sl->slice_type;
  
      pps_id = get_ue_golomb(&h->gb);
      if (pps_id >= MAX_PPS_COUNT) {
      if (h->pps.redundant_pic_cnt_present)
          h->redundant_pic_count = get_ue_golomb(&h->gb);
  
-     ret = ff_set_ref_count(h);
+     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)))) {
 +
-         ff_h264_fill_default_ref_list(h);
+         ff_h264_fill_default_ref_list(h, sl);
 +    }
  
-     if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
+     if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
         ret = ff_h264_decode_ref_pic_list_reordering(h);
         if (ret < 0) {
             h->ref_count[1] = h->ref_count[0] = 0;
  
      if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||
          (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
-          h->slice_type_nos != AV_PICTURE_TYPE_I) ||
 +         h->nal_unit_type != NAL_IDR_SLICE) ||
 +        (h->avctx->skip_loop_filter >= AVDISCARD_NONINTRA &&
+          sl->slice_type_nos != AV_PICTURE_TYPE_I) ||
          (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&
-          h->slice_type_nos == AV_PICTURE_TYPE_B) ||
+          sl->slice_type_nos == AV_PICTURE_TYPE_B) ||
          (h->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
           h->nal_ref_idc == 0))
          h->deblocking_filter = 0;
                     6 * (h->sps.bit_depth_luma - 8);
  
      h0->last_slice_type = slice_type;
-     h->slice_num        = ++h0->current_slice;
 +    memcpy(h0->last_ref_count, h0->ref_count, sizeof(h0->last_ref_count));
 -    if (sl->slice_num >= MAX_SLICES) {
 -        av_log(h->avctx, AV_LOG_ERROR,
 -               "Too many slices, increase MAX_SLICES and recompile\n");
+     sl->slice_num       = ++h0->current_slice;
-     if (h->slice_num)
-         h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y;
-     if (   h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= h->resync_mb_y
-         && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= h->resync_mb_y
-         && h->slice_num >= MAX_SLICES) {
 +
-         av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES);
++    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++) {
@@@ -2105,7 -1884,7 +2105,7 @@@ static av_always_inline void fill_filte
  
      {
          int8_t *ref = &h->cur_pic.ref_index[list][4 * mb_xy];
-         int (*ref2frm)[64] = (void*)(h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2));
 -        int (*ref2frm)[64] = h->ref2frm[sl->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2);
++        int (*ref2frm)[64] = (void*)(h->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);
Simple merge
Simple merge
@@@ -355,343 -318,6 +355,343 @@@ int ff_vdpau_add_buffer(struct vdpau_pi
      return 0;
  }
  
-     render->info.h264.slice_count = h->slice_num;
 +/* 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, 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)                      \