关于UVC摄像头指示灯的调试过程总结
最近遇到了一个很是奇怪的UVC摄像头指示灯问题,现象如下:
上层应用是一个会议系统软件,当需要进行会议时,点击会议按钮添加会议。这时应用软件打开摄像头,并开始与服务器进行网络连接。当然由于摄像头的打开,摄像头指示灯点亮。
上层应用软件与服务器连接后,进行会议界面。这时突然摄像头指示灯熄灭,但会议正常,摄像头图像正常,就是摄像头指示灯熄灭。
由于上层应用软件为第三方开发,不知其详细工作原理,无技术支持。
USB摄像头固件也为第三方提供,也无法提供相关的技术资料。
手头只有自己根据摄像头的抓包信息,开发的Windows驱动。
当然,Windows提供了UVC摄像头的驱动,我里由于我们需要做一些特殊处理,故需要自己重新开发驱动。
调试了很多次,发现有时摄像头指示灯也会正常,不过也就是几十次出现一次正常。自己反反复复,做了很多实验,过程如下:
- 换一台主机,问题依旧。
- 再换一台主机,偶尔正常。
- 将本次使用的4K摄像头换成1K的摄像头,正常。
- 换上位机应用软件,正常。
- 在出现问题的摄像头上再次试验,多次也会出现偶尔的正常。
这里又有一个很奇怪的问题,就是换应用软件,就正常了。比如我将定制的专业会议软件换成了potplayer播放器,人家就没有问题。但是使用专用的应用软件时,前期正常,连接上会议后进入会议后出现问题。
这时通过抓包分析,发现进入会议系统后,有大量的UVC扩展单元请求。由于我们基于UVC扩展单元做了一些私有通讯,所以从这里来看,应该是这里的问题。
但是!!!这是不应该或者说是不可能的。因为关于UVC的扩展单元的通讯,我并没有在转发至固件,所有关于UVC的扩展请求我都是在Windows内核中自行处理的。
所以,奇了个怪了~~~
但是,通过更换1K别的摄像头,所有东西又都是正常的。所以我这时怀疑是否有一些别的能讯,比如固件中有类似看门狗的东西,是需要定时喂狗的,不然,人家就是给你熄灯~ 哎,想的真是越来越多了。但是,写固件的人没必要这么坑的吧,这么搞~
调试,调试,当你进入一个坑的时候,只要不放弃,总能找到原因的,总能爬出来的。
一个实在没有办法的时候,退抓全包。发现抓到一次HID获取描述符和HID的SET_IDLE请求。所以这时大概率应该是这个SET_IDLE的坑。
手中的摄像头是一个复合设备,即UVC摄像头+自定义的HID设备。
先不管那么多,过滤掉SET_IDLE请求。
else if (Urb->UrbHeader.Function == URB_FUNCTION_CLASS_INTERFACE)
{
if (Urb->UrbControlVendorClassRequest.Request == 0x0A) //idle
{
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED;
}
else if (Urb->UrbControlVendorClassRequest.Request == 0x03)//protocol
{
}
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);
return Status;
}
再次加载程序,运行,一切OK!!!!
其实在这个过程中,无法确定灯的问题时,偿试着绕过这个问题.就是定时将灯拉起,但定时拉灯又会出现了一些别的问题,偿试了很多种方法,效果都不满意,无奈放弃。关于这一段血泪史,就不再诉说了。
最后再说一下这个SET_IDLE,这个请求在灯灭的时候,还发生了错误。
抓包内容如下:
CTL 21 0a 00 00 00 00 00 00 SET_IDLE
USTS C0000004 stall pid
包标识PID错误,这时BUShound就搞不定了。只有换USB总线分析仪了。
关于PID的资料可参考:http://www.usbzh.com/article/detail-73.html
想想,最近事还挺多的,自己手头的这个USB总线分析仪,算不,不提也罢。。。
记录此问题,改天再详细分析。