Re: [PATCH v2 2/2] media: uvc: limit max bandwidth for HDMI capture

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

 



Hi Hans

On Mon, 6 Jan 2025 at 16:49, Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
>
> Hi,
>
> On 6-Jan-25 3:48 PM, Ricardo Ribalda wrote:
> > On Mon, 6 Jan 2025 at 15:09, Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
> >>
> >> From: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
> >>
> >> This device:
> >>         534d:2109 MacroSilicon
> >>
> >> Announces that it supports several frame intervals for
> >> their resolutions for MJPEG compression:
> >>
> >>         VideoStreaming Interface Descriptor:
> >>         bLength                            46
> >>         bDescriptorType                    36
> >>         bDescriptorSubtype                  7 (FRAME_MJPEG)
> >>         bFrameIndex                         1
> >>         bmCapabilities                   0x00
> >>           Still image unsupported
> >>         wWidth                           1920
> >>         wHeight                          1080
> >>         dwMinBitRate                   768000
> >>         dwMaxBitRate                196608000
> >>         dwMaxVideoFrameBufferSize     4147200
> >>         dwDefaultFrameInterval         166666
> >>         bFrameIntervalType                  5
> >>         dwFrameInterval( 0)            166666
> >>         dwFrameInterval( 1)            333333
> >>         dwFrameInterval( 2)            400000
> >>         dwFrameInterval( 3)            500000
> >>         dwFrameInterval( 4)           1000000
> >>
> >> However, the highest frame interval (166666), which means 60 fps
> >> is not supported. If set to it, URB packages will be dropped,
> >> causing JPEG decoding errors and part of the video frames will
> >> be missed.
> >>
> >> Also, as specified at the device's documentation, for such
> >> resolution, the maximum interval is 30 fps (interval == 333333).
> >>
> >> The last format that supports such frame interval is 1280x720.
> >>
> >> Add a quirk to estimate a raw bandwidth, by doing:
> >>         width * height * framerate
> >> E. g.:
> >>         1920 * 1080 * 30 = 62208000
> >>
> >> if the bandwidth is greater than such threshold, get
> >> the next value from the dwFrameInterval.
> >>
> >> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
> >> Link: https://lore.kernel.org/r/bca0634691cea503c2c5df62b98ba66f0c85bf85.1624350539.git.mchehab+huawei@xxxxxxxxxx
> >> [hdegoede@xxxxxxxxxx add "pixels per second" comment, use UVC_FIVAL_DENOM]
> >> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
> >> ---
> >>  drivers/media/usb/uvc/uvc_driver.c | 14 ++++++++++++++
> >>  drivers/media/usb/uvc/uvc_video.c  | 29 ++++++++++++++++++++++++++---
> >>  drivers/media/usb/uvc/uvcvideo.h   |  1 +
> >>  3 files changed, 41 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> >> index f754640fddf5..6d001d4f0902 100644
> >> --- a/drivers/media/usb/uvc/uvc_driver.c
> >> +++ b/drivers/media/usb/uvc/uvc_driver.c
> >> @@ -2491,6 +2491,11 @@ static const struct uvc_device_info uvc_quirk_fix_bandwidth = {
> >>         .quirks = UVC_QUIRK_FIX_BANDWIDTH,
> >>  };
> >>
> >> +static const struct uvc_device_info uvc_quirk_fix_bw_622 = {
> >> +       .quirks = UVC_QUIRK_FIX_BANDWIDTH,
> >> +       .max_bandwidth = 62208000,
> >> +};
> >> +
> >>  static const struct uvc_device_info uvc_quirk_probe_def = {
> >>         .quirks = UVC_QUIRK_PROBE_DEF,
> >>  };
> >> @@ -2794,6 +2799,15 @@ static const struct usb_device_id uvc_ids[] = {
> >>           .bInterfaceSubClass   = 1,
> >>           .bInterfaceProtocol   = 0,
> >>           .driver_info          = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
> >> +       /* MacroSilicon HDMI capture */
> >> +       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
> >> +                               | USB_DEVICE_ID_MATCH_INT_INFO,
> >> +         .idVendor             = 0x534d,
> >> +         .idProduct            = 0x2109,
> >> +         .bInterfaceClass      = USB_CLASS_VIDEO,
> >> +         .bInterfaceSubClass   = 1,
> >> +         .bInterfaceProtocol   = 0,
> >> +         .driver_info          = (kernel_ulong_t)&uvc_quirk_fix_bw_622 },
> >>         /* Genesys Logic USB 2.0 PC Camera */
> >>         { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
> >>                                 | USB_DEVICE_ID_MATCH_INT_INFO,
> >> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> >> index 41cb1b45fa23..af5233ab667e 100644
> >> --- a/drivers/media/usb/uvc/uvc_video.c
> >> +++ b/drivers/media/usb/uvc/uvc_video.c
> >> @@ -225,9 +225,32 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
> >>         if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000)
> >>                 ctrl->dwMaxPayloadTransferSize &= ~0xffff0000;
> >>
> >> -       if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
> >> -           stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
> >> -           stream->intf->num_altsetting > 1) {
> >> +       if (!(stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH))
> >> +               return;
> >> +
> >> +       /* Handle UVC_QUIRK_FIX_BANDWIDTH */
> >> +
> >
> > Shouldn't this quirk be better implemented in uvc_try_frame_interval() ?
>
> This is the place where the other bandwidth checks / UVC_QUIRK_FIX_BANDWIDTH
> handling is done, so I guess it makes sense to keep this here.

If I understood it correctly the quirk skips one of the intervals.
If we add the quirk to uvc_ioctl_enum_frameintervals and
uvc_try_frame_interval(), the user will not enumerate frame intervals
that will not work.
IMO that is better than accepting an interval and then changing it to
something else.


[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