Skip to content

Commit

Permalink
vp9_raw_reorder: Reducing caching
Browse files Browse the repository at this point in the history
Up until now, vp9_raw_reorder was very conservative wrt the amount of
frames it buffered internally: It held onto them for as long as possible
and only output them when necessary, namely when a frame that is not yet
completely output is about to leave the reference frame buffer or when a
non-reference frame is encountered or when flushing at EOF.

Now a fourth scenario in which to output frames has been added: When a
frame that ought to be shown immediately (i.e. show_frame == 1) is
encountered, one can already output the current frame and all frames
preceding the current frame in decoding order as well as all outstanding
show_existing_frame-frames corresponding to frames whose pts is < the pts
of the new frame.

This also provides a workaround for a bug in ffmpeg.c: If the copyinkf
option is not used, then all non-keyframes preceding the second keyframe
do not even reach the vp9_raw_reorder bsf: Because the first keyframe
isn't immediately output, FFmpeg's counter of output frames is still
zero after the first keyframe has been sent to the bsf, so that any
further packet before the second keyframe is considered a leading
non-keyframe to be dropped. Now vp9_raw_reorder outputs the first
keyframe immediately in the common case that it is a show_frame.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
  • Loading branch information
mkver committed Jun 15, 2019
1 parent 88261db commit f94e1b0
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions libavcodec/vp9_raw_reorder_bsf.c
Expand Up @@ -363,28 +363,31 @@ static int vp9_raw_reorder_filter(AVBSFContext *bsf, AVPacket *out)
vp9_raw_reorder_clear_slot(ctx, s);
}

for (s = 0; s < FRAME_SLOTS; s++) {
if (!(frame->refresh_frame_flags & (1 << s)))
continue;
ctx->slot[s] = frame;
}
frame->slots = frame->refresh_frame_flags;

if (!frame->refresh_frame_flags) {
// If the new frame is a frame that ought to be shown immediately,
// then we can already output the current frame and all frames
// preceding the current frame in decoding order as well as all
// outstanding show_existing_frame-frames corresponding to frames
// whose pts is < the pts of the current frame.
if (frame->needs_output && (!frame->refresh_frame_flags ||
frame->show_frame)) {
err = vp9_raw_reorder_make_output(bsf, out, frame);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to create output "
"for transient frame.\n");
av_log(bsf, AV_LOG_ERROR, "Failed to create output.\n");
ctx->next_frame = NULL;
goto fail;
}
if (!frame->needs_display) {
vp9_raw_reorder_frame_free(&frame);
ctx->next_frame = NULL;
}
if (!frame->refresh_frame_flags && !frame->needs_output)
vp9_raw_reorder_frame_free(&ctx->next_frame);
return 0;
}

for (s = 0; s < FRAME_SLOTS; s++) {
if (!(frame->refresh_frame_flags & (1 << s)))
continue;
ctx->slot[s] = frame;
}
frame->slots = frame->refresh_frame_flags;

ctx->next_frame = NULL;
return AVERROR(EAGAIN);

Expand Down

0 comments on commit f94e1b0

Please sign in to comment.