lkml.org 
[lkml]   [2020]   [Apr]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH] media: uvcvideo: Ensure all probed info is returned to v4l2
    From
    bFrameIndex and bFormatIndex can be negotiated by the camera during
    probing, resulting in the camera choosing a different format than
    expected. v4l2 can already accommodate such changes, but the code was
    not updating the proper fields.

    Without such a change, v4l2 would potentially interpret the payload
    incorrectly, causing corrupted output. This was happening on the
    Elgato HD60 S+, which currently always renegotiates to format 1.

    As an aside, the Elgato firmware is buggy and should not be renegotating,
    but it is still a valid thing for the camera to do. Both macOS and Windows
    will properly probe and read uncorrupted images from this camera.

    With this change, both qv4l2 and chromium can now read uncorrupted video
    from the Elgato HD60 S+.

    Signed-off-by: Adam Goode <agoode@google.com>
    ---
    drivers/media/usb/uvc/uvc_v4l2.c | 26 ++++++++++++++++++++++++++
    1 file changed, 26 insertions(+)

    diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
    index 0335e69b70ab..7f14096cb44d 100644
    --- a/drivers/media/usb/uvc/uvc_v4l2.c
    +++ b/drivers/media/usb/uvc/uvc_v4l2.c
    @@ -247,11 +247,37 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
    if (ret < 0)
    goto done;

    + /* After the probe, update fmt with the values returned from
    + * negotiation with the device.
    + */
    + for (i = 0; i < stream->nformats; ++i) {
    + if (probe->bFormatIndex == stream->format[i].index) {
    + format = &stream->format[i];
    + break;
    + }
    + }
    + if (i == stream->nformats) {
    + uvc_trace(UVC_TRACE_FORMAT, "Unknown bFormatIndex %u.\n",
    + probe->bFormatIndex);
    + return -EINVAL;
    + }
    + for (i = 0; i < format->nframes; ++i) {
    + if (probe->bFrameIndex == format->frame[i].bFrameIndex) {
    + frame = &format->frame[i];
    + break;
    + }
    + }
    + if (i == format->nframes) {
    + uvc_trace(UVC_TRACE_FORMAT, "Unknown bFrameIndex %u.\n",
    + probe->bFrameIndex);
    + return -EINVAL;
    + }
    fmt->fmt.pix.width = frame->wWidth;
    fmt->fmt.pix.height = frame->wHeight;
    fmt->fmt.pix.field = V4L2_FIELD_NONE;
    fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
    fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
    + fmt->fmt.pix.pixelformat = format->fcc;
    fmt->fmt.pix.colorspace = format->colorspace;

    if (uvc_format != NULL)
    --
    2.25.3
    \
     
     \ /
      Last update: 2020-04-24 07:37    [W:4.136 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site