3. UVC协议规范详解:UVC 1.5标准、视频控制接口(VC)、视频流接口(VS)、描述符结构

UVC(USB Video Class)协议是USB-IF组织为USB摄像头设备定义的标准协议。本章深入解析UVC 1.5标准的核心规范,重点讲解视频控制接口(VC)与视频流接口(VS)的职责划分,以及描述符结构的组织方式。理解这些内容是开发UVC Gadget驱动的理论基础。

核心要点: UVC协议将摄像头设备抽象为两个独立的接口——视频控制接口(VC)负责设备控制与参数调节,视频流接口(VS)负责视频数据的传输。这种分离设计使得控制逻辑与数据流解耦,便于驱动分层实现。

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机制:标准化的流参数协商流程,确保主机与设备之间的格式、分辨率、帧率一致。
开发提示: 在UVC Gadget驱动中,我们主要实现UVC 1.5的子集——单流、MJPEG/YUYV格式、基本控制(亮度、对比度、曝光)。扩展单元可用于添加厂商特定功能,但需主机端驱动配合。

3.2 视频控制接口(VC)

视频控制接口(Video Control Interface,VC)是UVC设备的控制中心,负责处理所有与视频参数相关的控制请求。VC接口通过控制端点(Endpoint 0,默认控制管道)与主机通信,使用USB标准请求(Class-Specific Request)来读写设备属性。

视频控制接口(VC)架构 主机UVC驱动 控制请求 VC接口 (控制端点0) 输入单元 处理单元 输出单元 扩展单元 控制路由 VC接口关键单元说明 • 输入单元(IT):代表物理摄像头传感器,提供格式、分辨率信息。 • 处理单元(PU):负责图像处理控制(亮度、对比度、饱和度、白平衡)。 • 输出单元(OU):控制输出方向(如USB、HDMI),UVC Gadget中固定为USB。 • 扩展单元(XU):厂商自定义控制,通过私有请求ID访问。 • 控制请求格式:bmRequestType=0xA1(读)或0x21(写),bRequest=SET_CUR/GET_CUR。

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)
实现注意: UVC Gadget驱动中,VC接口的控制请求处理函数需要解析控制选择子,并调用对应的硬件控制函数。如果硬件不支持某个控制,应在描述符中将其标记为“不支持”,否则主机端会尝试发送请求导致错误。

3.3 视频流接口(VS)

视频流接口(Video Streaming Interface,VS)负责视频数据的实际传输。VS接口使用等时端点(Isochronous Endpoint)或批量端点(Bulk Endpoint)来发送视频帧数据。UVC 1.5标准推荐使用等时传输以保证实时性,但在USB Gadget场景中,批量传输更常见(兼容性更好)。

视频流接口(VS)数据传输流程 主机UVC驱动 VS端点 (等时/批量) Gadget驱动 视频帧数据 帧回调 Probe & Commit 协商流程 1. 主机发送PROBE_CONTROL(GET_CUR)获取设备支持的默认格式。 2. 主机修改格式/分辨率/帧率后发送PROBE_CONTROL(SET_CUR)进行试探。 3. 设备返回调整后的参数(可能降级),主机确认后发送COMMIT_CONTROL生效。 视频帧结构(UVC 1.5) 每个视频帧由多个USB数据包组成:帧头(FID位标记帧边界)+ 负载数据 + 帧尾(EOF标记)。 Gadget驱动需在每帧开始时设置FID位翻转,并在帧结束时发送空包(Zero-Length Packet)表示结束。

VS接口的核心机制是Probe & Commit协商流程,它确保主机和设备就视频格式达成一致:

  1. PROBE_CONTROL(GET_CUR):主机读取设备当前默认的流参数(格式、分辨率、帧率)。
  2. PROBE_CONTROL(SET_CUR):主机修改参数后发送给设备试探,设备返回实际可用的参数(可能降级)。
  3. PROBE_CONTROL(GET_CUR):主机再次读取确认设备接受的参数。
  4. COMMIT_CONTROL(SET_CUR):主机提交最终参数,设备开始按此参数发送视频流。
开发技巧: 在UVC Gadget驱动中,Probe阶段可以返回一个“最接近”的格式,而不是严格匹配。例如主机请求1920x1080@30fps,如果硬件只支持1280x720@30fps,则在Probe中返回1280x720,主机通常会接受降级方案。

3.4 描述符结构

UVC设备的描述符是USB描述符体系中的核心部分,它向主机声明设备的能力和配置。UVC描述符分为标准描述符和类特定描述符两类。标准描述符(设备描述符、配置描述符、接口描述符、端点描述符)遵循USB规范,类特定描述符则定义UVC特有的信息。

UVC描述符层次结构 设备描述符 配置描述符 VC接口描述符 VS接口描述符 摄像头终端描述符 处理单元描述符 输出单元描述符 扩展单元描述符 输入头描述符 格式描述符(MJPEG/YUYV) 帧描述符(分辨率/帧率) 颜色匹配描述符

在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 定义分辨率、帧率范围、缓冲区大小
描述符组织原则: 描述符必须按照USB规范要求的顺序排列:设备描述符 → 配置描述符 → 接口描述符(VC) → 类特定VC描述符 → 接口描述符(VS,备用设置0) → 接口描述符(VS,备用设置1) → 类特定VS描述符 → 端点描述符。任何顺序错误都会导致主机枚举失败。

3.5 本章小结