[libav-commits] v4l2: poll the file descriptor

Luca Barbato git at libav.org
Tue Jan 10 05:04:11 CET 2012


Module: libav
Branch: master
Commit: 0efd48dfd15273a5ac85f2fd42f19d419fafe90d

Author:    Luca Barbato <lu_zero at gentoo.org>
Committer: Luca Barbato <lu_zero at gentoo.org>
Date:      Thu Jan  5 12:17:45 2012 +0100

v4l2: poll the file descriptor

Instead of busy waiting use poll();

---

 libavdevice/v4l2.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 9c5da39..2da9872 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;
 }
 



More information about the libav-commits mailing list