[PATCH for v4l-utils] qv4l2: fix UVC support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hans,

Can you apply this to v4l-utils?

Thanks!

	Hans

>From 977eb253a3e7a5257a2051da240314e2dac385bf Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xxxxxxxxx>
Date: Sat, 13 Mar 2010 23:19:48 +0100
Subject: [PATCH] qv4l2: fix UVC support

The workaround for drivers using videobuf broke the UVC support.
Fix this.

Signed-off-by: Hans Verkuil <hverkuil@xxxxxxxxx>
---
 utils/qv4l2-qt4/general-tab.cpp |   18 +++++++++++++++---
 utils/qv4l2-qt4/qv4l2.cpp       |    4 +++-
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/utils/qv4l2-qt4/general-tab.cpp b/utils/qv4l2-qt4/general-tab.cpp
index 50a3edc..706b15d 100644
--- a/utils/qv4l2-qt4/general-tab.cpp
+++ b/utils/qv4l2-qt4/general-tab.cpp
@@ -198,11 +198,23 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
 	if (m_querycap.capabilities & V4L2_CAP_STREAMING) {
 		v4l2_requestbuffers reqbuf;
 
-		if (reqbufs_user_cap(reqbuf, 1))
+		// Yuck. The videobuf framework does not accept a count of 0.
+		// This is out-of-spec, but it means that the only way to test which
+		// method is supported is to give it a non-zero count. But non-videobuf
+		// drivers like uvc do not allow e.g. S_FMT calls after a REQBUFS call
+		// with non-zero counts unless there is a REQBUFS call with count == 0
+		// in between. This is actual proper behavior, although somewhat
+		// unexpected. So the only way at the moment to do this that works
+		// everywhere is to call REQBUFS with a count of 1, and then again with
+	       	// a count of 0.
+		if (reqbufs_user_cap(reqbuf, 1)) {
 			m_capMethods->addItem("User pointer I/O", QVariant(methodUser));
-
-		if (reqbufs_mmap_cap(reqbuf, 1))
+			reqbufs_user_cap(reqbuf, 0);
+		}
+		if (reqbufs_mmap_cap(reqbuf, 1)) {
 			m_capMethods->addItem("Memory mapped I/O", QVariant(methodMmap));
+			reqbufs_mmap_cap(reqbuf, 0);
+		}
 	}
 	if (m_querycap.capabilities & V4L2_CAP_READWRITE) {
 		m_capMethods->addItem("read()", QVariant(methodRead));
diff --git a/utils/qv4l2-qt4/qv4l2.cpp b/utils/qv4l2-qt4/qv4l2.cpp
index 96cb4d7..63881be 100644
--- a/utils/qv4l2-qt4/qv4l2.cpp
+++ b/utils/qv4l2-qt4/qv4l2.cpp
@@ -352,7 +352,7 @@ void ApplicationWindow::stopCapture()
 			if (-1 == munmap(m_buffers[i].start, m_buffers[i].length))
 				perror("munmap");
 		// Free all buffers.
-		reqbufs_mmap_out(reqbufs, 0);
+		reqbufs_mmap_cap(reqbufs, 0);
 		break;
 
 	case methodUser:
@@ -360,6 +360,8 @@ void ApplicationWindow::stopCapture()
 			perror("VIDIOC_STREAMOFF");
 		for (i = 0; i < m_nbuffers; ++i)
 			free(m_buffers[i].start);
+		// Free all buffers.
+		reqbufs_user_cap(reqbufs, 0);
 		break;
 	}
 	free(m_buffers);
-- 
1.6.4.2


-- 
Hans Verkuil - video4linux developer - sponsored by TANDBERG
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux