mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
hevc: add support for bumping process
cherry picked from commit 8aa2fb7df3cffc67a3fd03a3a7eb49dbed4094c7 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
c0a586d9d5
commit
23480da0aa
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user