[FFmpeg-cvslog] lavd/v4l2: correctly handle error conditions in mmap_read_frame()

Giorgio Vazzana git at videolan.org
Sat Mar 9 17:15:07 CET 2013


ffmpeg | branch: master | Giorgio Vazzana <mywing81 at gmail.com> | Sat Mar  9 14:36:56 2013 +0100| [0286b425409702a111fe72bc0efe529a5bafc4ed] | committer: Michael Niedermayer

lavd/v4l2: correctly handle error conditions in mmap_read_frame()

In particular:

1) save errno before it (possibly) gets overwritten by other calls
2) do not forget to enqueue the buffer again in case of error

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=0286b425409702a111fe72bc0efe529a5bafc4ed
---

 libavdevice/v4l2.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 14306bd..e12ca05 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -610,15 +610,17 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
         res = av_new_packet(pkt, buf.bytesused);
         if (res < 0) {
             av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");
+            if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0)
+                avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
             return res;
         }
         memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);
 
-        res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
-        if (res < 0) {
-            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");
+        if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
+            res = AVERROR(errno);
+            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
             av_free_packet(pkt);
-            return AVERROR(errno);
+            return res;
         }
         avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
     } else {
@@ -636,7 +638,8 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
              * allocate a buffer for memcpying into it
              */
             av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
-            res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
+            if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0)
+                avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
 
             return AVERROR(ENOMEM);
         }
@@ -647,6 +650,9 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
         pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,
                                     buf_descriptor, 0);
         if (!pkt->buf) {
+            av_log(ctx, AV_LOG_ERROR, "Failed to create a buffer\n");
+            if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0)
+                avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
             av_freep(&buf_descriptor);
             return AVERROR(ENOMEM);
         }



More information about the ffmpeg-cvslog mailing list