Re: [PATCH 3/3] media: uvcvideo: Implement dual stream quirk to fix loss of usb packets

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

 



On Fri, 8 Nov 2024 at 15:24, Isaac Scott <isaac.scott@xxxxxxxxxxxxxxxx> wrote:
>
> Some cameras, such as the Sonix Technology Co. 292A exhibit issues when
> running two parallel streams, causing USB packets to be dropped when an
> H.264 stream posts a keyframe while an MJPEG stream is running
> simultaneously. This occasionally causes the driver to erroneously
> output two consecutive JPEG images as a single frame.
>
> To fix this, we inspect the buffer, and trigger a new frame when we
> find an SOI, inverting the FID to make sure no frames are erroneously
> dropped.
>
> Signed-off-by: Isaac Scott <isaac.scott@xxxxxxxxxxxxxxxx>
> ---
>  drivers/media/usb/uvc/uvc_video.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>
> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> index 2fb9f2b59afc..f754109f5e96 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -1211,6 +1211,30 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
>                 return -EAGAIN;
>         }
>
> +       /*
> +        * Some cameras, such as the Sonix Technology Co. 292A exhibit issues
> +        * when running two parallel streams, causing USB packets to be dropped
> +        * when an H.264 stream posts a keyframe while an MJPEG stream is
> +        * running simultaneously. This occasionally causes the driver to
> +        * erroneously output two consecutive JPEG images as a single frame.
> +        *
> +        * Check the buffer for a new SOI on JPEG streams and complete the
> +        * preceding buffer using EAGAIN, and invert the FID to make sure the
> +        * erroneous frame is not dropped.
> +        */
> +       if ((stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF) &&
> +           (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
> +            stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
> +               const u8 *packet = data + header_len;

                  Don't you have to validate that data[header_len+1]
can be read?
> +
> +               if ((packet[0] == 0xff && packet[1] == 0xd8) && buf->bytesused != 0) {

nit: maybe it would be nice to make a define for 0xd8 and say what it is
> +                       buf->state = UVC_BUF_STATE_READY;
> +                       buf->error = 1;
> +                       stream->last_fid ^= UVC_STREAM_FID;
> +                       return -EAGAIN;
> +               }
> +       }
> +
>         stream->last_fid = fid;
>
>         return header_len;
> --
> 2.43.0
>
>


-- 
Ricardo Ribalda




[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