UVC的版本区别之处理单元描述符
UVC规范自发布到现在,已经有UVC1.0,UVC1.1和UVC1.5三个版本了。
在Windows环境下,支持的最广泛的是UVC1.0,从Win7开始支持UVC1.1,从Win8开始支持UVC1.5.
我们常用的UVC摄像头一般为了支持更加广泛的操作系统,一般情况下UVC的固件是UVC1.0,但随着固件的升级,不过避免的需要使用UVC1.1规范,甚至最新的UVC1.5规范版本。
关于UVC的版本区别,一般最典型的是从视频流接口的特定类请求的长度来判断。当特定类的请求长度为26字节时,是UVC1.0版本;当特定类请求的长度是34字节进,是UVC1.1版本;当特定类请求的长度是48字节时,是UVC1.5版本。
当然在UVC的类特定视频控制接口头描述符的bcdUVC字段以BCD的形式标识了当前UVC的版本,如UVC1.0是0x100,UVC1.1是0x11,UVC1.5是0x150。
前面说了UVC的版本区别,其实不光反映在我们耳熟能详的一些细节,对于一些常用的描述符也是有很细微的差别的。这里的处理单元描述符就是其中之一。
本人在Windows驱动中虚拟UVC摄像头时,就因处理单元的描述符的版本设置不正确,导致UVC摄像头枚举失败。
显示的错误如下图所示:
在Windows设备管理器中的设备状态上可以看到,设备启动失败。错误信息是:
Thsi device cannot start。(Code 10)
{Operation Failed}
The requested operation was unsuccessful.
本人测试的机器为英文操作系统,版本是win10 x64 10.0.17763.1879
由于我是将UVC从1.0改为UVC1.1,而且是只改了特定类请求和处理单元,所以我是知道是由于处理单元描述符引起的错误。
下面我将UVC各版本的处理单元描述符分类显示:
UVC1.0的处理单元描述符
typedef struct _USB_PU_DESCRIPTOR
{
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 bDescriptorSubtype;
UINT8 bUnitID;
UINT8 bSourceID;
UINT16 wMaxMultiplier;
UINT8 bControlSize;
UINT8 bmControls[n];
UINT8 iProcessing;
} USB_PU_DESCRIPTOR;
`
UVC1.1的处理单元描述符
typedef struct _USB_PU_DESCRIPTOR
{
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 bDescriptorSubtype;
UINT8 bUnitID;
UINT8 bSourceID;
UINT16 wMaxMultiplier;
UINT8 bControlSize;
UINT8 bmControls[n];
UINT8 iProcessing;
UINT8 bmVideoStandards;
} USB_PU_DESCRIPTOR;
UVC1.1相比较于UVC1.0,其总长度多了一个字节长度,这是因为多了一个bmVideoStandards字段。
而到UVC1.5中,处理单元描述符从一个可变的长度变成了固定长度的描述符,这是因为bmControls的个数变成了固定为3个。
参考文章:
UVC1.5 处理单元描述符 http://www.usbzh.com/article/detail-84.html
UVC1.0和UVC 1.1有什么区别 http://www.usbzh.com/article/detail-241.html