summaryrefslogtreecommitdiff
path: root/libavcodec/hevc_refs.c
diff options
context:
space:
mode:
authorMickaƫl Raulet <mraulet@insa-rennes.fr>2014-07-26 14:27:56 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-07-26 15:40:34 +0200
commit23480da0aa70b045b7b8dea7da8fedde0bcd7062 (patch)
tree46889cf309f1eb90221b01187f1db5c426df8535 /libavcodec/hevc_refs.c
parentc0a586d9d5cd99e9f36e4d190f9aa137803378dc (diff)
hevc: add support for bumping process
cherry picked from commit 8aa2fb7df3cffc67a3fd03a3a7eb49dbed4094c7 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/hevc_refs.c')
-rw-r--r--libavcodec/hevc_refs.c49
1 files changed, 46 insertions, 3 deletions
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;