4. UVC(USB Video Class)协议基础
UVC(USB Video Class)是 USB-IF 定义的标准化视频设备协议,使摄像头、视频采集卡等设备无需安装专用驱动即可在主机端即插即用。在 ARM 平台移植 UVC Gadget 驱动前,必须深入理解 UVC 标准规范、视频流格式以及描述符结构。本章将围绕这三个核心知识点展开,为后续驱动移植打下坚实的协议基础。
4.1 UVC 标准规范概述
UVC 规范定义了一套标准的 USB 描述符、请求和事件机制,用于枚举和控制视频设备。其核心设计思想是将视频设备抽象为 功能单元(Functional Units) 和 终端(Terminals) 的拓扑结构。
uvcvideo)加载,无需厂商自定义驱动。
4.1.1 UVC 版本与兼容性
| UVC 版本 | 发布年份 | 主要特性 | ARM 平台关注点 |
|---|---|---|---|
| UVC 1.0 | 2003 | 基础视频流、静态图像捕获、MJPEG 格式 | 兼容性最广,Gadget 驱动首选 |
| UVC 1.1 | 2005 | 增加 H.264 支持、改进流控 | 需注意 H.264 编码器硬件支持 |
| UVC 1.5 | 2012 | 增加 H.265/HEVC、帧间隔控制 | ARM 平台硬件编码器需支持 HEVC |
4.1.2 UVC 功能拓扑结构
UVC 设备内部由多个逻辑单元组成,主机通过 USB 控制传输(端点 0)与这些单元交互。典型的 UVC 摄像头拓扑包含以下单元:
- 输入终端(IT): 代表物理摄像头传感器,负责采集原始图像数据。
- 处理单元(PU): 负责图像处理,如亮度、对比度、饱和度调节。
- 编码单元(EU): 负责将原始视频流编码为 MJPEG 或 H.264 格式。
- 输出终端(OT): 代表 USB 接口,将编码后的视频流发送给主机。
4.2 视频流格式:MJPEG 与 H.264
UVC 规范支持多种视频编码格式,其中 MJPEG 和 H.264 是 ARM 平台最常用的两种格式。两者在带宽占用、编码复杂度、主机兼容性方面差异显著。
4.2.1 MJPEG(Motion JPEG)
MJPEG 将视频的每一帧独立压缩为 JPEG 图像。其特点是编码简单、帧内无依赖,适合嵌入式平台的低功耗场景。
- 编码原理: 每帧独立 JPEG 压缩,帧间无预测。
- 带宽需求: 较高,1080p@30fps 约需 30-50 Mbps。
- 主机兼容性: 极佳,所有操作系统原生支持。
- ARM 实现: 可使用硬件 JPEG 编码器或软件 libjpeg。
4.2.2 H.264(Advanced Video Coding)
H.264 利用帧间预测和变换编码,在相同画质下带宽仅为 MJPEG 的 1/5 到 1/10。但编码复杂度高,通常需要硬件编码器支持。
- 编码原理: I/P/B 帧结构,帧间运动估计与补偿。
- 带宽需求: 较低,1080p@30fps 约需 5-10 Mbps。
- 主机兼容性: UVC 1.1+ 支持,Windows/macOS 需额外解码器。
- ARM 实现: 必须依赖硬件 H.264 编码器(如 Rockchip MPP、Allwinner VENC)。
| 对比维度 | MJPEG | H.264 |
|---|---|---|
| 编码复杂度 | 低(适合 MCU/低功耗 ARM) | 高(需硬件编码器) |
| 带宽占用 | 高(30-50 Mbps @1080p) | 低(5-10 Mbps @1080p) |
| 帧内依赖 | 无(每帧独立) | 有(I/P/B 帧依赖) |
| UVC 版本要求 | UVC 1.0+ | UVC 1.1+ |
| 主机解码 | 无需解码器 | 需 H.264 解码器 |
4.3 UVC 描述符结构
UVC 描述符是设备向主机声明自身能力的数据结构,位于 USB 配置描述符中。主机通过解析这些描述符来识别视频流格式、分辨率、帧率以及控制能力。UVC 描述符分为 标准描述符 和 类特定描述符 两大类。
4.3.1 接口描述符(Interface Descriptor)
UVC 设备通常包含两个接口:控制接口(Interface 0) 和 流接口(Interface 1)。控制接口用于发送 UVC 请求(如设置亮度、启动/停止流),流接口用于传输视频数据。
- 控制接口(VideoControl Interface):
- 接口类:0x0E(Video Interface Class)
- 接口子类:0x01(VideoControl Subclass)
- 接口协议:0x00(未指定)
- 包含:终端描述符、单元描述符
- 流接口(VideoStreaming Interface):
- 接口类:0x0E(Video Interface Class)
- 接口子类:0x02(VideoStreaming Subclass)
- 接口协议:0x00(未指定)
- 包含:格式描述符、帧描述符、端点描述符
4.3.2 端点描述符(Endpoint Descriptor)
流接口必须包含一个 等时(Isochronous) 或 批量(Bulk) 端点,用于传输视频帧数据。UVC 1.0 标准推荐使用等时端点,但 UVC 1.5 开始支持批量端点以提升兼容性。
| 端点类型 | 传输方式 | 带宽保证 | 典型应用 |
|---|---|---|---|
| 等时端点 | Isochronous | 有(预留带宽) | UVC 1.0 标准摄像头 |
| 批量端点 | Bulk | 无(尽力而为) | UVC 1.5 高分辨率摄像头 |
4.3.3 类特定描述符(Class-Specific Descriptors)
UVC 定义了一系列类特定描述符,用于描述视频格式、帧尺寸、帧率等参数。这些描述符位于流接口的接口描述符之后。
- VS_INPUT_HEADER: 描述流接口的总体信息,包含支持的格式数量。
- VS_FORMAT_MJPEG / VS_FORMAT_H264: 描述视频编码格式,如 MJPEG 或 H.264。
- VS_FRAME_MJPEG / VS_FRAME_H264: 描述帧尺寸(宽度、高度)和帧率(帧间隔)。
- VS_COLORFORMAT: 描述色彩空间(如 YUY2、NV12)。
4.3.4 描述符代码示例(UVC Gadget 内核配置)
在 Linux 内核的 UVC Gadget 驱动中,描述符通过 uvc_function_info 结构体定义。以下是一个简化的 MJPEG 流接口描述符配置片段:
/* 流接口描述符定义 */
static struct usb_interface_descriptor uvc_streaming_intf_alt0 = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 1, /* 流接口编号 */
.bAlternateSetting = 0, /* 备用设置 0:无带宽 */
.bNumEndpoints = 0, /* 无端点 */
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = UVC_SC_VIDEOSTREAMING,
.bInterfaceProtocol = 0,
.iInterface = 0,
};
static struct usb_interface_descriptor uvc_streaming_intf_alt1 = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 1,
.bAlternateSetting = 1, /* 备用设置 1:启用流 */
.bNumEndpoints = 1, /* 1 个批量端点 */
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = UVC_SC_VIDEOSTREAMING,
.bInterfaceProtocol = 0,
.iInterface = 0,
};
/* 批量端点描述符 */
static struct usb_endpoint_descriptor uvc_fs_streaming_ep = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN | 1, /* EP1 IN */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = cpu_to_le16(512), /* 全速批量最大包 */
.bInterval = 0,
};
bAlternateSetting 用于切换带宽模式。备用设置 0 表示无数据传输(用于枚举),备用设置 1 及以上表示启用视频流。主机通过 SET_INTERFACE 请求切换备用设置。
4.4 本章小结
UVC 协议是 USB Gadget 摄像头驱动的核心通信语言。本章涵盖了:
- UVC 标准规范: 版本演进、功能单元拓扑结构。
- 视频流格式: MJPEG 与 H.264 的编码原理、带宽对比及 ARM 实现要点。
- 描述符结构: 接口描述符、端点描述符、类特定描述符的层级关系与代码示例。