summaryrefslogtreecommitdiff
path: root/libavdevice
diff options
context:
space:
mode:
authorGiorgio Vazzana <mywing81@gmail.com>2014-09-01 22:20:05 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-09-06 00:05:59 +0200
commitd7e088849e33fc339ab14d3d10ada241c50880c1 (patch)
tree1b1cb413d5f1bfbaa70a5c09fd9d0cbf2f35eb97 /libavdevice
parentc368538667121fb20c5414dfaf0fb273035a0854 (diff)
lavd/v4l2: introduce enqueue_buffer()
Additionally, make sure a buffer gets enqueued again (even in error paths) after it has been succesfully dequeued. Tested-by: Dmitry Volyntsev <xeioexception@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavdevice')
-rw-r--r--libavdevice/v4l2.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index b473f7e6a3..cf7a92cdd4 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -399,10 +399,23 @@ static void dummy_release_buffer(AVPacket *pkt)
}
#endif
+static int enqueue_buffer(struct video_data *s, struct v4l2_buffer *buf)
+{
+ int res = 0;
+
+ if (v4l2_ioctl(s->fd, VIDIOC_QBUF, buf) < 0) {
+ res = AVERROR(errno);
+ av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
+ } else {
+ avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
+ }
+
+ return res;
+}
+
static void mmap_release_buffer(void *opaque, uint8_t *data)
{
struct v4l2_buffer buf = { 0 };
- int res;
struct buff_data *buf_descriptor = opaque;
struct video_data *s = buf_descriptor->s;
@@ -411,13 +424,7 @@ static void mmap_release_buffer(void *opaque, uint8_t *data)
buf.index = buf_descriptor->index;
av_free(buf_descriptor);
- if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
- res = AVERROR(errno);
- av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
- av_err2str(res));
- }
-
- avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
+ enqueue_buffer(s, &buf);
}
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
@@ -520,6 +527,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
av_log(ctx, AV_LOG_ERROR,
"The v4l2 frame is %d bytes, but %d bytes are expected\n",
buf.bytesused, s->frame_size);
+ enqueue_buffer(s, &buf);
return AVERROR_INVALIDDATA;
}
@@ -529,19 +537,16 @@ 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);
+ enqueue_buffer(s, &buf);
return res;
}
memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);
- 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));
+ res = enqueue_buffer(s, &buf);
+ if (res) {
av_free_packet(pkt);
return res;
}
- avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
} else {
struct buff_data *buf_descriptor;
@@ -559,8 +564,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
* allocate a buffer for memcpying into it
*/
av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
- if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0)
- avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
+ enqueue_buffer(s, &buf);
return AVERROR(ENOMEM);
}
@@ -571,8 +575,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
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);
+ enqueue_buffer(s, &buf);
av_freep(&buf_descriptor);
return AVERROR(ENOMEM);
}