vp8 encoder can be configured to drop frames, when e.g. bitrate overshoot is detected. At present the code responsible for managing an internal fifo assumes that we will get an output frame per each frame fed into encoder. That is not the case if the encoder can decide to drop frames.
Running: ffmpeg -stream_loop 100 -i dash_video3.webm -c:v libvpx -b:v 50k -drop-threshold 20 -screen-content-mode 2 output.webm results in lots of warnings like: [libvpx @ 0x563fd8aba100] Mismatching timestamps: libvpx 2187 queued 2185; this is a bug, please report it [libvpx @ 0x563fd8aba100] Mismatching timestamps: libvpx 2189 queued 2186; this is a bug, please report it followed by: [vost#0:0/libvpx @ 0x563fd8ab9b40] [enc:libvpx @ 0x563fd8aba080] Error submitting video frame to the encoder [vost#0:0/libvpx @ 0x563fd8ab9b40] [enc:libvpx @ 0x563fd8aba080] Error encoding a frame: No space left on device [vost#0:0/libvpx @ 0x563fd8ab9b40] Task finished with error code: -28 (No space left on device) [vost#0:0/libvpx @ 0x563fd8ab9b40] Terminating thread with return code -28 (No space left on device) The reason for the above error is that each dropped frame leaves an extra item in the fifo, which eventually overflows. The proposed fix is to keep popping elements from the fifo until the one with the matching pts is found. A side effect of this change is that the code no longer considers pts mismatch to be a bug. This has likely regressed around 5bda4ec6c3cb6f286bb40dee4457c3c26e0f78cb when fifo started to be universally used. Signed-off-by: Dariusz Marcinkiewicz <[email protected]> --- libavcodec/libvpxenc.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 05c34a6857..c537c96603 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -383,6 +383,18 @@ static int frame_data_submit(AVCodecContext *avctx, AVFifo *fifo, } ret = av_fifo_write(fifo, &fd, 1); + if (ret == AVERROR(ENOSPC)) { + FrameData fd2; + + av_log(avctx, AV_LOG_WARNING, "Fifo full, will drop a front element\n"); + + ret = av_fifo_read(fifo, &fd2, 1); + if (ret >= 0) { + frame_data_uninit(&fd2); + ret = av_fifo_write(fifo, &fd, 1); + } + } + if (ret < 0) goto fail; @@ -398,13 +410,18 @@ static int frame_data_apply(AVCodecContext *avctx, AVFifo *fifo, AVPacket *pkt) uint8_t *data; int ret = 0; - if (av_fifo_peek(fifo, &fd, 1, 0) < 0) - return 0; - if (fd.pts != pkt->pts) { - av_log(avctx, AV_LOG_WARNING, - "Mismatching timestamps: libvpx %"PRId64" queued %"PRId64"; " - "this is a bug, please report it\n", pkt->pts, fd.pts); - goto skip; + while (1) { + if (av_fifo_peek(fifo, &fd, 1, 0) < 0) + return 0; + + if (fd.pts == pkt->pts) { + break; + } + + av_log(avctx, AV_LOG_DEBUG, "Dropped frame with pts %"PRId64"\n", + fd.pts); + av_fifo_drain2(fifo, 1); + frame_data_uninit(&fd); } pkt->duration = fd.duration; -- 2.52.0.487.g5c8c507ade-goog _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
