[FFmpeg-devel] [PATCH] avcodec/v4l2_m2m_dec: dequeue frame if input isn't ready

Cameron Gutman aicommander at gmail.com
Tue Dec 14 04:12:15 EET 2021


The V4L2M2M API operates asynchronously, so multiple packets can
be enqueued before getting a batch of frames back. Since it was
only possible to receive a frame by submitting another packet,
there wasn't a way to drain those excess output frames from when
avcodec_receive_frame() returned AVERROR(EAGAIN).

In my testing, this change reduced decode latency of a real-time
60 FPS H.264 stream by approximately 10x (200ms -> 20ms) on a
Raspberry Pi 4.

Signed-off-by: Cameron Gutman <aicommander at gmail.com>
---
 libavcodec/v4l2_m2m_dec.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
index 224eb3d5e7..b0c3d30ac8 100644
--- a/libavcodec/v4l2_m2m_dec.c
+++ b/libavcodec/v4l2_m2m_dec.c
@@ -142,8 +142,12 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
 
     if (!s->buf_pkt.size) {
         ret = ff_decode_get_packet(avctx, &s->buf_pkt);
-        if (ret < 0 && ret != AVERROR_EOF)
-            return ret;
+        if (ret < 0) {
+            if (ret == AVERROR(EAGAIN))
+                return ff_v4l2_context_dequeue_frame(capture, frame, 0);
+            else if (ret != AVERROR_EOF)
+                return ret;
+        }
     }
 
     if (s->draining)
-- 
2.25.1



More information about the ffmpeg-devel mailing list