diff options
author | Giorgio Vazzana <mywing81@gmail.com> | 2013-03-09 14:36:56 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-03-09 16:58:53 +0100 |
commit | 0286b425409702a111fe72bc0efe529a5bafc4ed (patch) | |
tree | 2d4af41eae3e4e5f4ab5a13934cdba4c45123220 /libavdevice/v4l2.c | |
parent | 982070c113d70b4b97743c56ba9cd3e32c70169b (diff) | |
download | ffmpeg-0286b425409702a111fe72bc0efe529a5bafc4ed.tar.gz |
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@gmx.at>
Diffstat (limited to 'libavdevice/v4l2.c')
-rw-r--r-- | libavdevice/v4l2.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 14306bd1a2..e12ca053fb 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); } |