LINUX&UVC相机打开时的带宽选择
2024-03-26
244
0
UVC规范明确指出,传输UVC图像数据的端点既可以是同步传输,也可以是批量传输。
批量传输
对于批量传输,其实根本不存在带宽选择的问题的。只要是批量传输,端点都是可以使能工作的,但是数据传输的效能是根据USB总线上的带宽利用率而决定的。因为USB批量占用的是周期性传输和控制传输剩余的带宽。
- USB带宽分配管理规则 为什么USB设备的最高带宽只能到达80% https://www.usbzh.com/article/detail-879.html
在UVC视频流输入头描述符中bEndpointAddress字段指定了数据传输的端点,详见:https://www.usbzh.com/article/detail-98.html
所以对于批量传输的UVC相机,只需要在接口描述符下中查找端点地址为bEndpointAddress的端点描述符,然后初始化该端点即可:
else
{
/* Bulk endpoint, proceed to URB initialization. */
ep = uvc_find_endpoint(&intf->altsetting[0],stream->header.bEndpointAddress);
if (ep == NULL)
return -EIO;
ret = uvc_init_video_bulk(stream, ep, gfp_flags);
}
LINUX&UVC驱动中打开视频数据传输端点时,使用的是uvc_video_start_transfer函数。
同步传输
同步传输涉及UVC协商时的dwMaxPayloadTransferSize。该字段的计算及含义可详见:
LINUX&UVC驱动会校验UVC视频流输入头描述符中bEndpointAddress地址的带宽是否满足dwMaxPayloadTransferSize的带宽需求。如果不满足,会提示带宽不足。
/* Isochronous endpoint, select the alternate setting. */
bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
for (i = 0; i < intf->num_altsetting; ++i) {
struct usb_host_interface *alts;
unsigned int psize;
alts = &intf->altsetting[i];
//查找指点的端点描述符
ep = uvc_find_endpoint(alts,stream->header.bEndpointAddress);
if (ep == NULL)
continue;
/* Check if the bandwidth is high enough. */
//检查带宽是否满足
psize = uvc_endpoint_max_bpi(stream->dev->udev, ep);
if (psize >= bandwidth && psize <= best_psize) {
altsetting = alts->desc.bAlternateSetting;
best_psize = psize;
best_ep = ep;
}
}
//如果不满足,提示带宽不足
if (best_ep == NULL) {
uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting "
"for requested bandwidth.\n");
return -EIO;
}
结论
- 同步传传存在因带宽不足而打开相机失败的原因,而批量传输就不存在打开失败。
- 同步传输如果正确打开了,就会有数据。而批量传输不见得一定有数据传输。