Merge commit 'c8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8'
authorClément Bœsch <u@pkh.me>
Sun, 12 Jun 2016 14:06:58 +0000 (16:06 +0200)
committerClément Bœsch <u@pkh.me>
Sun, 12 Jun 2016 17:01:43 +0000 (19:01 +0200)
* commit 'c8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8':
  h264: factor out calculating the POC count into a separate file

Merged-by: Clément Bœsch <u@pkh.me>
12 files changed:
1  2 
libavcodec/dxva2_h264.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_parse.c
libavcodec/h264_parse.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
@@@ -433,8 -403,6 +433,8 @@@ static int h264_init_context(AVCodecCon
      h->x264_build            = -1;
      h->recovery_frame        = -1;
      h->frame_recovered       = 0;
-     h->prev_frame_num        = -1;
++    h->poc.prev_frame_num    = -1;
 +    h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
  
      h->next_outputed_poc = INT_MIN;
      for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
@@@ -829,14 -812,11 +829,14 @@@ static void decode_postinit(H264Contex
   */
  static void idr(H264Context *h)
  {
 +    int i;
      ff_h264_remove_all_refs(h);
-     h->prev_frame_num        =
-     h->prev_frame_num_offset = 0;
-     h->prev_poc_msb          = 1<<16;
-     h->prev_poc_lsb          = 0;
+     h->poc.prev_frame_num        =
 -    h->poc.prev_frame_num_offset =
 -    h->poc.prev_poc_msb          =
++    h->poc.prev_frame_num_offset = 0;
++    h->poc.prev_poc_msb          = 1<<16;
+     h->poc.prev_poc_lsb          = 0;
 +    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
 +        h->last_pocs[i] = INT_MIN;
  }
  
  /* forget old pics after a seek */
@@@ -847,17 -828,8 +847,17 @@@ void ff_h264_flush_change(H264Context *
      h->next_outputed_poc = INT_MIN;
      h->prev_interlaced_frame = 1;
      idr(h);
 -    if (h->cur_pic_ptr)
 +
-     h->prev_frame_num = -1;
++    h->poc.prev_frame_num = -1;
 +    if (h->cur_pic_ptr) {
          h->cur_pic_ptr->reference = 0;
 +        for (j=i=0; h->delayed_pic[i]; i++)
 +            if (h->delayed_pic[i] != h->cur_pic_ptr)
 +                h->delayed_pic[j++] = h->delayed_pic[i];
 +        h->delayed_pic[j] = NULL;
 +    }
 +    ff_h264_unref_picture(h, &h->last_pic_for_ec);
 +
      h->first_field = 0;
      ff_h264_reset_sei(h);
      h->recovery_frame = -1;
@@@ -1147,23 -984,15 +1068,23 @@@ again
              if ((err = ff_h264_decode_slice_header(h, sl)))
                  break;
  
 -            if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
 -                h->recovery_frame = (h->poc.frame_num + h->sei_recovery_frame_cnt) &
 -                                    ((1 << h->ps.sps->log2_max_frame_num) - 1);
 +            if (h->sei_recovery_frame_cnt >= 0) {
-                 if (h->frame_num != h->sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I)
++                if (h->poc.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
-                     || av_mod_uintp2(h->recovery_frame - h->frame_num, h->ps.sps->log2_max_frame_num) > h->sei_recovery_frame_cnt) {
-                     h->recovery_frame = av_mod_uintp2(h->frame_num + h->sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num);
++                    || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > h->sei_recovery_frame_cnt) {
++                    h->recovery_frame = av_mod_uintp2(h->poc.frame_num + h->sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num);
 +
 +                    if (!h->valid_recovery_point)
-                         h->recovery_frame = h->frame_num;
++                        h->recovery_frame = h->poc.frame_num;
 +                }
              }
  
 -            h->cur_pic_ptr->f->key_frame |=
 -                (nal->type == NAL_IDR_SLICE) || (h->sei_recovery_frame_cnt >= 0);
 +            h->cur_pic_ptr->f->key_frame |= (nal->type == NAL_IDR_SLICE);
  
 -            if (nal->type == NAL_IDR_SLICE || h->recovery_frame == h->poc.frame_num) {
 +            if (nal->type == NAL_IDR_SLICE ||
-                 (h->recovery_frame == h->frame_num && nal->ref_idc)) {
++                (h->recovery_frame == h->poc.frame_num && nal->ref_idc)) {
                  h->recovery_frame         = -1;
                  h->cur_pic_ptr->recovered = 1;
              }
@@@ -1188,12 -1049,8 +1178,11 @@@ void ff_h264_unref_picture(H264Context 
  int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl);
  
  void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height);
- int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
  
  int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl);
 +#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);
Simple merge
@@@ -63,6 -76,10 +76,10 @@@ int ff_h264_check_intra_pred_mode(void 
  
  int ff_h264_parse_ref_count(int *plist_count, int ref_count[2],
                              GetBitContext *gb, const struct PPS *pps,
 -                            int slice_type_nos, int picture_structure);
 +                            int slice_type_nos, int picture_structure, void *logctx);
  
+ int ff_h264_init_poc(int pic_field_poc[2], int *pic_poc,
+                      const struct SPS *sps, H264POCContext *poc,
+                      int picture_structure, int nal_ref_idc);
  #endif /* AVCODEC_H264_PARSE_H */
@@@ -327,13 -275,13 +328,13 @@@ static inline int parse_nal_units(AVCod
          case NAL_IDR_SLICE:
              s->key_frame = 1;
  
-             h->prev_frame_num        = 0;
-             h->prev_frame_num_offset = 0;
-             h->prev_poc_msb          =
-             h->prev_poc_lsb          = 0;
+             p->poc.prev_frame_num        = 0;
+             p->poc.prev_frame_num_offset = 0;
+             p->poc.prev_poc_msb          =
+             p->poc.prev_poc_lsb          = 0;
          /* fall through */
          case NAL_SLICE:
 -            get_ue_golomb(&nal.gb);  // skip first_mb_in_slice
 +            get_ue_golomb_long(&nal.gb);  // skip first_mb_in_slice
              slice_type   = get_ue_golomb_31(&nal.gb);
              s->pict_type = ff_h264_golomb_to_pict_type[slice_type % 5];
              if (h->sei_recovery_frame_cnt >= 0) {
              h->ps.pps = p->ps.pps;
              sps = p->ps.sps;
  
-             h->frame_num = get_bits(&nal.gb, sps->log2_max_frame_num);
 +            // heuristic to detect non marked keyframes
 +            if (h->ps.sps->ref_frame_count <= 1 && h->ps.pps->ref_count[0] <= 1 && s->pict_type == AV_PICTURE_TYPE_I)
 +                s->key_frame = 1;
 +
+             p->poc.frame_num = get_bits(&nal.gb, sps->log2_max_frame_num);
  
              s->coded_width  = 16 * sps->mb_width;
              s->coded_height = 16 * sps->mb_height;
              }
  
              if (h->nal_unit_type == NAL_IDR_SLICE)
 -                get_ue_golomb(&nal.gb); /* idr_pic_id */
 +                get_ue_golomb_long(&nal.gb); /* idr_pic_id */
              if (sps->poc_type == 0) {
-                 h->poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb);
+                 p->poc.poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb);
  
                  if (p->ps.pps->pic_order_present == 1 &&
                      h->picture_structure == PICT_FRAME)
Simple merge
@@@ -725,11 -656,9 +725,11 @@@ int ff_h264_execute_ref_pic_marking(H26
              for (j = 0; j < 16; j++) {
                  remove_long(h, j, 0);
              }
-             h->frame_num  = h->cur_pic_ptr->frame_num = 0;
+             h->poc.frame_num = h->cur_pic_ptr->frame_num = 0;
              h->mmco_reset = 1;
              h->cur_pic_ptr->mmco_reset = 1;
 +            for (j = 0; j < MAX_DELAYED_PIC_COUNT; j++)
 +                h->last_pocs[j] = INT_MIN;
              break;
          default: assert(0);
          }
@@@ -418,10 -407,9 +418,10 @@@ int ff_h264_update_thread_context(AVCod
      // extradata/NAL handling
      h->is_avc = h1->is_avc;
      h->nal_length_size = h1->nal_length_size;
 +    h->x264_build      = h1->x264_build;
  
      // POC timing
-     copy_fields(h, h1, poc_lsb, current_slice);
+     copy_fields(h, h1, poc, current_slice);
  
      copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1);
      copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1);
  
      if (!h->droppable) {
          err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
-         h->prev_poc_msb = h->poc_msb;
-         h->prev_poc_lsb = h->poc_lsb;
+         h->poc.prev_poc_msb = h->poc.poc_msb;
+         h->poc.prev_poc_lsb = h->poc.poc_lsb;
      }
-     h->prev_frame_num_offset = h->frame_num_offset;
-     h->prev_frame_num        = h->frame_num;
+     h->poc.prev_frame_num_offset = h->poc.frame_num_offset;
+     h->poc.prev_frame_num        = h->poc.frame_num;
  
      h->recovery_frame        = h1->recovery_frame;
 -    h->frame_recovered       = h1->frame_recovered;
  
      return err;
  }
@@@ -1323,20 -1105,11 +1322,20 @@@ int ff_h264_decode_slice_header(H264Con
      }
  
      frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
-         if (h->frame_num != frame_num) {
 +    if (!first_slice) {
-                    h->frame_num, frame_num);
++        if (h->poc.frame_num != frame_num) {
 +            av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n",
++                   h->poc.frame_num, frame_num);
 +            return AVERROR_INVALIDDATA;
 +        }
 +    }
 +
      if (!h->setup_finished)
-         h->frame_num = frame_num;
+         h->poc.frame_num = frame_num;
  
      sl->mb_mbaff       = 0;
 -
 +    mb_aff_frame       = 0;
 +    last_mb_aff_frame  = h->mb_aff_frame;
      last_pic_structure = h->picture_structure;
      last_pic_droppable = h->droppable;
  
                     h->current_slice + 1);
              return AVERROR_INVALIDDATA;
          }
 -    } else {
 +    }
 +
 +    if (!h->setup_finished) {
 +        h->droppable         = droppable;
 +        h->picture_structure = picture_structure;
 +        h->mb_aff_frame      = mb_aff_frame;
 +    }
 +    sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;
 +
 +    if (h->current_slice == 0) {
          /* Shorten frame num gaps so we don't have to allocate reference
           * frames just to throw them away */
-         if (h->frame_num != h->prev_frame_num) {
-             int unwrap_prev_frame_num = h->prev_frame_num;
+         if (h->poc.frame_num != h->poc.prev_frame_num) {
+             int unwrap_prev_frame_num = h->poc.prev_frame_num;
              int max_frame_num         = 1 << sps->log2_max_frame_num;
  
-             if (unwrap_prev_frame_num > h->frame_num)
+             if (unwrap_prev_frame_num > h->poc.frame_num)
                  unwrap_prev_frame_num -= max_frame_num;
  
-             if ((h->frame_num - unwrap_prev_frame_num) > sps->ref_frame_count) {
-                 unwrap_prev_frame_num = (h->frame_num - sps->ref_frame_count) - 1;
+             if ((h->poc.frame_num - unwrap_prev_frame_num) > sps->ref_frame_count) {
+                 unwrap_prev_frame_num = (h->poc.frame_num - sps->ref_frame_count) - 1;
                  if (unwrap_prev_frame_num < 0)
                      unwrap_prev_frame_num += max_frame_num;
  
              }
          }
  
-         while (h->frame_num != h->prev_frame_num && !h->first_field &&
-                h->frame_num != (h->prev_frame_num + 1) % (1 << sps->log2_max_frame_num)) {
 -        while (h->poc.frame_num != h->poc.prev_frame_num &&
++        while (h->poc.frame_num != h->poc.prev_frame_num && !h->first_field &&
+                h->poc.frame_num != (h->poc.prev_frame_num + 1) % (1 << sps->log2_max_frame_num)) {
              H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
              av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
-                    h->frame_num, h->prev_frame_num);
+                    h->poc.frame_num, h->poc.prev_frame_num);
 -            ret = initialize_cur_frame(h);
 +            if (!sps->gaps_in_frame_num_allowed_flag)
 +                for(i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)
 +                    h->last_pocs[i] = INT_MIN;
 +            ret = h264_frame_start(h);
              if (ret < 0) {
                  h->first_field = 0;
                  return ret;
              }
  
-             h->prev_frame_num++;
-             h->prev_frame_num        %= 1 << sps->log2_max_frame_num;
-             h->cur_pic_ptr->frame_num = h->prev_frame_num;
+             h->poc.prev_frame_num++;
+             h->poc.prev_frame_num        %= 1 << sps->log2_max_frame_num;
+             h->cur_pic_ptr->frame_num = h->poc.prev_frame_num;
 +            h->cur_pic_ptr->invalid_gap = !sps->gaps_in_frame_num_allowed_flag;
              ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
              ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
              ret = ff_generate_sliding_window_mmcos(h, 1);
                                    (const uint8_t **)prev->f->data,
                                    prev->f->linesize,
                                    prev->f->format,
 -                                  h->mb_width  * 16,
 -                                  h->mb_height * 16);
 +                                  prev->f->width,
 +                                  prev->f->height);
                      h->short_ref[0]->poc = prev->poc + 2;
                  }
-                 h->short_ref[0]->frame_num = h->prev_frame_num;
+                 h->short_ref[0]->frame_num = h->poc.prev_frame_num;
              }
          }
  
                  h->cur_pic_ptr = NULL;
                  h->first_field = FIELD_PICTURE(h);
              } else {
-                 if (h->cur_pic_ptr->frame_num != h->frame_num) {
 +                h->missing_fields = 0;
+                 if (h->cur_pic_ptr->frame_num != h->poc.frame_num) {
 +                    ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
 +                                              h->picture_structure==PICT_BOTTOM_FIELD);
                      /* This and the previous field had different frame_nums.
                       * Consider this field first in pair. Throw away previous
                       * one except for reference purposes. */
                                   FIELD_OR_MBAFF_PICTURE(h);
      if (h->picture_structure == PICT_BOTTOM_FIELD)
          sl->resync_mb_y = sl->mb_y = sl->mb_y + 1;
 -    assert(sl->mb_y < h->mb_height);
 +    av_assert1(sl->mb_y < h->mb_height);
  
      if (h->picture_structure == PICT_FRAME) {
-         h->curr_pic_num = h->frame_num;
+         h->curr_pic_num = h->poc.frame_num;
          h->max_pic_num  = 1 << sps->log2_max_frame_num;
      } else {
-         h->curr_pic_num = 2 * h->frame_num + 1;
+         h->curr_pic_num = 2 * h->poc.frame_num + 1;
          h->max_pic_num  = 1 << (sps->log2_max_frame_num + 1);
      }
  
Simple merge
@@@ -355,345 -317,6 +355,345 @@@ int ff_vdpau_add_buffer(struct vdpau_pi
      return 0;
  }
  
-     render->info.h264.frame_num = h->frame_num;
 +/* Obsolete non-hwaccel VDPAU support below... */
 +
 +#if FF_API_VDPAU
 +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_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_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->poc.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->ps.sps->ref_frame_count;
 +    render->info.h264.mb_adaptive_frame_field_flag           = h->ps.sps->mb_aff && !render->info.h264.field_pic_flag;
 +    render->info.h264.constrained_intra_pred_flag            = h->ps.pps->constrained_intra_pred;
 +    render->info.h264.weighted_pred_flag                     = h->ps.pps->weighted_pred;
 +    render->info.h264.weighted_bipred_idc                    = h->ps.pps->weighted_bipred_idc;
 +    render->info.h264.frame_mbs_only_flag                    = h->ps.sps->frame_mbs_only_flag;
 +    render->info.h264.transform_8x8_mode_flag                = h->ps.pps->transform_8x8_mode;
 +    render->info.h264.chroma_qp_index_offset                 = h->ps.pps->chroma_qp_index_offset[0];
 +    render->info.h264.second_chroma_qp_index_offset          = h->ps.pps->chroma_qp_index_offset[1];
 +    render->info.h264.pic_init_qp_minus26                    = h->ps.pps->init_qp - 26;
 +    render->info.h264.num_ref_idx_l0_active_minus1           = h->ps.pps->ref_count[0] - 1;
 +    render->info.h264.num_ref_idx_l1_active_minus1           = h->ps.pps->ref_count[1] - 1;
 +    render->info.h264.log2_max_frame_num_minus4              = h->ps.sps->log2_max_frame_num - 4;
 +    render->info.h264.pic_order_cnt_type                     = h->ps.sps->poc_type;
 +    render->info.h264.log2_max_pic_order_cnt_lsb_minus4      = h->ps.sps->poc_type ? 0 : h->ps.sps->log2_max_poc_lsb - 4;
 +    render->info.h264.delta_pic_order_always_zero_flag       = h->ps.sps->delta_pic_order_always_zero_flag;
 +    render->info.h264.direct_8x8_inference_flag              = h->ps.sps->direct_8x8_inference_flag;
 +    render->info.h264.entropy_coding_mode_flag               = h->ps.pps->cabac;
 +    render->info.h264.pic_order_present_flag                 = h->ps.pps->pic_order_present;
 +    render->info.h264.deblocking_filter_control_present_flag = h->ps.pps->deblocking_filter_parameters_present;
 +    render->info.h264.redundant_pic_cnt_present_flag         = h->ps.pps->redundant_pic_cnt_present;
 +    memcpy(render->info.h264.scaling_lists_4x4, h->ps.pps->scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4));
 +    memcpy(render->info.h264.scaling_lists_8x8[0], h->ps.pps->scaling_matrix8[0], sizeof(render->info.h264.scaling_lists_8x8[0]));
 +    memcpy(render->info.h264.scaling_lists_8x8[1], h->ps.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 */
 +#endif /* FF_API_VDPAU */
 +
  #if FF_API_VDPAU_PROFILE
  int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile)
  {
Simple merge