UVC摄像头技术笔记
+ -

USB 等时/同步传输、块传输与转换设置在UVC摄像头驱动中的探讨

2021-05-11 2929 0

最近在Windows10 x64环境下,开发了一个虚拟UVC摄像头驱动。确切的来说这不是摄像头驱动,而是一个虚拟USB总线驱动。使用该虚拟总线驱动使用应用软件通过IOCTL控制总线子设备的创建与卸载。

框架设计

驱动安装完成后,是一个单纯的USB虚拟总线。

应用软件通过发送自定义IOCTL码IOCTL_BUSENUM_PLUGIN_CAMERA通知驱动程序。
驱动程序收到IOCTL_BUSENUM_PLUGIN_CAMERA请求后,使用IoCreateDevice创建一个PDO,并挂入子设备链表,然后使用IoInvalidateDeviceRelations通过PNP管理器该问线子设备有变化。
后续就是一堆的子设备的枚举,详细的过程可见 windows加载即插即用PNP设备的过程 一节。

言归正转,使用该虚拟总线驱动枚举出一个子设备后,子设备会加载USB通用驱动USBCCGP,再由USBCCGP枚举出UVC Camera设备。其总线关系如下图所示:

本人的测试机为英文操作系统

  • Virtula USB Bus 我们开发的虚拟总线驱动vusbbus.sys
    • USB Compoite Device - USB通用驱动usbccgp.sys
      • USB Cpature - USB摄像头驱动 ksthunksys和usbvideo.sys

总线关系

UVC描述符布局

批量传输

参考UVC1.5描述符相关章节.本人的配置描述符布局如下:
这里只写重要的描述符。

可以看到,在这里使视频流的传输使用了0x82地址,最大传输字节为16KB,使用的是块传输。
在使用过程中,发现会出现一个问题,就是上层打开摄像头时,而我们通过我们的开发的应用软件很难有一个好的方法获取当前摄像头的是否处于打开状态,这样很难报告上层应用软件是否需要写数据。

等时/同步传输

在原来来块传输的基础下,修改配置描述符如下:

这里将原来的接口1中的端点个数设为0,并新增加一个其转换设置为1的接口描述符,在其内部再原来的块/批量传输改为等时传输,并需要修改wMaxPacketSize=400。这是因为在等时传输的包(高速全速)的最大上限为1024个字节,否则虽然会枚举成功,但打开摄像头时会报说设备被占用的错误导致打开失败。
注意

wMaxPacketSize的值可设置大于1024,如在本人笔记本自带的摄像头在YUV2格式时设置为0XC00,详见 UV2摄像头相关数据大小计算

另外,修改模式时,在固件中也应相应配置相应端点的工作模式,不能只改端点描述符的属性而不改变在初始化端点的相关代码。另外不同类型的端点传输数据时使用的函数也有所不同,所以一定要注意。

关于等时传输的包大小:

等时/同步传输的包大小最大1024字节,是指每次的传输,但每个URB中可以包含多个包传输。
如以WINDOWS下URB的等进传输URB结构体定义如下:

struct _URB_ISOCH_TRANSFER {
    struct _URB_HEADER Hdr;
    USBD_PIPE_HANDLE PipeHandle;
    ULONG TransferFlags;
    ULONG TransferBufferLength;
    PVOID TransferBuffer;
    PMDL TransferBufferMDL;
    struct _URB *UrbLink; // Reserved
    struct _URB_HCD_AREA hca; // Reserved
    ULONG StartFrame;
    ULONG NumberOfPackets;
    ULONG ErrorCount;
    USBD_ISO_PACKET_DESCRIPTOR IsoPacket[1];
};
typedef struct _USBD_ISO_PACKET_DESCRIPTOR {
    ULONG Offset;
    ULONG Length;
    USBD_STATUS Status;
} USBD_ISO_PACKET_DESCRIPTOR, *PUSBD_ISO_PACKET_DESCRIPTOR;

这里NumberOfPackets代表可以该URB可以有多少个数据包。如将最大设为1024,则Offset为该 USBD_ISO_PACKET_DESCRIPTOR的数据偏移,为1024的整数包,Length为该包的长度,前面几包为1024,最后一包小于等于1024字节。

这里有一个比较奇怪的问题就是,如果新的接口1中的端点类型设为块传输,但上层依旧会依等时/同步传输的方式来读取数据。可能这是因为是在转换设置接口中的吧。
PS:在Linux(内核版本为5.6.11)内核源代码中uvc_video.c:2056中有如下代码,可以看到,这里是通过判断转换接口来区分是等时传输还是块传输的:

    /* Select the video decoding function */
    if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
        if (stream->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
            stream->decode = uvc_video_decode_isight;
        else if (stream->intf->num_altsetting > 1)
            stream->decode = uvc_video_decode_isoc;
        else
            stream->decode = uvc_video_decode_bulk;
    }

关于摄像头是否打开的判断

通过上层选择接口中其转换设置的不同,可以判断当前摄像头的状态。

  • 如转换设置为0,表示关闭或初始化摄像头。
  • 如转换设置为1,表示打开摄像头。

UVC摄像头使用批量传输的方式进行数据读取的,详见UVC 摄像头的打开与关闭一节详细的特定类请求

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

UVC 等时传输中的URB_ISOCH_TRANSFER
通过UVC规范可知,视频图像数据的读取可使用两种端点传输方式,分别为:BULK 块/批量传输方式ISO 等时/同步传输方式在Windows内核中,USB数据的读取是通过URB来进行传输的,其结构体是一个大大的共用体,根据数据传输的方式对应其不同的结构体,其内容如下:typedef _Struct_s......
UVC等时传输中的dwMaxPayloadTransferSize
UVC的视频流接口控制请求的数据大小可为26字节,34字节和48字节,其分别对应的是UVC的1.0,1,1和UVC1.5版本。在其整个视频流控制接口参数偏移地址22处的字段为一4字节的dwMaxPayloadTransferSize,根据其字段解释为“指定设备在单个有效负载传输中可以传输或接收的最大......
USB 等时/同步传输、块传输与转换设置在UVC摄像头驱动中的探讨
最近在Windows10 x64环境下,开发了一个虚拟UVC摄像头驱动。确切的来说这不是摄像头驱动,而是一个虚拟USB总线驱动。使用该虚拟总线驱动使用应用软件通过IOCTL控制总线子设备的创建与卸载。框架设计驱动安装完成后,是一个单纯的USB虚拟总线。应用软件通过发送自定义IOCTL码IOCTL......
USB 同步/等时传输方式
USB协议规定了四种传输类型:控制传输、批量传输、同步传输、中断传输。等时传输也有“同步传输”的叫法,一般用于要求数据连续、实时且数据量大的场合,其对传输延时十分敏感,类似用于USB摄像设备,USB语音设备等等。同步事务没有握手包。当一个同步传输中有多个事务时,最后一个事务之前的事务的数据长......
USB超高速 同步传输
正如USB2.0一样,超速同步传输类型是用来支持想要能容忍错误,周期性的轮询服务的传输流。超速跟USB2.0一样不发送起始帧,但是时序信息要通过同步时间戳包(ITP)被发送给设备。这个规格的协议层章详细描述了用来完成同步传输的包,总线事务和事务处理流程。也描述了怎么样传送时序信息给设备。超速同步传输......
基于UVC规范的USB摄像头数据传输模式的总结
根据UVC(USB VIDEO CLASS)规范,UVC视频数据传输方式支持:同步传输即ISO传输批量传输即BULK传输但是不同的操作系统对UVC规范的支持不一定是全量支持的:Windows操作系统对于windows操作系统,对UVC版本的支持情况如下:UVC 版本Windows ......
手动分析使用BUSHOUND抓取同步传输的URB
BUSHOUND大家太熟了,使用它来进行数据抓包那不太太方便。但在BUSHOUND的抓取配置项中,有一个叫了URB的东西,我相信大家都没有选中过,因为一般来说,对WINDOWS USB驱动开发人员来说都不一定有用,更何况大家也只是用来抓取一下几个数据的输入输出,更没有必要进行USB的分析了。本人今天......
USB 同步传输端点的数据包PID序列及额外传输端点大小
对于同步传输:如果输入端点提供的负载数据小于端点描述符指定的最大负载数据,则主机端将不再该端点提供进一步的输入事务。这是因为所对USB设备来说,所有的数据传输都是由主机发起的。对于数据输入IN事务,虽然数据的传输方向为设备端到主机,但是该事务却是由主机发起。由于设备的输入端点提供的负载数据小于该......
USB摄像头同步传输的完成后URB参数
这几天不是闲来无事,一个工作的任务就是对手中一个USB摄像头进行驱动开发,并进行视频格式的转换。通过分析该USB摄像头可知,其采用的是同步传输,所以本人在开发的驱动中,使用同步的URB进行下发请求数据,然后在完成例程中获取数据。同步传输的URB本人在 手动分析使用BUSHOUND抓取同步传输的URB......
UAC麦克风同步传输的URB分析
之前写过同步传输的UVC摄像头的URB,文章名称为:手动分析使用BUSHOUND抓取同步传输的URB 。今天恰好手中有一个UVC麦克风,所以也拿来分析。也许和之前的文章有所重复,但是因为侧重点的不同,也许会有意想不到的小收获取。言归正转,我们知道,在UAC音频规范中,数据的传输不像UVC摄像头那样,......
USB摄像头同步传输H264遇到的花屏问题
以往拿到的摄像头数据传输都是批量传输,本人也只在音频驱动的开发中使用了同步传输。这次突然拿到一个摄像头,数据采用的是同步传输,本以为很简单的代码移植,却没有想到还是遇到了一个坑,自己花费了大力气来排查,在这期间自己也看了大量的资料,今天在这里做一个简单的总结。以前的摄像头拿到的USB摄像头如批量传......
USB2.0 同步传输数据包PID序列
同步传输方式分为全速模式和高速模式,低速模式不存在同步传输。全速传输模式下的数据包PID序列全速模式下的同步传输数据方式只使用DATA0包,因此接收方在接收数据时只会收到DATA0数据包。高速传输模式下的数据包PID序列高速模式下的数据包序列根据一个微帧中的事务个数不同,采用不同的数据包序列,使......
UAC音频设备的同步传输(同步、自适应、异步)模式区分
USB定义了四种数据传输,分别为控制传输,中断传输、批量传输和同步传输。其中同步传输按端点的配置可分为同步方式,自适应方式和异步方式。这是通过端点描述符的bEndpointType的bit3-2的值来进行配置的。bEndpointType的bit3-2传输方式00无同步0......
USB2.0低速、全速、高速模式四种传输模式速宽对比
USB 数据传输通过事务来实现。事务在帧的主机控制时间间隔内进行。事务的长度和频率取决于端点使用的传输类型。可以在一个帧中发送的传输类型和帧长度由 USB 的指定速度定义。低速模式下控制传输、中断传输、批量传输、同步传输对比低速帧速率为1ms传输类型最大传输长度每帧的传输次数最大理......
USB传输模式选择及各传输特性对比
通用串行总线 (USB) 传输类型是指主机和设备端点之间使用的通信模式。传输类型决定了用于与端点通信的事务的频率和长度。传输类型还可以分配一个循环冗余校验和 (CRC),以对每个传输的数据包进行验证。传输类型由设备设置,并在枚举过程中与主机通信。USB分为四种传输模式,分别为中断传输模式,控制传输......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!