UVC 基础学习(4):VideoContrl Interface 及其描述符介绍

简介: 所有信息整理来源于UVC 官方spec 翻译理解及内核源码做参考

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 可参考以下连接说明

https://patchwork.kernel.org/project/linux-media/patch/1447090438-28681-1-git-send-email-laurent.pinchart@ideasonboard.com/

image.png


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(...):


image.png


/* 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]:具体控制支持


image.png


image.png


/* 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 字符串描述索引


image.png

image.png


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:未用。字符串描述索引。


image.png


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设备添加各种各样的功能。同时,只有设备端描述符正确配置,主机才能获取并且知道设备到底支持哪些功能。

相关文章
|
1月前
|
算法 数据处理 C++
Franca IDL与CommonAPI C++ D-Bus实战教程:方法、信号和属性传递详解
Franca IDL与CommonAPI C++ D-Bus实战教程:方法、信号和属性传递详解
91 0
|
2月前
|
缓存 Python
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
|
11月前
|
编解码 C++ 索引
UVC 基础学习(5):VideoStream Interface 描述符介绍
今天我们继续学习UVC的接口描述符:VideoStream 。 VideoStream 接口描述符是整个UVC设备最重要的组成之一,和VideoControl一样,其也包含标准接口和特殊类接口。
452 0
|
11月前
|
索引
UVC 基础学习(3):基础描述符介绍
UVC 基础学习(3):基础描述符介绍
413 0
|
11月前
|
C++
UVC 基础学习(6):端点描述符介绍
今天带大家认识一下UVC端点描述符信息。
308 0
|
Linux