ffmpeg | branch: master | Clément Bœsch <[email protected]> | Sun Jun 12 16:06:58 2016 +0200| [bd3fd467febe92300e0ebf8ff13c193f9236479a] | committer: Clément Bœsch
Merge commit 'c8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8' * commit 'c8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8': h264: factor out calculating the POC count into a separate file Merged-by: Clément Bœsch <[email protected]> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=bd3fd467febe92300e0ebf8ff13c193f9236479a --- libavcodec/dxva2_h264.c | 2 +- libavcodec/h264.c | 103 ++++++--------------------------------------- libavcodec/h264.h | 13 +----- libavcodec/h264_parse.c | 80 +++++++++++++++++++++++++++++++++++ libavcodec/h264_parse.h | 17 ++++++++ libavcodec/h264_parser.c | 34 ++++++++------- libavcodec/h264_picture.c | 8 ++-- libavcodec/h264_refs.c | 2 +- libavcodec/h264_slice.c | 66 ++++++++++++++--------------- libavcodec/vaapi_h264.c | 2 +- libavcodec/vdpau.c | 2 +- libavcodec/vdpau_h264.c | 2 +- 12 files changed, 170 insertions(+), 161 deletions(-) diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index bd1fa1e..a6aa0f6 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -145,7 +145,7 @@ static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext * pp->num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1; pp->num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1; pp->Reserved8BitsA = 0; - pp->frame_num = h->frame_num; + pp->frame_num = h->poc.frame_num; pp->log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4; pp->pic_order_cnt_type = sps->poc_type; if (sps->poc_type == 0) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 0de6d91..367f6bf 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -429,11 +429,11 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) h->slice_context_count = 1; h->workaround_bugs = avctx->workaround_bugs; h->flags = avctx->flags; - h->prev_poc_msb = 1 << 16; + h->poc.prev_poc_msb = 1 << 16; 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; @@ -831,10 +831,10 @@ 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 = 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; } @@ -848,7 +848,7 @@ void ff_h264_flush_change(H264Context *h) h->prev_interlaced_frame = 1; idr(h); - 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++) @@ -889,85 +889,6 @@ static void flush_dpb(AVCodecContext *avctx) h->context_initialized = 0; } -int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc) -{ - const SPS *sps = h->ps.sps; - const int max_frame_num = 1 << sps->log2_max_frame_num; - int field_poc[2]; - - h->frame_num_offset = h->prev_frame_num_offset; - if (h->frame_num < h->prev_frame_num) - h->frame_num_offset += max_frame_num; - - if (sps->poc_type == 0) { - const int max_poc_lsb = 1 << sps->log2_max_poc_lsb; - - if (h->poc_lsb < h->prev_poc_lsb && - h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2) - h->poc_msb = h->prev_poc_msb + max_poc_lsb; - else if (h->poc_lsb > h->prev_poc_lsb && - h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2) - h->poc_msb = h->prev_poc_msb - max_poc_lsb; - else - h->poc_msb = h->prev_poc_msb; - field_poc[0] = - field_poc[1] = h->poc_msb + h->poc_lsb; - if (h->picture_structure == PICT_FRAME) - field_poc[1] += h->delta_poc_bottom; - } else if (sps->poc_type == 1) { - int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc; - int i; - - if (sps->poc_cycle_length != 0) - abs_frame_num = h->frame_num_offset + h->frame_num; - else - abs_frame_num = 0; - - if (h->nal_ref_idc == 0 && abs_frame_num > 0) - abs_frame_num--; - - expected_delta_per_poc_cycle = 0; - for (i = 0; i < sps->poc_cycle_length; i++) - // FIXME integrate during sps parse - expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i]; - - if (abs_frame_num > 0) { - int poc_cycle_cnt = (abs_frame_num - 1) / sps->poc_cycle_length; - int frame_num_in_poc_cycle = (abs_frame_num - 1) % sps->poc_cycle_length; - - expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle; - for (i = 0; i <= frame_num_in_poc_cycle; i++) - expectedpoc = expectedpoc + sps->offset_for_ref_frame[i]; - } else - expectedpoc = 0; - - if (h->nal_ref_idc == 0) - expectedpoc = expectedpoc + sps->offset_for_non_ref_pic; - - field_poc[0] = expectedpoc + h->delta_poc[0]; - field_poc[1] = field_poc[0] + sps->offset_for_top_to_bottom_field; - - if (h->picture_structure == PICT_FRAME) - field_poc[1] += h->delta_poc[1]; - } else { - int poc = 2 * (h->frame_num_offset + h->frame_num); - - if (!h->nal_ref_idc) - poc--; - - field_poc[0] = poc; - field_poc[1] = poc; - } - - if (h->picture_structure != PICT_BOTTOM_FIELD) - pic_field_poc[0] = field_poc[0]; - if (h->picture_structure != PICT_TOP_FIELD) - pic_field_poc[1] = field_poc[1]; - *pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]); - - return 0; -} - /** * Compute profile from profile_idc and constraint_set?_flags. * @@ -1148,22 +1069,22 @@ again: break; 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); 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; } diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 99262ae..da8a92f 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -648,17 +648,7 @@ typedef struct H264Context { uint16_t *slice_table_base; - // POC stuff - int poc_lsb; - int poc_msb; - int delta_poc_bottom; - int delta_poc[2]; - int frame_num; - int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0 - int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0 - int frame_num_offset; ///< for POC type 2 - int prev_frame_num_offset; ///< for POC type 2 - int prev_frame_num; ///< frame_num of the last pic for POC type 1/2 + H264POCContext poc; /** * frame_num for frames or 2 * frame_num + 1 for field pics. @@ -1188,7 +1178,6 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic); 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 diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index 4f125b5..d99d4ae 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -239,3 +239,83 @@ fail: ref_count[1] = 0; return AVERROR_INVALIDDATA; } + +int ff_h264_init_poc(int pic_field_poc[2], int *pic_poc, + const SPS *sps, H264POCContext *pc, + int picture_structure, int nal_ref_idc) +{ + const int max_frame_num = 1 << sps->log2_max_frame_num; + int field_poc[2]; + + pc->frame_num_offset = pc->prev_frame_num_offset; + if (pc->frame_num < pc->prev_frame_num) + pc->frame_num_offset += max_frame_num; + + if (sps->poc_type == 0) { + const int max_poc_lsb = 1 << sps->log2_max_poc_lsb; + + if (pc->poc_lsb < pc->prev_poc_lsb && + pc->prev_poc_lsb - pc->poc_lsb >= max_poc_lsb / 2) + pc->poc_msb = pc->prev_poc_msb + max_poc_lsb; + else if (pc->poc_lsb > pc->prev_poc_lsb && + pc->prev_poc_lsb - pc->poc_lsb < -max_poc_lsb / 2) + pc->poc_msb = pc->prev_poc_msb - max_poc_lsb; + else + pc->poc_msb = pc->prev_poc_msb; + field_poc[0] = + field_poc[1] = pc->poc_msb + pc->poc_lsb; + if (picture_structure == PICT_FRAME) + field_poc[1] += pc->delta_poc_bottom; + } else if (sps->poc_type == 1) { + int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc; + int i; + + if (sps->poc_cycle_length != 0) + abs_frame_num = pc->frame_num_offset + pc->frame_num; + else + abs_frame_num = 0; + + if (nal_ref_idc == 0 && abs_frame_num > 0) + abs_frame_num--; + + expected_delta_per_poc_cycle = 0; + for (i = 0; i < sps->poc_cycle_length; i++) + // FIXME integrate during sps parse + expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i]; + + if (abs_frame_num > 0) { + int poc_cycle_cnt = (abs_frame_num - 1) / sps->poc_cycle_length; + int frame_num_in_poc_cycle = (abs_frame_num - 1) % sps->poc_cycle_length; + + expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle; + for (i = 0; i <= frame_num_in_poc_cycle; i++) + expectedpoc = expectedpoc + sps->offset_for_ref_frame[i]; + } else + expectedpoc = 0; + + if (nal_ref_idc == 0) + expectedpoc = expectedpoc + sps->offset_for_non_ref_pic; + + field_poc[0] = expectedpoc + pc->delta_poc[0]; + field_poc[1] = field_poc[0] + sps->offset_for_top_to_bottom_field; + + if (picture_structure == PICT_FRAME) + field_poc[1] += pc->delta_poc[1]; + } else { + int poc = 2 * (pc->frame_num_offset + pc->frame_num); + + if (!nal_ref_idc) + poc--; + + field_poc[0] = poc; + field_poc[1] = poc; + } + + if (picture_structure != PICT_BOTTOM_FIELD) + pic_field_poc[0] = field_poc[0]; + if (picture_structure != PICT_TOP_FIELD) + pic_field_poc[1] = field_poc[1]; + *pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]); + + return 0; +} diff --git a/libavcodec/h264_parse.h b/libavcodec/h264_parse.h index 0fac629..413f04d 100644 --- a/libavcodec/h264_parse.h +++ b/libavcodec/h264_parse.h @@ -39,6 +39,19 @@ typedef struct H264PredWeightTable { int implicit_weight[48][48][2]; } H264PredWeightTable; +typedef struct H264POCContext { + int poc_lsb; + int poc_msb; + int delta_poc_bottom; + int delta_poc[2]; + int frame_num; + int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0 + int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0 + int frame_num_offset; ///< for POC type 2 + int prev_frame_num_offset; ///< for POC type 2 + int prev_frame_num; ///< frame_num of the last pic for POC type 1/2 +} H264POCContext; + struct SPS; struct PPS; @@ -65,4 +78,8 @@ 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, 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 */ diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 51ca9f2..e0977ea 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -49,6 +49,7 @@ typedef struct H264ParseContext { ParseContext pc; H264ParamSets ps; H264DSPContext h264dsp; + H264POCContext poc; int got_first; } H264ParseContext; @@ -327,10 +328,10 @@ static inline int parse_nal_units(AVCodecParserContext *s, 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_long(&nal.gb); // skip first_mb_in_slice @@ -367,7 +368,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, 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; - h->frame_num = get_bits(&nal.gb, sps->log2_max_frame_num); + 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; @@ -414,26 +415,27 @@ static inline int parse_nal_units(AVCodecParserContext *s, if (h->nal_unit_type == NAL_IDR_SLICE) 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) - h->delta_poc_bottom = get_se_golomb(&nal.gb); + p->poc.delta_poc_bottom = get_se_golomb(&nal.gb); } if (sps->poc_type == 1 && !sps->delta_pic_order_always_zero_flag) { - h->delta_poc[0] = get_se_golomb(&nal.gb); + p->poc.delta_poc[0] = get_se_golomb(&nal.gb); if (p->ps.pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) - h->delta_poc[1] = get_se_golomb(&nal.gb); + p->poc.delta_poc[1] = get_se_golomb(&nal.gb); } /* Decode POC of this picture. * The prev_ values needed for decoding POC of the next picture are not set here. */ field_poc[0] = field_poc[1] = INT_MAX; - ff_init_poc(h, field_poc, &s->output_picture_number); + ff_h264_init_poc(field_poc, &s->output_picture_number, sps, + &p->poc, h->picture_structure, nal.ref_idc); /* Continue parsing to check if MMCO_RESET is present. * FIXME: MMCO_RESET could appear in non-first slice. @@ -446,15 +448,15 @@ static inline int parse_nal_units(AVCodecParserContext *s, } /* Set up the prev_ values for decoding POC of the next picture. */ - h->prev_frame_num = got_reset ? 0 : h->frame_num; - h->prev_frame_num_offset = got_reset ? 0 : h->frame_num_offset; + p->poc.prev_frame_num = got_reset ? 0 : p->poc.frame_num; + p->poc.prev_frame_num_offset = got_reset ? 0 : p->poc.frame_num_offset; if (h->nal_ref_idc != 0) { if (!got_reset) { - h->prev_poc_msb = h->poc_msb; - h->prev_poc_lsb = h->poc_lsb; + p->poc.prev_poc_msb = p->poc.poc_msb; + p->poc.prev_poc_lsb = p->poc.poc_lsb; } else { - h->prev_poc_msb = 0; - h->prev_poc_lsb = + p->poc.prev_poc_msb = 0; + p->poc.prev_poc_lsb = h->picture_structure == PICT_BOTTOM_FIELD ? 0 : field_poc[0]; } } diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index c4b17c0..e2e324b 100644 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -166,11 +166,11 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup) if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) { 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; } if (avctx->hwaccel) { diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 02c7867..2b90168 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -725,7 +725,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) 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++) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 394a0c4..6c09707 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -421,7 +421,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, 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); @@ -435,11 +435,11 @@ int ff_h264_update_thread_context(AVCodecContext *dst, 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; @@ -476,8 +476,7 @@ static int h264_frame_start(H264Context *h) pic->reference = h->droppable ? 0 : h->picture_structure; pic->f->coded_picture_number = h->coded_picture_number++; pic->field_picture = h->picture_structure != PICT_FRAME; - pic->frame_num = h->frame_num; - + pic->frame_num = h->poc.frame_num; /* * Zero key_frame here; IDR markings per slice in frame or fields are ORed * in later. @@ -1324,15 +1323,15 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) frame_num = get_bits(&sl->gb, sps->log2_max_frame_num); if (!first_slice) { - if (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->frame_num, frame_num); + 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; @@ -1385,19 +1384,19 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) 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; - h->prev_frame_num = unwrap_prev_frame_num; + h->poc.prev_frame_num = unwrap_prev_frame_num; } } @@ -1426,7 +1425,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) last_pic_structure == PICT_TOP_FIELD); } } else { - if (h->cur_pic_ptr->frame_num != h->frame_num) { + if (h->cur_pic_ptr->frame_num != h->poc.frame_num) { /* This and previous field were reference, but had * different frame_nums. Consider this field first in * pair. Throw away previous field except for reference @@ -1458,11 +1457,11 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) } } - 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 && !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); 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; @@ -1472,9 +1471,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) 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); @@ -1505,7 +1504,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) 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; } } @@ -1526,7 +1525,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) h->first_field = FIELD_PICTURE(h); } else { h->missing_fields = 0; - if (h->cur_pic_ptr->frame_num != h->frame_num) { + 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. @@ -1577,10 +1576,10 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) 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); } @@ -1591,12 +1590,12 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) int poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb); if (!h->setup_finished) - h->poc_lsb = poc_lsb; + h->poc.poc_lsb = poc_lsb; if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) { int delta_poc_bottom = get_se_golomb(&sl->gb); if (!h->setup_finished) - h->delta_poc_bottom = delta_poc_bottom; + h->poc.delta_poc_bottom = delta_poc_bottom; } } @@ -1604,18 +1603,19 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) int delta_poc = get_se_golomb(&sl->gb); if (!h->setup_finished) - h->delta_poc[0] = delta_poc; + h->poc.delta_poc[0] = delta_poc; if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) { delta_poc = get_se_golomb(&sl->gb); if (!h->setup_finished) - h->delta_poc[1] = delta_poc; + h->poc.delta_poc[1] = delta_poc; } } if (!h->setup_finished) - ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc); + ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc, + sps, &h->poc, h->picture_structure, h->nal_ref_idc); if (pps->redundant_pic_cnt_present) sl->redundant_pic_count = get_ue_golomb(&sl->gb); @@ -1829,7 +1829,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) av_get_picture_type_char(sl->slice_type), sl->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "", - pps_id, h->frame_num, + pps_id, h->poc.frame_num, h->cur_pic_ptr->field_poc[0], h->cur_pic_ptr->field_poc[1], sl->ref_count[0], sl->ref_count[1], diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 9b13fa9..91ee2d6 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -279,7 +279,7 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx, pic_param->pic_fields.bits.deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present; pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present; pic_param->pic_fields.bits.reference_pic_flag = h->nal_ref_idc != 0; - pic_param->frame_num = h->frame_num; + pic_param->frame_num = h->poc.frame_num; /* Fill in VAIQMatrixBufferH264. */ iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferH264)); diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index d791d15..057f907 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -459,7 +459,7 @@ void ff_vdpau_h264_picture_start(H264Context *h) render->info.h264.field_order_cnt[i] = foc; } - render->info.h264.frame_num = h->frame_num; + render->info.h264.frame_num = h->poc.frame_num; } void ff_vdpau_h264_picture_complete(H264Context *h) diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c index 124fc98..a915461 100644 --- a/libavcodec/vdpau_h264.c +++ b/libavcodec/vdpau_h264.c @@ -134,7 +134,7 @@ static int vdpau_h264_start_frame(AVCodecContext *avctx, info->field_order_cnt[0] = h264_foc(pic->field_poc[0]); info->field_order_cnt[1] = h264_foc(pic->field_poc[1]); info->is_reference = h->nal_ref_idc != 0; - info->frame_num = h->frame_num; + info->frame_num = h->poc.frame_num; info->field_pic_flag = h->picture_structure != PICT_FRAME; info->bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD; info->num_ref_frames = sps->ref_frame_count; ====================================================================== diff --cc libavcodec/h264.c index 0de6d91,e415103..367f6bf --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@@ -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; } diff --cc libavcodec/h264.h index 99262ae,007ce58..da8a92f --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@@ -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); diff --cc libavcodec/h264_parse.h index 0fac629,c47b420..413f04d --- a/libavcodec/h264_parse.h +++ b/libavcodec/h264_parse.h @@@ -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 */ diff --cc libavcodec/h264_parser.c index 51ca9f2,991a841..e0977ea --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@@ -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) { @@@ -363,11 -311,7 +364,11 @@@ h->ps.pps = p->ps.pps; sps = p->ps.sps; + // 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; + - h->frame_num = get_bits(&nal.gb, sps->log2_max_frame_num); + 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; @@@ -412,9 -356,9 +413,9 @@@ } 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) diff --cc libavcodec/h264_refs.c index 02c7867,08c3bff..2b90168 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@@ -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); } diff --cc libavcodec/h264_slice.c index 394a0c4,82a5a82..6c09707 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@@ -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); @@@ -435,13 -421,14 +435,13 @@@ 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 (!first_slice) { - if (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->frame_num, frame_num); ++ 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; @@@ -1373,27 -1146,18 +1372,27 @@@ 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; @@@ -1458,24 -1216,20 +1457,24 @@@ } } - 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); @@@ -1501,11 -1255,11 +1500,11 @@@ (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; } } @@@ -1525,10 -1278,7 +1524,10 @@@ h->cur_pic_ptr = NULL; h->first_field = FIELD_PICTURE(h); } else { + h->missing_fields = 0; - if (h->cur_pic_ptr->frame_num != h->frame_num) { + 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. */ @@@ -1574,13 -1315,13 +1573,13 @@@ 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); } diff --cc libavcodec/vdpau.c index d791d15,bf5f8d9..057f907 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@@ -355,345 -317,6 +355,345 @@@ int ff_vdpau_add_buffer(struct vdpau_pi return 0; } +/* 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->frame_num; ++ 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) { _______________________________________________ ffmpeg-cvslog mailing list [email protected] http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
