From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
To: Linux Media Mailing List <linux-media@vger.kernel.org>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: linuxarm@huawei.com, mauro.chehab@huawei.com,
Mauro Carvalho Chehab <mchehab+huawei@kernel.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH] media: uvc: limit max bandwidth for HDMI capture
Date: Mon, 1 Feb 2021 20:08:59 +0100 [thread overview]
Message-ID: <b791d5874c83663505cbd4f74907ac38d00bb727.1612206534.git.mchehab+huawei@kernel.org> (raw)
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. For such resolution, the maximum interval
is, instead 333333 (30 fps).
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@kernel.org>
---
drivers/media/usb/uvc/uvc_driver.c | 15 +++++++++++++++
drivers/media/usb/uvc/uvc_video.c | 26 +++++++++++++++++++++++---
drivers/media/usb/uvc/uvcvideo.h | 2 ++
3 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 1abc122a0977..c83a329f6527 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2339,6 +2339,7 @@ static int uvc_probe(struct usb_interface *intf,
dev->info = info ? info : &uvc_quirk_none;
dev->quirks = uvc_quirks_param == -1
? dev->info->quirks : uvc_quirks_param;
+ dev->max_bandwidth = dev->info->max_bandwidth;
if (id->idVendor && id->idProduct)
uvc_dbg(dev, PROBE, "Probing known UVC device %s (%04x:%04x)\n",
@@ -2615,6 +2616,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,
};
@@ -2830,6 +2836,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 f2f565281e63..4afc1fbe0801 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -162,9 +162,29 @@ 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 */
+
+ if (format->flags & UVC_FMT_FLAG_COMPRESSED &&
+ stream->dev->max_bandwidth && frame->bFrameIntervalType) {
+ u32 bandwidth;
+
+ for (i = 0; i < frame->bFrameIntervalType - 1; ++i) {
+ bandwidth = frame->wWidth * frame->wHeight;
+ bandwidth *= 10000000 / frame->dwFrameInterval[i];
+
+ if (bandwidth <= stream->dev->max_bandwidth)
+ break;
+ }
+
+ ctrl->dwFrameInterval = frame->dwFrameInterval[i];
+ return;
+ }
+
+ if (stream->intf->num_altsetting > 1) {
u32 interval;
u32 bandwidth;
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 97df5ecd66c9..b44e0cd4c826 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -658,6 +658,7 @@ static inline u32 uvc_urb_index(const struct uvc_urb *uvc_urb)
struct uvc_device_info {
u32 quirks;
+ u32 max_bandwidth;
u32 meta_format;
u16 uvc_version;
};
@@ -667,6 +668,7 @@ struct uvc_device {
struct usb_interface *intf;
unsigned long warnings;
u32 quirks;
+ u32 max_bandwidth;
int intfnum;
char name[32];
--
2.29.2
next reply other threads:[~2021-02-01 19:10 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-01 19:08 Mauro Carvalho Chehab [this message]
2021-06-21 18:22 ` [PATCH] media: uvc: limit max bandwidth for HDMI capture Laurent Pinchart
2021-06-22 8:29 ` Mauro Carvalho Chehab
2021-06-22 8:50 ` Dave Stevenson
2021-06-22 8:59 ` Laurent Pinchart
2021-06-22 9:09 ` Mauro Carvalho Chehab
2021-06-25 19:18 ` Nicolas Dufresne
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b791d5874c83663505cbd4f74907ac38d00bb727.1612206534.git.mchehab+huawei@kernel.org \
--to=mchehab+huawei@kernel.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linuxarm@huawei.com \
--cc=mauro.chehab@huawei.com \
--cc=mchehab@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.