3. UVC协议规范详解:UVC 1.5标准、视频控制接口(VC)、视频流接口(VS)、描述符结构
UVC(USB Video Class)协议是USB-IF组织为USB摄像头设备定义的标准协议。本章深入解析UVC 1.5标准的核心规范,重点讲解视频控制接口(VC)与视频流接口(VS)的职责划分,以及描述符结构的组织方式。理解这些内容是开发UVC Gadget驱动的理论基础。
3.1 UVC 1.5标准概述
UVC 1.5标准于2012年发布,是当前最广泛使用的USB摄像头协议版本。它定义了摄像头设备与主机之间的通信规范,包括设备描述、控制机制、数据格式和传输方式。
| 版本 | 发布时间 | 主要特性 | 支持分辨率 |
|---|---|---|---|
| UVC 1.0 | 2003年 | 基础视频流、静态格式 | VGA (640x480) |
| UVC 1.1 | 2005年 | 动态格式切换、H.264支持 | HD (1280x720) |
| UVC 1.5 | 2012年 | 多流、帧间隔控制、扩展单元 | Full HD (1920x1080) |
| UVC 1.6 | 2020年 | MJPEG优化、低延迟模式 | 4K (3840x2160) |
UVC 1.5标准的核心改进包括:
- 多流支持:允许设备同时输出多个不同格式或分辨率的视频流。
- 帧间隔控制:支持更精细的帧率调节,通过Frame Interval Descriptor实现。
- 扩展单元(Extension Unit):提供厂商自定义控制通道,用于实现私有功能(如自动对焦、白平衡)。
- Probe & Commit机制:标准化的流参数协商流程,确保主机与设备之间的格式、分辨率、帧率一致。
3.2 视频控制接口(VC)
视频控制接口(Video Control Interface,VC)是UVC设备的控制中心,负责处理所有与视频参数相关的控制请求。VC接口通过控制端点(Endpoint 0,默认控制管道)与主机通信,使用USB标准请求(Class-Specific Request)来读写设备属性。
VC接口通过控制选择子(Control Selector)来区分不同的控制功能。每个控制选择子对应一个特定的摄像头参数,例如:
| 控制选择子 | 名称 | 所属单元 | 数据类型 |
|---|---|---|---|
| PU_BRIGHTNESS_CONTROL | 亮度 | 处理单元 | WORD (signed) |
| PU_CONTRAST_CONTROL | 对比度 | 处理单元 | WORD (unsigned) |
| PU_SATURATION_CONTROL | 饱和度 | 处理单元 | WORD (unsigned) |
| PU_WHITE_BALANCE_TEMPERATURE_CONTROL | 白平衡色温 | 处理单元 | WORD (unsigned) |
| CT_ZOOM_ABSOLUTE_CONTROL | 变焦(绝对) | 摄像头终端 | WORD (unsigned) |
| CT_EXPOSURE_TIME_ABSOLUTE_CONTROL | 曝光时间 | 摄像头终端 | DWORD (unsigned) |
3.3 视频流接口(VS)
视频流接口(Video Streaming Interface,VS)负责视频数据的实际传输。VS接口使用等时端点(Isochronous Endpoint)或批量端点(Bulk Endpoint)来发送视频帧数据。UVC 1.5标准推荐使用等时传输以保证实时性,但在USB Gadget场景中,批量传输更常见(兼容性更好)。
VS接口的核心机制是Probe & Commit协商流程,它确保主机和设备就视频格式达成一致:
- PROBE_CONTROL(GET_CUR):主机读取设备当前默认的流参数(格式、分辨率、帧率)。
- PROBE_CONTROL(SET_CUR):主机修改参数后发送给设备试探,设备返回实际可用的参数(可能降级)。
- PROBE_CONTROL(GET_CUR):主机再次读取确认设备接受的参数。
- COMMIT_CONTROL(SET_CUR):主机提交最终参数,设备开始按此参数发送视频流。
3.4 描述符结构
UVC设备的描述符是USB描述符体系中的核心部分,它向主机声明设备的能力和配置。UVC描述符分为标准描述符和类特定描述符两类。标准描述符(设备描述符、配置描述符、接口描述符、端点描述符)遵循USB规范,类特定描述符则定义UVC特有的信息。
在UVC Gadget驱动中,描述符通常以静态数组的形式定义在驱动代码中。以下是一个典型的UVC描述符结构示例(简化版):
/* UVC 1.5 描述符结构示例(简化) */
static struct usb_interface_descriptor uvc_control_intf = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0, /* VC接口号 */
.bAlternateSetting = 0,
.bNumEndpoints = 0, /* VC使用端点0 */
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = USB_SUBCLASS_VIDEOCONTROL,
.bInterfaceProtocol = 0x10, /* UVC 1.5 */
};
static struct uvc_control_endpoint_descriptor uvc_control_ep = {
.bLength = UVC_DT_CONTROL_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_CS_ENDPOINT,
.bDescriptorSubType = UVC_EP_CONTROL,
.bmAttributes = 0x00,
.wMaxPacketSize = 0x0000,
};
static struct usb_interface_descriptor uvc_streaming_intf = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 1, /* VS接口号 */
.bAlternateSetting = 1, /* 备用设置1:开启流 */
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = USB_SUBCLASS_VIDEOSTREAMING,
.bInterfaceProtocol = 0x10,
};
static struct usb_endpoint_descriptor uvc_streaming_ep = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x81, /* IN端点,地址1 */
.bmAttributes = USB_ENDPOINT_XFER_ISOC, /* 等时传输 */
.wMaxPacketSize = cpu_to_le16(1024),
.bInterval = 1,
};
UVC类特定描述符的详细字段说明:
| 描述符类型 | 子类型 | 关键字段 | 说明 |
|---|---|---|---|
| VC头描述符 | UVC_VC_HEADER | bcdUVC, wTotalLength, dwClockFrequency | 声明UVC版本、描述符总长度、时钟频率 |
| 摄像头终端描述符 | UVC_VC_INPUT_TERMINAL | wTerminalType, wObjectiveFocalLengthMin/Max | 定义传感器类型(如ITT_CAMERA)和物理特性 |
| 处理单元描述符 | UVC_VC_PROCESSING_UNIT | bUnitID, bmControls, iProcessing | 声明支持的控制(亮度、对比度等) |
| VS输入头描述符 | UVC_VS_INPUT_HEADER | bNumFormats, wTotalLength, bEndpointAddress | 声明支持的格式数量和端点地址 |
| 格式描述符 | UVC_VS_FORMAT_MJPEG / UVC_VS_FORMAT_FRAME_BASED | bFormatIndex, bNumFrameDescriptors, bmFlags | 定义格式类型(MJPEG/YUYV/H.264) |
| 帧描述符 | UVC_VS_FRAME_MJPEG / UVC_VS_FRAME_FRAME_BASED | wWidth, wHeight, dwMinBitRate, dwMaxVideoFrameBufferSize | 定义分辨率、帧率范围、缓冲区大小 |