1. 前言
接上文,本文简化UVC拓扑结构,抽像出一个简单的VideoControl 来介绍常用的VC Interface 及接口描述符。
如图所示,VC Interface 包含CT,PU、OT三部分,事实上只是一个接口,然后根据不同的子类型实现不同的单元(CT/PU/OT)
每个Terminal或者Unit都有唯一的标识,各个单元之间的联系是通过bSourceID建立联系。
2. VideoControl Interface
VideoControl(以下简称VC)Interface 描述符,包含所有相关信息,以表示,相应的视频功能。
VC 分类 Standard VC 和 Class-specific 接口,即标准VC接口和特殊类接口。
2.1 标准VC接口
标准 VC 接口描述符和标准接口描述符的定义是一样的,只是用来表示接口本身。
- bLength:描述符长度,固定为9
- bDescriptorType:描述符类型。这里为接口描述符,设为0x4
- bInterfaceNumber:接口索引,0表示VideoControl,1表示VideoStream
- bAlternateSetting:可替换设置索引
- bNumEndpoints:端点0以外的端点数,这里表示一个端点
- bInterfaceClass:接口类,0xE表示Video_Class
- bInterfaceSubClass:接口子类,这里是0x1表示VideoControl,0x2表示VideoStream
- bInterfaceProtocol:协议代码,这里因为看的是uvc1.5的协议所以必须设为1.
- iInterface:接口字符串描述符的索引值
关于PC_PROTOCOL_15 可参考以下连接说明
driver/usb/gadget/function/f_uvc.c
static struct usb_interface_descriptor uvc_control_intf = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, .bInterfaceNumber = UVC_INTF_VIDEO_CONTROL, .bAlternateSetting = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = UVC_SC_VIDEOCONTROL, .bInterfaceProtocol = 0x00, /* 默认不支持1.5协议 */ .iInterface = 0, };
2.2 特殊类VC接口
UVC 特殊类接口描述符是一连串的描述符,它包含了所有用来描述设备功能的描述符,比如 unit 和 terminal 描述符。它们直连的链接关系可以通过描述符中的 bSourceID 或者 baSourceID 。
2.2.1 接口头
类特殊描述符整个长度依赖于uint和terminal,因此该描述符以一个头为开始,如下图:
- bLength:描述符长度,为n+12
- bDescriptorType:描述符类型。
- bDescriptorType:0x1,表示是VC_HEADER
- bcdUVC:支持的UVC协议版本
- wTotalLength:整个类特殊描述符的长度
- dwClockFrequency:时钟频率
- bInCollection:指定设备拥有的 VideoStream 接口数
- baInterfaceNr(1):VideoStream 接口号
- baInterfaceNr(...):
/* driver/usb/gadget/legacy/webcam.c */ DECLARE_UVC_HEADER_DESCRIPTOR(1); static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = { .bLength = UVC_DT_HEADER_SIZE(1), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = UVC_VC_HEADER, .bcdUVC = cpu_to_le16(0x0150), .wTotalLength = 0, /* dynamic */ .dwClockFrequency = cpu_to_le32(48000000), .bInCollection = 0, /* dynamic */ .baInterfaceNr[0] = 0, /* dynamic */ };
2.2.2 Camera Terminal Descriptor
Input Terminal Descriptor (简称IT)。CT描述符,表示camera 输入描述符。其结构如下:
- bLength:描述符长度
- bDescriptorType:描述符类型,
- bDescriptorSubType:描述符子类,VC_INPUT_TERMINAL,
- bTerminalID:CT 唯一标识
- wTerminalType:Terminal type
- bAssocTerminal:用于将IT 和OT关联,如果不存在关联,设为0
- iTerminal:字符串描述符的索引,用来描述CT
- wObjectiveFocalLengthMin:默认设为0,不支持zoom
- wObjectiveFocalLengthMax:默认设为0
- wOcularFocalLength:默认设为0
- bControlSize:bm 控制
- bmControls[n]:具体控制支持
/* driver/usb/gadget/legacy/webcam.c */ static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = { .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = UVC_VC_INPUT_TERMINAL, .bTerminalID = 1, .wTerminalType = cpu_to_le16(0x0201), .bAssocTerminal = 0, .iTerminal = 0, .wObjectiveFocalLengthMin = cpu_to_le16(0), .wObjectiveFocalLengthMax = cpu_to_le16(0), .wOcularFocalLength = cpu_to_le16(0), .bControlSize = 3, .bmControls[0] = 2, .bmControls[1] = 0, .bmControls[2] = 0, };
2.2.3 Processing Unit Descriptor
Processing Unit 描述符,以下简称PU 描述符,结构如下:
- bLength:描述符长度
- bDescriptorType:描述符类型,这里表示接口,
- bDescriptorSubType:描述符子类,这里表示一个PU单元
- bUnitID:PU 唯一标识
- bSourceID:源ID,
- wMaxMultiplier:
- bControlSize:bm控制占字节数
- bmControls[0]:bm 控制
- bmControls[1] :
- iProcessing:PU 字符串描述索引
static const struct uvc_processing_unit_descriptor uvc_processing = { .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = UVC_VC_PROCESSING_UNIT, .bUnitID = 2, .bSourceID = 1, .wMaxMultiplier = cpu_to_le16(16*1024), .bControlSize = 2, .bmControls[0] = 1, .bmControls[1] = 0, .iProcessing = 0, };
2.2.4 Output Terminal Descriptor
Output Terminal Descriptor ,简称OT 描述符,结构如下:
- bLength:描述符长度
- bDescriptorType:描述符类型,表明这个一个接口
- bDescriptorSubTypeL:描述符子类,表示PU类型
- bTerminalID:OT 唯一标识
- wTerminalType:Terminal 类型,表明是一个Stream Terminal
- bAssocTerminal:无关联
- bSourceID:源ID,为2表示,OT 直接与PU相连(暂时忽略SU)
- iTerminal:未用。字符串描述索引。
static const struct uvc_output_terminal_descriptor uvc_output_terminal = { .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL, .bTerminalID = 3, .wTerminalType = cpu_to_le16(0x0101), .bAssocTerminal = 0, .bSourceID = 2, .iTerminal = 0, };
2.2.5 其他
其他接口单元暂时不做介绍,比如SU,和IT以及EU,XU等
3. 总结
本文以一个简单的模型介绍了,uvc的VideoContrl Interface 以及包含的描述符信息。通过此文,可以看出,VC Interface 事实上完成的就是两个功能:
- 视频流输入输出:CT/OT
- Camera 控制:对焦、曝光、白平衡等等
通过配置PU 和 CT 单元,可以为UVC设备添加各种各样的功能。同时,只有设备端描述符正确配置,主机才能获取并且知道设备到底支持哪些功能。