diff options
author | gcocherel <gildas.cocherel@laposte.net> | 2014-04-29 11:29:16 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-04-29 22:43:25 +0200 |
commit | 2eddf3a6efd80aa6e9d7f42ad9a892a82c5ece70 (patch) | |
tree | 9c686e413206da2dd2bb45cccdcd78d50acf0caf /libavcodec | |
parent | 978c193d47c08edad5aa1931a89622c3a0a5c601 (diff) | |
download | ffmpeg-streaming-2eddf3a6efd80aa6e9d7f42ad9a892a82c5ece70.zip ffmpeg-streaming-2eddf3a6efd80aa6e9d7f42ad9a892a82c5ece70.tar.gz |
avcodec/hevc: fix no output of prior pics and pic output flags(cherry picked from commit e99b96dff1d76d74cb5633aa9702828d863050e2)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/hevc.c | 27 | ||||
-rw-r--r-- | libavcodec/hevc.h | 1 | ||||
-rw-r--r-- | libavcodec/hevc_refs.c | 12 |
3 files changed, 40 insertions, 0 deletions
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 63097ed..9ee0d26 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -349,6 +349,17 @@ fail: return ret; } +static int is_sps_exist(HEVCContext *s, const HEVCSPS* last_sps) +{ + int i; + + for( i = 0; i < MAX_SPS_COUNT; i++) + if(s->sps_list[i]) + if (last_sps == (HEVCSPS*)s->sps_list[i]->data) + return 1; + return 0; +} + static int hls_slice_header(HEVCContext *s) { GetBitContext *gb = &s->HEVClc->gb; @@ -363,8 +374,11 @@ static int hls_slice_header(HEVCContext *s) if (IS_IDR(s)) ff_hevc_clear_refs(s); } + sh->no_output_of_prior_pics_flag = 0; if (s->nal_unit_type >= 16 && s->nal_unit_type <= 23) sh->no_output_of_prior_pics_flag = get_bits1(gb); + if (s->nal_unit_type == NAL_CRA_NUT && s->last_eos == 1) + sh->no_output_of_prior_pics_flag = 1; sh->pps_id = get_ue_golomb_long(gb); if (sh->pps_id >= MAX_PPS_COUNT || !s->pps_list[sh->pps_id]) { @@ -379,7 +393,16 @@ static int hls_slice_header(HEVCContext *s) s->pps = (HEVCPPS*)s->pps_list[sh->pps_id]->data; if (s->sps != (HEVCSPS*)s->sps_list[s->pps->sps_id]->data) { + const HEVCSPS* last_sps = s->sps; s->sps = (HEVCSPS*)s->sps_list[s->pps->sps_id]->data; + if (last_sps) { + if (is_sps_exist(s, last_sps)) { + if (s->sps->width != last_sps->width || s->sps->height != last_sps->height || + s->sps->temporal_layer[s->sps->max_sub_layers - 1].max_dec_pic_buffering != last_sps->temporal_layer[last_sps->max_sub_layers - 1].max_dec_pic_buffering) + sh->no_output_of_prior_pics_flag = 0; + } else + sh->no_output_of_prior_pics_flag = 0; + } ff_hevc_clear_refs(s); ret = set_sps(s, s->sps); if (ret < 0) @@ -438,6 +461,7 @@ static int hls_slice_header(HEVCContext *s) return AVERROR_INVALIDDATA; } + sh->pic_output_flag = 1; if (s->pps->output_flag_present_flag) sh->pic_output_flag = get_bits1(gb); @@ -2530,6 +2554,7 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) int i, consumed, ret = 0; s->ref = NULL; + s->last_eos = s->eos; s->eos = 0; /* split the input packet into NAL units, so we know the upper bound on the @@ -2886,6 +2911,7 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) ff_dsputil_init(&s->dsp, avctx); s->context_initialized = 1; + s->eos = 0; return 0; @@ -2950,6 +2976,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->seq_output = s0->seq_output; s->pocTid0 = s0->pocTid0; s->max_ra = s0->max_ra; + s->eos = s0->eos; s->is_nalff = s0->is_nalff; s->nal_length_size = s0->nal_length_size; diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 0512721..4e85742 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -793,6 +793,7 @@ typedef struct HEVCContext { int pocTid0; int slice_idx; ///< number of the slice being currently decoded int eos; ///< current packet contains an EOS/EOB NAL + int last_eos; ///< last packet contains an EOS/EOB NAL int max_ra; int bs_width; int bs_height; diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 3a8e4a3..24d55d1 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -146,6 +146,8 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc) ref->poc = poc; ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; + if (s->sh.pic_output_flag == 0) + ref->flags &= ~(HEVC_FRAME_FLAG_OUTPUT); ref->sequence = s->seq_decode; ref->window = s->sps->output_window; @@ -159,6 +161,16 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) int min_poc = INT_MAX; int i, min_idx, ret; + if (s->sh.no_output_of_prior_pics_flag == 1) { + for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { + HEVCFrame *frame = &s->DPB[i]; + if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) && frame->poc != s->poc && + frame->sequence == s->seq_output) { + frame->flags &= ~(HEVC_FRAME_FLAG_OUTPUT); + } + } + } + for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { HEVCFrame *frame = &s->DPB[i]; if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) && |