I did some more experiments with this webcam, and with a nasty hack got it working.
Basically the problem seems to be the frame interval requested. If I replace line 175 of uvc_v4l2.c [1] with probe->dwFrameInterval = 2500000; the camera works fine in mjpeg mode. The frame interval behaves oddly in this camera, in that if you set the frame interval above a certain threshold the camera seems to ignore it and send frames at whatever rate it feels like, but if you set it below a certain threshold the camera exhibits the bug I've described above, sending back corrupted frames and error codes. Most likely a firmware bug, as I can't imagine anyone would design a camera to function that way. I assume we wouldn't be inclined to patch the kernel to deal with this one camera's weird behaviour? [1] http://lxr.free-electrons.com/source/drivers/media/video/uvc/uvc_v4l2.c?v=2.6.28#L175 On 3 November 2011 10:20, Laurent Pinchart <laurent.pinch...@ideasonboard.com> wrote: > Hi, > > On Wednesday 07 September 2011 08:11:48 Alexey Fisher wrote: >> Am 06.09.2011 12:53, schrieb Michael Tandy: >> > [99317.553237] uvcvideo: uvc_v4l2_ioctl(VIDIOC_STREAMON) >> > [99317.554747] uvcvideo: uvc_v4l2_poll >> > [99333.472385] uvcvideo: Dropping payload (error bit set). >> > [99333.472389] uvcvideo: Frame complete (EOF found). >> > [99333.472391] uvcvideo: EOF in empty payload. >> > [99333.472429] uvcvideo: uvc_v4l2_poll >> > [99333.472438] uvcvideo: uvc_v4l2_ioctl(VIDIOC_DQBUF) >> > [99333.472447] uvcvideo: Dequeuing buffer 0 (3, 2676 bytes). >> >> hmm... the camera notify us about with error bit set, but current driver >> will just drop it and mark the buffer as faulty. > > As the data can't be trusted, the uvcvideo driver decides to drop the packet. > Alternatively the packet could be processed normally and the buffer market as > bad. It would then be up to the application to decide what to do with such > buffers (you will have to set the no_drop module parameter to 1, as the driver > drops faulty buffers by default). > > The following patch should implement that behaviour, in case you want to test > it. > > diff --git a/drivers/media/video/uvc/uvc_video.c > b/drivers/media/video/uvc/uvc_video.c > index ffd1158..baa5850 100644 > --- a/drivers/media/video/uvc/uvc_video.c > +++ b/drivers/media/video/uvc/uvc_video.c > @@ -419,13 +419,6 @@ static int uvc_video_decode_start(struct uvc_streaming > *stream, > if (len < 2 || data[0] < 2 || data[0] > len) > return -EINVAL; > > - /* Skip payloads marked with the error bit ("error frames"). */ > - if (data[1] & UVC_STREAM_ERR) { > - uvc_trace(UVC_TRACE_FRAME, "Dropping payload (error bit " > - "set).\n"); > - return -ENODATA; > - } > - > fid = data[1] & UVC_STREAM_FID; > > /* Increase the sequence number regardless of any buffer states, so > @@ -442,6 +435,13 @@ static int uvc_video_decode_start(struct uvc_streaming > *stream, > return -ENODATA; > } > > + /* Mark the buffer as bad if the error bit is set. */ > + if (data[1] & UVC_STREAM_ERR) { > + uvc_trace(UVC_TRACE_FRAME, "Marking buffer as bad (error bit " > + "set).\n"); > + buf->error = 1; > + } > + > /* Synchronize to the input stream by waiting for the FID bit to be > * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. > * stream->last_fid is initialized to -1, so the first isochronous > > >> According to uvc specification v1.1 in "4.3.1.7 Stream Error Code >> Control" we can/should check the error reason: >> ------------------------------------------------------------------- >> The host software should send a GET_CUR request to this control to >> determine the error when one of the following events occurs: >> - The Error bit in the video or still image payload header is set by the >> device >> .... >> For scenarios where the host is transmitting video data to the device, >> the host can not use the Error bit in the payload header to detect a >> device error. Therefore, in order to determine when a streaming error >> occurs, the host must rely on either a Control Change interrupt from the >> device or a bulk endpoint stall. >> -------------------------------------------------------------------- >> >> I'm suddenly not so good to implement ne things without testing and >> probing. May be Laurent can do this? Or i need access to the webcam. > > Retrieving the cause of the error requires sending a control request, which > can't be done in interrupt context. This could be implemented, but won't be > trivial, and I'm not sure it will give any useful information anyway. Knowing > whether the error comes from a buffer underrun, a buffer overrun or something > else won't let the driver fix the error. > > -- > Regards, > > Laurent Pinchart > _______________________________________________ Linux-uvc-devel mailing list Linux-uvc-devel@lists.berlios.de https://lists.berlios.de/mailman/listinfo/linux-uvc-devel