diff options
author | Mickaƫl Raulet <mraulet@insa-rennes.fr> | 2014-07-26 14:27:56 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-07-26 15:40:34 +0200 |
commit | 23480da0aa70b045b7b8dea7da8fedde0bcd7062 (patch) | |
tree | 46889cf309f1eb90221b01187f1db5c426df8535 /libavcodec | |
parent | c0a586d9d5cd99e9f36e4d190f9aa137803378dc (diff) | |
download | ffmpeg-23480da0aa70b045b7b8dea7da8fedde0bcd7062.tar.gz |
hevc: add support for bumping process
cherry picked from commit 8aa2fb7df3cffc67a3fd03a3a7eb49dbed4094c7
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/hevc.c | 3 | ||||
-rw-r--r-- | libavcodec/hevc.h | 3 | ||||
-rw-r--r-- | libavcodec/hevc_refs.c | 49 |
3 files changed, 52 insertions, 3 deletions
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index af74034281..e71d39ce0b 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -2601,6 +2601,9 @@ static int hevc_frame_start(HEVCContext *s) s->frame->pict_type = 3 - s->sh.slice_type; + if (!IS_IRAP(s)) + ff_hevc_bump_frame(s); + av_frame_unref(s->output_frame); ret = ff_hevc_output_frame(s, s->output_frame, 0); if (ret < 0) diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index a1e2e8469e..bf0090f37c 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -719,6 +719,7 @@ typedef struct DBParams { #define HEVC_FRAME_FLAG_OUTPUT (1 << 0) #define HEVC_FRAME_FLAG_SHORT_REF (1 << 1) #define HEVC_FRAME_FLAG_LONG_REF (1 << 2) +#define HEVC_FRAME_FLAG_BUMPING (1 << 3) typedef struct HEVCFrame { AVFrame *frame; @@ -1016,6 +1017,8 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc); */ int ff_hevc_output_frame(HEVCContext *s, AVFrame *frame, int flush); +void ff_hevc_bump_frame(HEVCContext *s); + void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags); void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 136cc6ff0e..bb55aa8a80 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -166,9 +166,9 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) 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 && + if (!(frame->flags & HEVC_FRAME_FLAG_BUMPING) && frame->poc != s->poc && frame->sequence == s->seq_output) { - frame->flags &= ~(HEVC_FRAME_FLAG_OUTPUT); + ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT); } } } @@ -198,7 +198,10 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) int pixel_shift = !!(desc->comp[0].depth_minus1 > 7); ret = av_frame_ref(out, src); - ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT); + if (frame->flags & HEVC_FRAME_FLAG_BUMPING) + ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); + else + ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT); if (ret < 0) return ret; @@ -223,6 +226,46 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) return 0; } +void ff_hevc_bump_frame(HEVCContext *s) +{ + int dpb = 0; + int min_poc = INT_MAX; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { + HEVCFrame *frame = &s->DPB[i]; + if ((frame->flags) && + frame->sequence == s->seq_output && + frame->poc != s->poc) { + dpb++; + } + } + + if (s->sps && dpb >= s->sps->temporal_layer[s->sps->max_sub_layers - 1].max_dec_pic_buffering) { + for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { + HEVCFrame *frame = &s->DPB[i]; + if ((frame->flags) && + frame->sequence == s->seq_output && + frame->poc != s->poc) { + if (frame->flags == HEVC_FRAME_FLAG_OUTPUT && frame->poc < min_poc) { + min_poc = frame->poc; + } + } + } + + for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { + HEVCFrame *frame = &s->DPB[i]; + if (frame->flags & HEVC_FRAME_FLAG_OUTPUT && + frame->sequence == s->seq_output && + frame->poc <= min_poc) { + frame->flags |= HEVC_FRAME_FLAG_BUMPING; + } + } + + dpb--; + } +} + static int init_slice_rpl(HEVCContext *s) { HEVCFrame *frame = s->ref; |