[FFmpeg-cvslog] avcodec/hevc: fix no output of prior pics and pic output flags( cherry picked from commit e99b96dff1d76d74cb5633aa9702828d863050e2)
gcocherel
git at videolan.org
Tue Apr 29 23:16:30 CEST 2014
ffmpeg | branch: master | gcocherel <gildas.cocherel at laposte.net> | Tue Apr 29 11:29:16 2014 +0200| [2eddf3a6efd80aa6e9d7f42ad9a892a82c5ece70] | committer: Michael Niedermayer
avcodec/hevc: fix no output of prior pics and pic output flags(cherry picked from commit e99b96dff1d76d74cb5633aa9702828d863050e2)
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2eddf3a6efd80aa6e9d7f42ad9a892a82c5ece70
---
libavcodec/hevc.c | 27 +++++++++++++++++++++++++++
libavcodec/hevc.h | 1 +
libavcodec/hevc_refs.c | 12 ++++++++++++
3 files changed, 40 insertions(+)
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) &&
More information about the ffmpeg-cvslog
mailing list