qv4l2: handle VIDIOC_DQBUF error code EAGAIN correctly
authorHans Verkuil <hverkuil@xs4all.nl>
Sun, 16 Jan 2011 09:53:01 +0000 (10:53 +0100)
committerHans Verkuil <hverkuil@xs4all.nl>
Sun, 16 Jan 2011 09:53:01 +0000 (10:53 +0100)
qv4l2 would stop streaming if it receives EAGAIN from VIDIOC_DQBUF
instead of continuing. The same error code from read() was handled
correctly.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
utils/qv4l2/qv4l2.cpp
utils/qv4l2/v4l2-api.cpp
utils/qv4l2/v4l2-api.h

index 1dfd8ba..232a318 100644 (file)
@@ -174,6 +174,7 @@ void ApplicationWindow::capFrame()
        unsigned i;
        int s = 0;
        int err = 0;
+       bool again;
 
        switch (m_capMethod) {
        case methodRead:
@@ -194,11 +195,13 @@ void ApplicationWindow::capFrame()
                break;
 
        case methodMmap:
-               if (!dqbuf_mmap_cap(buf)) {
+               if (!dqbuf_mmap_cap(buf, again)) {
                        error("dqbuf");
                        m_capStartAct->setChecked(false);
                        return;
                }
+               if (again)
+                       return;
 
                if (useWrapper())
                        memcpy(m_capImage->bits(), (unsigned char *)m_buffers[buf.index].start,
@@ -212,11 +215,13 @@ void ApplicationWindow::capFrame()
                break;
 
        case methodUser:
-               if (!dqbuf_user_cap(buf)) {
+               if (!dqbuf_user_cap(buf, again)) {
                        error("dqbuf");
                        m_capStartAct->setChecked(false);
                        return;
                }
+               if (again)
+                       return;
 
                for (i = 0; i < m_nbuffers; ++i)
                        if (buf.m.userptr == (unsigned long)m_buffers[i].start
index 6b91bc4..cd22ca7 100644 (file)
@@ -404,20 +404,28 @@ bool v4l2::reqbufs_mmap_cap(v4l2_requestbuffers &reqbuf, int count)
        return ioctl(VIDIOC_REQBUFS, &reqbuf) >= 0;
 }
 
-bool v4l2::dqbuf_mmap_cap(v4l2_buffer &buf)
+bool v4l2::dqbuf_mmap_cap(v4l2_buffer &buf, bool &again)
 {
+       int res;
+
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
-       return ioctl(VIDIOC_DQBUF, &buf) >= 0;
+       res = ioctl(VIDIOC_DQBUF, &buf);
+       again = res < 0 && errno == EAGAIN;
+       return res >= 0 || again;
 }
 
-bool v4l2::dqbuf_user_cap(v4l2_buffer &buf)
+bool v4l2::dqbuf_user_cap(v4l2_buffer &buf, bool &again)
 {
+       int res;
+
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_USERPTR;
-       return ioctl(VIDIOC_DQBUF, &buf) >= 0;
+       res = ioctl(VIDIOC_DQBUF, &buf);
+       again = res < 0 && errno == EAGAIN;
+       return res >= 0 || again;
 }
 
 bool v4l2::qbuf(v4l2_buffer &buf)
index 8b8c55a..e8bd813 100644 (file)
@@ -87,8 +87,8 @@ public:
 
        bool reqbufs_mmap_cap(v4l2_requestbuffers &reqbuf, int count = 0);
        bool reqbufs_user_cap(v4l2_requestbuffers &reqbuf, int count = 0);
-       bool dqbuf_mmap_cap(v4l2_buffer &buf);
-       bool dqbuf_user_cap(v4l2_buffer &buf);
+       bool dqbuf_mmap_cap(v4l2_buffer &buf, bool &again);
+       bool dqbuf_user_cap(v4l2_buffer &buf, bool &again);
        bool qbuf(v4l2_buffer &buf);
        bool qbuf_mmap_cap(int index);
        bool qbuf_user_cap(int index, void *ptr, int length);