UVC摄像头技术笔记
+ -

USB摄像头同步传输H264遇到的花屏问题

2021-11-09 1158 0

以往拿到的摄像头数据传输都是批量传输,本人也只在音频驱动的开发中使用了同步传输
这次突然拿到一个摄像头,数据采用的是同步传输,本以为很简单的代码移植,却没有想到还是遇到了一个坑,自己花费了大力气来排查,在这期间自己也看了大量的资料,今天在这里做一个简单的总结。

以前的摄像头拿到的USB摄像头如批量传输,数据每隔8192字节加一个UVC负载数据头,而且是MJPG格式,固件厂商也比较讲究,数据包中没有大量没用的00数据,只要搞定一个,后面它们弄的像H264等其它格式的摄像头,自己也只做一个适配就行了,所以驱动开发起来那就一个快并轻松。
如一包MJPG的数据,它的数据格式布局大概如下:
UVC数据格式

但这次拿到的摄像头比较事多,是一个H264格式的同步传输的摄像头,它是有数据时发数据,没有数据时发00,数据和00全部混在一起,同步对于每个小包USBD_ISO_PACKET_DESCRIPTOR的1024长度数据,也加了UVC负载数据头
对于同步的数据传输,本人在每URB中每读取0x80个同步包。这样在我的理解中,每个URB应返回一个完整数据帧或者半完整帧,这样自己通过代码再将这个URB中的数据进行整合,应该就没有问题了。
数据整合的代码如下:

  PURB urb = frame->Urb;
  ULONG OkOffset = 0;
  for (ULONG i = 0; i < urb->UrbIsochronousTransfer.NumberOfPackets; i++)
  {
       if (urb->UrbIsochronousTransfer.IsoPacket[i].Status == STATUS_SUCCESS 
          && urb->UrbIsochronousTransfer.IsoPacket[i].Length >0)
      {
          PUCHAR pSrc = frame->data + urb->UrbIsochronousTransfer.IsoPacket[i].Offset;
          ULONG  PackeLen = urb->UrbIsochronousTransfer.IsoPacket[i].Length;
        //  if (OkOffset != urb->UrbIsochronousTransfer.IsoPacket[i].Offset)
          {
              RtlCopyMemory(frame->data + OkOffset,pSrc,PackeLen);
          }
          OkOffset += PackeLen;
      }
  }

  frame->size = urb->UrbIsochronousTransfer.TransferBufferLength ;
`

但这个数据在交层解析时,会出现花屏问题。
这个奇怪的问题竟然一弄就查了2天。
最后经过本人不懈的努务,终于发现了问题所在。
原因在于每URB中的同步传会出现粘包问题,所以这个URB中可能会有两包的数据,这样在中间的IsoPacket中会出现某一包的长度不等于1024字节,这样经过上层的代码进行拷贝后,会出现负载数据头错乱的问题,导致解码失败。
最后调整增加如下代码代码:

ULONG  PackeLen = urb->UrbIsochronousTransfer.IsoPacket[i].Length;
if (i < (urb->UrbIsochronousTransfer.NumberOfPackets-1)  
    && PackeLen != (urb->UrbIsochronousTransfer.IsoPacket[i+1].Offset - urb->UrbIsochronousTransfer.IsoPacket[i].Offset))
{
    PackeLen = urb->UrbIsochronousTransfer.IsoPacket[i+1].Offset - urb->UrbIsochronousTransfer.IsoPacket[i].Offset;
}

...
 frame->size = OkOffset;//

这样即可解决花屏问题

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)被发送给设备。这个规格的协议层章详细描述了用来完成同步传输的包,总线事务和事务处理流程。也描述了怎么样传送时序信息给设备。超速同步传输......
Windows下USB驱动同步URB转IRP请求函数代码
URB和IRP类似,只不过一个应用于通用的Windows驱动,一个专职于USB。USB的URB的负载是IRP,其通过负载到IRP时,然后使用通用的Windows IRP请求发向下层目标USB设备。USB与IRP的关联是通过IRP的IO_STACK_LOCATION的 IoStack->Para......
Windows下USB驱动异步URB转IRP请求函数代码
URB有同步请求,也有异步请求。这里微软官方提供了一个异步请求URB的代码示例// The SubmitUrbASync routine submits an URB asynchronously.//// Parameters://// Parameters:// Devic......
Windows下USB驱动同步URB转IRP请求函数代码-改进版
URB的同步调用一般使用:Windows下USB驱动同步URB转IRP请求函数代码 http://www.usbzh.com/article/detail-547.html但是,在某些特定的情况下,有时会因为下底设备并没有完成而挂死。这里提供一种超时取消IRP的方法,同时考虑到了线和切换的情况。这里......
Windows下虚拟USB设备数据的读写请求调试笔记
到现在为止,本人已经在Windows下确切来说是Windows10 x64下开发了以下USB虚拟USB设备:USB虚拟UVC摄像头设备USB虚拟UAC麦克风设备USB虚拟HID键盘设备USB虚拟HID鼠标设备USB虚拟HID键盘鼠标复合设备USB虚拟HID单点触摸屏设备USB虚拟HID多点触摸屏......
基于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事务,虽然数据的传输方向为设备端到主机,但是该事务却是由主机发起。由于设备的输入端点提供的负载数据小于该......
使用BUSHOUND手动分析USB控制传输的URB
USB的控制传输是最基本的传输类型,控制传输适用于设备的枚举和设备的状态控制。我里我们使用BUSHOUND来抓取USB控制传输的URB。同样的,我们使用的操作系统是Windows10 x64,和同步传输URB抓包一样,我们先抓取数据,然后再分析数据结构。这里我插入电脑的U盘的枚举以获取设备描述符为......
使用BUSHOUND手动分析USB批量传输的URB
使用BUSHOUND抓取U盘的批量传输的URB数据,我们对其其进行数据分析:13 IN 55 53 42 53 40 0b ac 57 00 00 00 00 00 URB80 00 09 00 00 00 00 00 d8 f2 75 a0 77 7f 00 00 ......
USB摄像头同步传输的完成后URB参数
这几天不是闲来无事,一个工作的任务就是对手中一个USB摄像头进行驱动开发,并进行视频格式的转换。通过分析该USB摄像头可知,其采用的是同步传输,所以本人在开发的驱动中,使用同步的URB进行下发请求数据,然后在完成例程中获取数据。同步传输URB本人在 手动分析使用BUSHOUND抓取同步传输URB......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

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

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