Re: nasty bug at qv4l2

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

 



On Tuesday, December 28, 2010 23:53:08 Hans de Goede wrote:
> Hi,
> 
> On 12/25/2010 03:09 PM, Mauro Carvalho Chehab wrote:
> > Em 25-12-2010 07:14, Mauro Carvalho Chehab escreveu:
> >> Em 24-12-2010 16:54, Hans Verkuil escreveu:
> >>> On Friday, December 24, 2010 15:41:10 Hans de Goede wrote:
> >>>> Hi,
> >>>>
> >>>> On 12/24/2010 03:20 PM, Hans Verkuil wrote:
> >>>>> On Friday, December 24, 2010 15:19:26 Hans de Goede wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> On 12/22/2010 12:30 PM, Mauro Carvalho Chehab wrote:
> >>>>>>> Hans V/Hans G,
> >>>>>>>
> >>>>>>> There's a nasty bug at qv4l2 or at libv4l: it is not properly updating
> >>>>>>> all info, if you change the video device. On my tests with uvcvideo (video0)
> >>>>>>> and a gspca camera (pac7302, video1), it was showing the supported formats
> >>>>>>> for the uvcvideo camera when I changed from video0 to video1.
> >>>>>>>
> >>>>>>> The net result is that the image were handled with the wrong decoder
> >>>>>>> (instead of using fourcc V4L2_PIX_FMT_PJPG, it were using BGR3), producing
> >>>>>>> a wrong decoding.
> >>>>>>>
> >>>>>>> Could you please take a look on it?
> >
> > <snip>
> >
> >>> I wonder if Mauro got confused by the different behavior as well.
> >>
> >> I think I used the libv4l way. I'll re-try on both modes. This way, we'll know for sure if
> >> the issue is at libv4l or not.
> >
> > Double checked: when opening in raw mode, everything works fine. However, when
> > opening with "libv4l" mode, it doesn't update the supported formats.
> >
> 
> I've spend some time looking at this, with interesting results. There is a bug
> in libv4lconvert, which gets exposed when using qv4l2 with a pac7311 camera
> (no need to first open another type of device).
> 
> As suspected, qv4l2 tries to call into libv4lconvert directly even when going
> through libv4l. So what happens is:
> 1) qv4l2 sees rgb24 as a format supported by the device and selects it
>     (because of libv4l2 being used)
> 2) qv4l2 still tries to use libv4lconvert directly and ends up setting up
>     conversion from rgb24 to rgb24 (the conversion from pjpg to rgb24 is
>     already done transparently by libv4l)
> 3) libv4lconvert (or rather libv4lcontrol which is part of libv4lconvert)
>     enables software whitebalancing by default on pac7311 cameras
> 
> libv4lconvert has special code to detect src_fmt == dest_fmt and just do
> a memcpy, however this code does not trigger because of 3 (as when doing
> processing just a memcpy is not what we want). However libv4lconvert
> API is based on providing a src and destination buffer, and in this case
> libv4lconvert_convert ends up skipping all steps (conversion, cropping,
> flipping and rotating) except for processing, and the processing code
> works by modifying the buffer it is passed rather then using a separate
> input output buffer, so since none of the other separate input output
> buffer needing steps where done, the data never gets copied to the
> destination buffer!
> 
> I've just pushed a patch to v4l-utils git fixing this bug.
> 
> Note that qv4l2 should still be fixed to not call libv4lconvert directly
> when not in raw mode (instead it should just do a s_fmt rgb24, which
> libv4l will always offer for all supported devices), as the way things
> are now libv4lconvert_convert ends up getting called twice. Which will
> lead to various software processing steps being done twice, which
> is not a problem for whitebalance, but it makes software vflip and
> hflip no-ops. And for cameras which need 90 degrees rotation (pac7302)
> it will completely screw up the image.
> 
> In general an app can either use libv4lconvert directly, or call
> libv4l2 functions and let it deal with handling conversion transparently
> using both at the same time is not supported.

Makes a lot of sense.

I've made a patch for qv4l2 that should fix this. It's included below, but
before I push this I'd like to have some test feedback. I could only test with
ivtv and not with any webcams since I don't have access to them at the moment.

So let me know if this fixes qv4l2 and if so, I'll push the patch.

Regards,

	Hans

>From 9e66659528c5aec7ca7bfd1ec881fe4a921e3c7c Mon Sep 17 00:00:00 2001
Message-Id: <9e66659528c5aec7ca7bfd1ec881fe4a921e3c7c.1293647806.git.hverkuil@xxxxxxxxx>
From: Hans Verkuil <hverkuil@xxxxxxxxx>
Date: Wed, 29 Dec 2010 19:33:31 +0100
Subject: [PATCH] qv4l2: don't use v4lconvert directly when using libv4l.
To: linux-media@xxxxxxxxxxxxxxx

Only in 'raw' mode should v4lconvert be used, otherwise it will be
called twice causing all software image processing to be done twice
as well.

Signed-off-by: Hans Verkuil <hverkuil@xxxxxxxxx>
---
 utils/qv4l2/qv4l2.cpp |   34 ++++++++++++++++++++++++++--------
 1 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 5646bcf..a085f86 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -178,7 +178,10 @@ void ApplicationWindow::capFrame()
 	switch (m_capMethod) {
 	case methodRead:
 		s = read(m_frameData, m_capSrcFormat.fmt.pix.sizeimage);
-		err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
+		if (useWrapper())
+			memcpy(m_capImage->bits(), m_frameData, m_capSrcFormat.fmt.pix.sizeimage);
+		else
+			err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
 				m_frameData, m_capSrcFormat.fmt.pix.sizeimage,
 				m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage);
 		break;
@@ -190,7 +193,11 @@ void ApplicationWindow::capFrame()
 			return;
 		}
 
-		err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
+		if (useWrapper())
+			memcpy(m_capImage->bits(), (unsigned char *)m_buffers[buf.index].start,
+					m_capSrcFormat.fmt.pix.sizeimage);
+		else
+			err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
 				(unsigned char *)m_buffers[buf.index].start, buf.bytesused,
 				m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage);
 
@@ -209,7 +216,11 @@ void ApplicationWindow::capFrame()
 					&& buf.length == m_buffers[i].length)
 				break;
 
-		err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
+		if (useWrapper())
+			memcpy(m_capImage->bits(), (unsigned char *)buf.m.userptr,
+					m_capSrcFormat.fmt.pix.sizeimage);
+		else
+			err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
 				(unsigned char *)buf.m.userptr, buf.bytesused,
 				m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage);
 
@@ -410,6 +421,11 @@ void ApplicationWindow::capStart(bool start)
 	}
 	m_capMethod = m_genTab->capMethod();
 	g_fmt_cap(m_capSrcFormat);
+	if (useWrapper()) {
+		m_capSrcFormat.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
+		s_fmt(m_capSrcFormat);
+		g_fmt_cap(m_capSrcFormat);
+	}
 	m_frameData = new unsigned char[m_capSrcFormat.fmt.pix.sizeimage];
 	m_capDestFormat = m_capSrcFormat;
 	m_capDestFormat.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
@@ -421,11 +437,13 @@ void ApplicationWindow::capStart(bool start)
 			break;
 		}
 	}
-	v4lconvert_try_format(m_convertData, &m_capDestFormat, &m_capSrcFormat);
-	// v4lconvert_try_format sometimes modifies the source format if it thinks
-	// that there is a better format available. Restore our selected source
-	// format since we do not want that happening.
-	g_fmt_cap(m_capSrcFormat);
+	if (!useWrapper()) {
+		v4lconvert_try_format(m_convertData, &m_capDestFormat, &m_capSrcFormat);
+		// v4lconvert_try_format sometimes modifies the source format if it thinks
+		// that there is a better format available. Restore our selected source
+		// format since we do not want that happening.
+		g_fmt_cap(m_capSrcFormat);
+	}
 	m_capture->setMinimumSize(m_capDestFormat.fmt.pix.width, m_capDestFormat.fmt.pix.height);
 	m_capImage = new QImage(m_capDestFormat.fmt.pix.width, m_capDestFormat.fmt.pix.height, dstFmt);
 	m_capImage->fill(0);
-- 
1.6.4.2



-- 
Hans Verkuil - video4linux developer - sponsored by Cisco
--
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