]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/v4l2_m2m_enc: buffer frame if it cannot be enqueued
authorAndriy Gelman <andriy.gelman@gmail.com>
Sun, 23 Aug 2020 17:33:37 +0000 (13:33 -0400)
committerAndriy Gelman <andriy.gelman@gmail.com>
Sun, 23 Aug 2020 17:42:07 +0000 (13:42 -0400)
Currently if the frame buffers are full, the frame is unrefed and
dropped.  Instead buffer the frame so that it is enqueued in the
next v4l2_receive_packet() call.  The behavior was observed on
DragonBoard 410c.

Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com>
libavcodec/v4l2_m2m.c
libavcodec/v4l2_m2m_enc.c

index 31600617fd4c81d058d2dca9bd0b49c35854576c..cdfd579810f21f89ea933a0f7bc2e41bcef8d8d0 100644 (file)
@@ -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_packet_unref(&s->buf_pkt);
 
index af0ed1e306623afb8b1f6f79bac8295043bd9007..4230a415fd9c301806f92e92502789d8cb11abb9 100644 (file)
@@ -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) {