Re: [PATCH] media: uvcvideo: Add bandwidth_cap module param

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

 



Hi Andrew,

Thank you for the patch.

On Fri, Aug 21, 2020 at 11:00:38PM +0100, Andrew Murray wrote:
> Many UVC devices report larger values for dwMaxPayloadTransferSize than
> appear to be required. This results in less bandwidth available for
> other devices.
> 
> This problem is commonly observed when attempting to stream from multiple
> UVC cameras with the host controller returning -ENOSPC and sometimes a
> warning (XHCI controllers: "Not enough bandwidth for new device state.").
> 
> For uncompressed video, the UVC_QUIRK_FIX_BANDWIDTH works around this issue
> by overriding the device provided dwMaxPayloadTransferSize with a
> calculation of the actual bandwidth requirements from the requested frame
> size and rate. However for compressed video formats it's not practical to
> estimate the bandwidth required as the kernel doesn't have enough
> information.
> 
> Let's provide a pragmatic solution by allowing the user to impose an upper
> threshold to the amount of bandwidth each UVC device can reserve. If the
> parameter isn't used then no threshold is imposed.

Hmmmm... This is a bit annoying as it will apply equally to all formats
and all cameras. It may solve a real issue, but it's quite a bit of a
hack. I'm also concerned that users will be confused regarding how to
use this parameter properly, as there's no documentation that explains
its usage, and how to pick a proper value. Is there any way we could do
better ?

> Signed-off-by: Andrew Murray <amurray@xxxxxxxxxxxxxxxxxxxx>
> ---
>  drivers/media/usb/uvc/uvc_driver.c | 3 +++
>  drivers/media/usb/uvc/uvc_video.c  | 8 ++++++++
>  drivers/media/usb/uvc/uvcvideo.h   | 1 +
>  3 files changed, 12 insertions(+)
> 
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> index 431d86e1c94b..d5ecac7fc264 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -33,6 +33,7 @@ unsigned int uvc_no_drop_param;
>  static unsigned int uvc_quirks_param = -1;
>  unsigned int uvc_trace_param;
>  unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
> +unsigned int uvc_bandwidth_cap_param;
>  
>  /* ------------------------------------------------------------------------
>   * Video formats
> @@ -2389,6 +2390,8 @@ module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
>  MODULE_PARM_DESC(trace, "Trace level bitmask");
>  module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
>  MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
> +module_param_named(bandwidth_cap, uvc_bandwidth_cap_param, uint, S_IRUGO|S_IWUSR);
> +MODULE_PARM_DESC(bandwidth_cap, "Maximum bandwidth per device");
>  
>  /* ------------------------------------------------------------------------
>   * Driver initialization and cleanup
> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> index a65d5353a441..74a0dc0614cf 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -196,6 +196,14 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
>  
>  		ctrl->dwMaxPayloadTransferSize = bandwidth;
>  	}
> +
> +	if (uvc_bandwidth_cap_param &&
> +	    ctrl->dwMaxPayloadTransferSize > uvc_bandwidth_cap_param) {
> +		uvc_trace(UVC_TRACE_VIDEO,
> +			"Bandwidth capped from %u to %u B/frame.\n",
> +			ctrl->dwMaxPayloadTransferSize, uvc_bandwidth_cap_param);
> +		ctrl->dwMaxPayloadTransferSize = uvc_bandwidth_cap_param;
> +	}
>  }
>  
>  static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 6ab972c643e3..c7d9220c9a7a 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -718,6 +718,7 @@ extern unsigned int uvc_no_drop_param;
>  extern unsigned int uvc_trace_param;
>  extern unsigned int uvc_timeout_param;
>  extern unsigned int uvc_hw_timestamps_param;
> +extern unsigned int uvc_bandwidth_cap_param;
>  
>  #define uvc_trace(flag, msg...) \
>  	do { \

-- 
Regards,

Laurent Pinchart



[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