[FFmpeg-devel] [PATCH 2/3] avcodec/v4l2_m2m_enc: buffer frame if it cannot be enqueued

Andriy Gelman andriy.gelman at gmail.com
Fri Jul 17 05:09:17 EEST 2020


From: Andriy Gelman <andriy.gelman at gmail.com>

Currently if the frame buffers are full, the frame is unrefed and
dropped.  Instead buffer the frame so that it is enqueued in the
following v4l2_receive_packet() call.  The behavior was observed on
DragonBoard 410c.

Signed-off-by: Andriy Gelman <andriy.gelman at gmail.com>
---
 libavcodec/v4l2_m2m.c     | 1 +
 libavcodec/v4l2_m2m_enc.c | 8 ++++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c
index d8d872ea099..6b545045100 100644
--- a/libavcodec/v4l2_m2m.c
+++ b/libavcodec/v4l2_m2m.c
@@ -329,6 +329,7 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)
     sem_destroy(&s->refsync);
 
     close(s->fd);
+    av_frame_unref(s->frame);
     av_frame_free(&s->frame);
 
     av_free(s);
diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c
index 56df4286add..6d74c4c083d 100644
--- a/libavcodec/v4l2_m2m_enc.c
+++ b/libavcodec/v4l2_m2m_enc.c
@@ -295,16 +295,20 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
     if (s->draining)
         goto dequeue;
 
+    if (!frame->buf[0]) {
     ret = ff_encode_get_frame(avctx, frame);
     if (ret < 0 && ret != AVERROR_EOF)
         return ret;
 
     if (ret == AVERROR_EOF)
         frame = NULL;
+    }
 
     ret = v4l2_send_frame(avctx, frame);
-    av_frame_unref(frame);
-    if (ret < 0)
+    if (ret != AVERROR(EAGAIN))
+        av_frame_unref(frame);
+
+    if (ret < 0 && ret != AVERROR(EAGAIN))
         return ret;
 
     if (!output->streamon) {
-- 
2.27.0



More information about the ffmpeg-devel mailing list