aboutsummaryrefslogtreecommitdiffstats
path: root/libavdevice/v4l2.c
diff options
context:
space:
mode:
authorGiorgio Vazzana <mywing81@gmail.com>2013-03-09 14:36:56 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-03-09 16:58:53 +0100
commit0286b425409702a111fe72bc0efe529a5bafc4ed (patch)
tree2d4af41eae3e4e5f4ab5a13934cdba4c45123220 /libavdevice/v4l2.c
parent982070c113d70b4b97743c56ba9cd3e32c70169b (diff)
downloadffmpeg-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.c16
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);
}