diff mbox series

[FFmpeg-devel,7/8] lavc/libvpxenc: handle queue desync more gracefully

Message ID 20230228120104.2347-7-anton@khirnov.net
State Accepted
Commit 942fb48c38b9a26c4fe2b282cc11f9c22c68bf1f
Headers show
Series [FFmpeg-devel,1/8] lavu/frame: improve AVFrame.opaque[_ref] documentation | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch

Commit Message

Anton Khirnov Feb. 28, 2023, 12:01 p.m. UTC
If the packets returned by libvpx and our internal frame properties
queue get desynchronized for some reason (should not happen, but it is
not clear libvpx API guarantees this), we will keep adding to the queue
indefinitely and never remove anything.

Change the code to drain the queue even if timestamps do not match.
---
 libavcodec/libvpxenc.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 33f35bbaf4..aeeaa0e681 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -401,11 +401,16 @@  static int frame_data_apply(AVCodecContext *avctx, AVFifo *fifo, AVPacket *pkt)
 {
     FrameData fd;
     uint8_t *data;
+    int ret = 0;
+
     if (av_fifo_peek(fifo, &fd, 1, 0) < 0)
         return 0;
-    if (fd.pts != pkt->pts)
-        return 0;
-    av_fifo_drain2(fifo, 1);
+    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;
+    }
 
 #if FF_API_REORDERED_OPAQUE
 FF_DISABLE_DEPRECATION_WARNINGS
@@ -419,20 +424,22 @@  FF_ENABLE_DEPRECATION_WARNINGS
         pkt->opaque_ref     = fd.frame_opaque_ref;
         fd.frame_opaque_ref = NULL;
     }
-    av_buffer_unref(&fd.frame_opaque_ref);
 
     if (fd.hdr10_plus) {
         data = av_packet_new_side_data(pkt, AV_PKT_DATA_DYNAMIC_HDR10_PLUS, fd.hdr10_plus->size);
         if (!data) {
-            av_buffer_unref(&fd.hdr10_plus);
-            return AVERROR(ENOMEM);
+            ret = AVERROR(ENOMEM);
+            goto skip;
         }
 
         memcpy(data, fd.hdr10_plus->data, fd.hdr10_plus->size);
-        av_buffer_unref(&fd.hdr10_plus);
     }
 
-    return 0;
+skip:
+    av_fifo_drain2(fifo, 1);
+    frame_data_uninit(&fd);
+
+    return ret;
 }
 
 static av_cold int codecctl_int(AVCodecContext *avctx,