From ede43adf454bef92d7445fba0abb7269c39f2656 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 16 Jan 2011 10:53:01 +0100 Subject: [PATCH] qv4l2: handle VIDIOC_DQBUF error code EAGAIN correctly 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 --- utils/qv4l2/qv4l2.cpp | 9 +++++++-- utils/qv4l2/v4l2-api.cpp | 16 ++++++++++++---- utils/qv4l2/v4l2-api.h | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp index 1dfd8ba..232a318 100644 --- a/utils/qv4l2/qv4l2.cpp +++ b/utils/qv4l2/qv4l2.cpp @@ -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 diff --git a/utils/qv4l2/v4l2-api.cpp b/utils/qv4l2/v4l2-api.cpp index 6b91bc4..cd22ca7 100644 --- a/utils/qv4l2/v4l2-api.cpp +++ b/utils/qv4l2/v4l2-api.cpp @@ -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) diff --git a/utils/qv4l2/v4l2-api.h b/utils/qv4l2/v4l2-api.h index 8b8c55a..e8bd813 100644 --- a/utils/qv4l2/v4l2-api.h +++ b/utils/qv4l2/v4l2-api.h @@ -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); -- 2.7.4