Re: uvideo: kill a quirk, fix frame sizes

2011-03-29 Thread Michael Knudsen
On Sun, Mar 27, 2011 at 07:26:55PM +, Jacob Meuser wrote:
> USB_PRODUCT_MICROSOFT_LIFECAM: "Microsoft LifeCam"

I think I'm the one who added this entry, and with your diff my camera
still works:

uvideo0 at uhub0 port 5 configuration 1 interface 0 "Microsoft Microsoft
LifeCam" rev 2.00/1.01 addr 2

Going to check if this makes my camera work properly on my soekris.  I
gave up using it there because I got partial frames or frames that
seemed to be unsynchronized with the data stream (i.e. the frame starting
halfway down the actual image).

-m.

-- 
The Librarian gave him the kind of look other people would reserve for
people who said things like `What's so bad about genocide?'
-- (Terry Pratchett, Guards! Guards!)



Re: uvideo: kill a quirk, fix frame sizes

2011-03-28 Thread David Coppa
On Sun, Mar 27, 2011 at 9:26 PM, Jacob Meuser 
wrote:
> dcoppa@ noticed that his camera still didn't work with ffmpeg after
> the latest uvideo changes.  the problem was that the device reported
> a ridiculously large maximum frame size, and then malloc(9) failed
> because there wasn't enough free memory to allocate the frame buffer.
>
> this is similar to a problem with other cameras, and is why uvideo(4)
> has the UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE quirk.

For the archives, mine is a:

uvideo0 at uhub0 port 5 configuration 1 interface 0 "Acer BisonCam, NB
Pro" rev 2.00/0.02 addr 2

And it's the integrated webcam of my MSI Wind U100 netbook...

Cheers!
David



uvideo: kill a quirk, fix frame sizes

2011-03-27 Thread Jacob Meuser
dcoppa@ noticed that his camera still didn't work with ffmpeg after
the latest uvideo changes.  the problem was that the device reported
a ridiculously large maximum frame size, and then malloc(9) failed
because there wasn't enough free memory to allocate the frame buffer.

this is similar to a problem with other cameras, and is why uvideo(4)
has the UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE quirk.

however, these problems and the quirk only affect/fix uncompressed
video formats.  uncompressed video formats have a fixed bit-depth
per pixel.  that means that if you know how many pixels are in
a frame, you can figure out how many bytes are needed to store the
frame.  we always know the frame size and bit depth, so we can
always figure out the needed buffer size for uncompressed frames.

so, that's what the following diff does.  it calculates the frame
buffer size neeed for uncompressed frames and ignores values given
by the device.

I also noticed that one of my cameras will produce a "short" frame
almost every time capture is started, and occasionally during
capture.  this breaks ffmpeg.  also, the v4l2 spec says that
the read() method should never give out partial frames.  the spec
isn't so clear about mmap'd frames, but ffmpeg doesn't like them,
and I imagine other applications won't like them either.  so I
also extended the check that skips over-sized frames to skip
under-sized frames for uncompressed formats.

and finally, I moved the check of the data returned from a probe
request from the function that does the probe request to the
function that does the parameter negotiation.  also added a check
that we actually got the parameters we wanted.  without that check,
the driver could think one format is being used, but the device
is using a different one ...

please test with all uvideo(4) devices, especially these that were
using a quirk to fix the frame size:

USB_PRODUCT_CHENSOURCE_CM12402: "Eagle IR Cam"
USB_PRODUCT_MICRODIA_CAM_1: "CAM_1" (Sonix web cam)
USB_PRODUCT_MICROSOFT_LIFECAM: "Microsoft LifeCam"

-- 
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: uvideo.c
===
RCS file: /cvs/src/sys/dev/usb/uvideo.c,v
retrieving revision 1.158
diff -u -p uvideo.c
--- uvideo.c26 Mar 2011 19:50:52 -  1.158
+++ uvideo.c27 Mar 2011 19:04:00 -
@@ -249,7 +249,6 @@ struct video_hw_if uvideo_hw_if = {
 #define UVIDEO_FLAG_ISIGHT_STREAM_HEADER   0x1
 #define UVIDEO_FLAG_REATTACH   0x2
 #define UVIDEO_FLAG_VENDOR_CLASS   0x4
-#define UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE   0x8
 struct uvideo_devs {
struct usb_devno uv_dev;
char*ucode_name;
@@ -325,27 +324,6 @@ struct uvideo_devs {
NULL,
UVIDEO_FLAG_VENDOR_CLASS
},
-   {
-   /* Needs to fix dwMaxVideoFrameSize */
-   { USB_VENDOR_CHENSOURCE, USB_PRODUCT_CHENSOURCE_CM12402 },
-   NULL,
-   NULL,
-   UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE
-   },
-   {
-   /* Needs to fix dwMaxVideoFrameSize */
-   { USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_CAM_1 },
-   NULL,
-   NULL,
-   UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE
-   },
-   {
-   /* Needs to fix dwMaxVideoFrameSize */
-   { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_LIFECAM },
-   NULL,
-   NULL,
-   UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE
-   },
 };
 #define uvideo_lookup(v, p) \
((struct uvideo_devs *)usb_lookup(uvideo_devs, v, p))
@@ -1077,15 +1055,20 @@ uvideo_vs_parse_desc_frame_sub(struct uvideo_softc *sc
sc->sc_fmtgrp[fmtidx].frame_cur = fd;
 
/*
-* On some broken device, dwMaxVideoFrameBufferSize is not correct.
-* So fix it by frame width/height (XXX YUV2 format only).
+* On some devices, dwMaxVideoFrameBufferSize is not correct.
+* Version 1.1 of the UVC spec says this field is deprecated.
+* For uncompressed pixel formats, the frame buffer size can
+* be determined by multiplying width, height, and bytes per pixel.
+* Uncompressed formats have a fixed number of bytes per pixel.
+* Bytes per pixel can vary with compressed formats.
 */
-   if (sc->sc_quirk &&
-   sc->sc_quirk->flags & UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE &&
-   sc->sc_fmtgrp[fmtidx].pixelformat == V4L2_PIX_FMT_YUYV) {
-   fbuf_size = UGETW(fd->wWidth) * UGETW(fd->wHeight) * 4;
-   DPRINTF(1, "wWidth = %d, wHeight = %d\n",
-   UGETW(fd->wWidth), UGETW(fd->wHeight));
+   if (desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_UNCOMPRESSED) {
+   fbuf_size = UGETW(fd->wWidth) * UGETW(fd->wHeight) *
+   sc->sc_fmtgrp[fmtidx].format->u.uc.bBitsPerPixel / NBBY;
+   DPRINTF(10, "%s: %s: frame b