diff mbox series

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

Message ID 20200717020918.385084-2-andriy.gelman@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel,1/3] avcodec/v4l2_context: return EAGAIN to signal full buffers
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Andriy Gelman July 17, 2020, 2:09 a.m. UTC
From: Andriy Gelman <andriy.gelman@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@gmail.com>
---
 libavcodec/v4l2_m2m.c     | 1 +
 libavcodec/v4l2_m2m_enc.c | 8 ++++++--
 2 files changed, 7 insertions(+), 2 deletions(-)
diff mbox series

Patch

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) {