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

Reply via email to