aboutsummaryrefslogtreecommitdiffstats
path: root/libavdevice
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2012-01-05 12:17:45 +0100
committerLuca Barbato <lu_zero@gentoo.org>2012-01-10 05:04:22 +0100
commit0efd48dfd15273a5ac85f2fd42f19d419fafe90d (patch)
treef84b87dcd09a95f99f590ddc6599ecc90d520456 /libavdevice
parentb8c310cb0a071d998b90e9b166ed29062524de8b (diff)
downloadffmpeg-0efd48dfd15273a5ac85f2fd42f19d419fafe90d.tar.gz
v4l2: poll the file descriptor
Instead of busy waiting use poll();
Diffstat (limited to 'libavdevice')
-rw-r--r--libavdevice/v4l2.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 9c5da39e6a..2da98728c9 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -36,6 +36,7 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
+#include <poll.h>
#if HAVE_SYS_VIDEOIO_H
#include <sys/videoio.h>
#else
@@ -48,6 +49,7 @@
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avstring.h"
+#include "libavutil/mathematics.h"
static const int desired_video_buffers = 256;
@@ -61,6 +63,7 @@ struct video_data {
int frame_format; /* V4L2_PIX_FMT_* */
int width, height;
int frame_size;
+ int timeout;
int interlaced;
int top_field_first;
@@ -436,12 +439,20 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
struct video_data *s = ctx->priv_data;
struct v4l2_buffer buf;
struct buff_data *buf_descriptor;
+ struct pollfd p = { .fd = s->fd, .events = POLLIN };
int res;
memset(&buf, 0, sizeof(struct v4l2_buffer));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
+ res = poll(&p, 1, s->timeout);
+ if (res < 0)
+ return AVERROR(errno);
+
+ if (!(p.revents & (POLLIN | POLLERR | POLLHUP)))
+ return AVERROR(EAGAIN);
+
/* FIXME: Some special treatment might be needed in case of loss of signal... */
while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
if (res < 0) {
@@ -635,6 +646,10 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
s1->streams[0]->codec->time_base.den = tpf->denominator;
s1->streams[0]->codec->time_base.num = tpf->numerator;
+ s->timeout = 100 +
+ av_rescale_q(1, s1->streams[0]->codec->time_base,
+ (AVRational){1, 1000});
+
return 0;
}