Android USB Camera(2) : UVC协议分析

1. 前言

本文对USB的功能类协议USB Video Class(UVC)的具体设计进行介绍,但不会介绍USB基础协议,所以需要对USB基础协议有一定的了解,包括USB四大描述符以及四种传输方式。分析usb协议的重点在于描述符,这里将以实际设备的描述符为线索,贯穿、分析uvc协议。

2. UVC功能概述

UVC设备都是多Interface设备,这点同普通的u盘不同。UVC设备最起码有两个Interface,VideoControl(VC)Interface和VideoStream(VS) Interface; 这也是最常见的UVC设备。 Spec明确要求一个具有可用的,具有实际UVC功能的设备要有一个VC Interface,一个或多个VS Interface。

VCInterface用于进行配置,操控,设置UVC设备进入不同的功能状态,而VSInterface则负责视频数据流的传输;完整的UVC功能需依赖VS,VC Interfaces的配合才能实现。

3. IAD以及Interfaces

UVC功能需要使用一个VC Interface和一个或多个VS Interface的配合。Spec明确要求UVC设备必须使用一个Interface Association Descriptor(IAD)来描述这个包含了VC和VS的Interfaces集合。

此外USB协议中并没有专门朝设备索取IAD的命令,IAD需作为Configuration描述符的一部分发送给Host端。在该Configuration描述符的排列顺序中,IAD要放在它所包含的VC,VS描述符之前,且同一个IAD中所有的VC,VS Interface的Interface number必须连贯。

===>Device Descriptor<===
...

===>Configuration Descriptor<===
...

===>IAD Descriptor<=== 
bLength: 0x08 
bDescriptorType: 0x0B 
bFirstInterface: 0x00 
bInterfaceCount: 0x02 
bFunctionClass: 0x0E -> Video Interface Class 
bFunctionSubClass: 0x03 -> Video Interface Collection 
bFunctionProtocol: 0x00 -> PC_PROTOCOL_UNDEFINED protocol 
iFunction: 0x00 

===>Interface Descriptor<=== 
bLength: 0x09 
bDescriptorType: 0x04 
bInterfaceNumber: 0x00 
bAlternateSetting: 0x00 
bNumEndpoints: 0x01 
bInterfaceClass: 0x0E -> Video Interface Class 
bInterfaceSubClass: 0x01 -> Video Control Interface SubClass 
bInterfaceProtocol: 0x00 
iInterface: 0x00
...

===>Interface Descriptor<=== 
bLength: 0x09 
bDescriptorType: 0x04 
bInterfaceNumber: 0x01 
bAlternateSetting: 0x00 
bNumEndpoints: 0x00 
bInterfaceClass: 0x0E -> Video Interface Class 
bInterfaceSubClass: 0x02 -> Video Streaming Interface SubClass 
bInterfaceProtocol: 0x00 
iInterface: 0x00
...

===>IAD Descriptor<=== 
bLength: 0x08 
bDescriptorType: 0x0B 
bFirstInterface: 0x02 
bInterfaceCount: 0x02 
bFunctionClass: 0x01 -> Audio Interface Class 
bFunctionSubClass: 0x01 -> Audio Control Interface SubClass 
bFunctionProtocol: 0x00 
iFunction: 0x04 
English (United States) "USB2.0 MIC" 

===>Interface Descriptor<=== 
bLength: 0x09 
bDescriptorType: 0x04 
bInterfaceNumber: 0x02 
bAlternateSetting: 0x00 
bNumEndpoints: 0x00 
bInterfaceClass: 0x01 -> Audio Interface Class 
bInterfaceSubClass: 0x01 -> Audio Control Interface SubClass 
bInterfaceProtocol: 0x00 
CAUTION: This may be an invalid bInterfaceProtocol 
iInterface: 0x04 
English (United States) "USB2.0 MIC"
...

===>Interface Descriptor<=== 
bLength: 0x09 
bDescriptorType: 0x04 
bInterfaceNumber: 0x03 
bAlternateSetting: 0x00 
bNumEndpoints: 0x00 
bInterfaceClass: 0x01 -> Audio Interface Class 
bInterfaceSubClass: 0x02 -> Audio Streaming Interface SubClass 
bInterfaceProtocol: 0x00 
CAUTION: This may be an invalid bInterfaceProtocol 
iInterface: 0x04 
English (United States) "USB2.0 MIC"
...

可以看到我所使用的uvc设备包含两个IAD,第一个IAD是视频输入设备,也就是摄像头。第二个IAD是音频输入设备,也就是麦克风,暂时忽略这个IAD。重点分析第一个IAD,它包含了两个Interface,一个VC Interface和一个VS Interface

4. VC Interface

VC主要用于控制UVC功能中的Units和Terminals,通过对不同的Units和Terminals发下不同的指令,从而影响UVC设备的当前工作状态;Host端发下的所有对UVC设备的操纵控制命令都是经由此Interface完成的

===>Interface Descriptor<=== 
bLength: 0x09 
bDescriptorType: 0x04 
bInterfaceNumber: 0x00 
bAlternateSetting: 0x00 
bNumEndpoints: 0x01 
bInterfaceClass: 0x0E -> Video Interface Class 
bInterfaceSubClass: 0x01 -> Video Control Interface SubClass 
bInterfaceProtocol: 0x00 
iInterface: 0x00 

===>Class-Specific Video Control Interface Header Descriptor<=== 
bLength: 0x0D 
bDescriptorType: 0x24 
bDescriptorSubtype: 0x01 
bcdVDC: 0x0100 
wTotalLength: 0x0033 -> Validated 
dwClockFreq: 0x02DC6C00 = (48000000) Hz 
bInCollection: 0x01 
baInterfaceNr[1]: 0x01 
USB Video Class device: spec version 1.0

===>Video Control Input Terminal Descriptor<===
...

===>Video Control Processing Unit Descriptor<===
...

===>Video Control Output Terminal Descriptor<===
...

===>Endpoint Descriptor<=== 
bLength: 0x07 
bDescriptorType: 0x05 
bEndpointAddress: 0x81 -> Direction: IN - EndpointID: 1 
bmAttributes: 0x03 -> Interrupt Transfer Type 
wMaxPacketSize: 0x0010 = 1 transactions per microframe, 0x10 max bytes 
bInterval: 0x0A 

===>Class-specific VC Interrupt Endpoint Descriptor<=== 
bLength: 0x05 
bDescriptorType: 0x25 
bDescriptorSubtype: 0x03 
wMaxTransferSize: 0x0010 = (16) Bytes

这个设备包含了一个Processing Unit、一个Input Terminal和Output Terminal,VC Interface需要对它们下发不同的命令,为此VC Interface需要包含一个控制端点(强制性要求),它使用的就是每个USB设备中默认的端点0。

另外一个Interrupt端点则是可选的,用来返回或通知Host端当前的UVC设备内部状态有变化。大部分情况下,一个UVC设备的VC Interface不需一定要实现此端点,但一旦UVC设备需要实现某些特定feature时,Spec会强制性要求实现该interrupt端点。

5. UVC设备内的各种Entity

UVC的Spec在制定时考虑到了诸多不同UVC设备可能存在的特性,为保证Spec具有最大范围的适用性和兼容性,将UVC设备内可能存在的每个功能模块划分为逻辑意义上的功能单元(Entity),并要求具体UVC设备的开发者必须为每个Entity指定ID号,且该ID号能唯一标识某一指定的功能单元,以便Host端的UVC驱动能依此对设备内不同的功能单元进行操作和配置。

Entity粗略可划分为Unit,Terminal两种。这都是逻辑意义上的划分,它们对应UVC设备内的某个功能单元。

5.1 Unit

Unit可以理解为构建出UVC设备功能的各功能单元,多个Unit按照一定的规则连接后就是一个完整的UVC功能设备。Spec规定Unit有一个或多个入口,一个出口;也就是说可以有多个Unit或Terminal作为一个Unit的输入源头,而数据在流经Unit后仅能作为其他Unit或Terminal的一个输入源头。

Spec中定义了三种Unit:Selector Unit (SU),Processing Unit (PU),Extension Unit (EU)。

===>Video Control Processing Unit Descriptor<=== 
bLength: 0x0B 
bDescriptorType: 0x24 
bDescriptorSubtype: 0x05 
bUnitID: 0x02 
bSourceID: 0x01 
wMaxMultiplier: 0x0000 
bControlSize: 0x02 
bmControls : 0x3F 0x06 
D00 = 1 
  • 7
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值