usbCamera相同规格摄像头不同时出预览图的一种解决思路

最近在做一项目,正常点亮一拖四usbCamera,开发版是用的是MTK8173,应用方面参考https://github.com/saki4510t/UVCCamera

单个摄像头点亮无问题,不同厂商,型号的四个摄像头同时点亮,预览,拍照,录像也是正常的。但当相同厂商,型号,也即读取的摄像头descriptor完全相同,问题就出现了,只有先挂载的可以正常预览,相同规格摄像头的第二个就无法出预览图。

出现问题的log中,明显的错误如下:

01-02 04:24:45.286  3519  3572 I libUVCCamera: [3572*UVCPreview.cpp:492:prepare_preview]:frameSize=(640,480)@MJPEG

01-02 04:24:45.294  3519  3572 E libuvc/stream: [3572*stream.c:1605:uvc_stream_start_bandwidth]:fail

01-02 04:24:45.294  3519  3572 W libUVCCamera: [3572*diag.c:88:uvc_perror]:failed start_streaming:Unknown error (-99)

提示uvc_stream_start_bandwidth出错。同样,在github能找到的issue里,最接近的是

https://github.com/saki4510t/UVCCamera/issues/8

遗憾的是从头看到尾,目前作者没有给到很好的解决方案。

 

没办法,还得从代码去找问题,追logcat却也看不出来问题,就想到从kernel角度看下,其log如下:

<6>[  235.960068]  (1)[1394:CameraThread]usb 1-2.1.4: zzz,usbdev_do_ioctl: SETINTERFACE

<3>[  235.961266]  (1)[1394:CameraThread]usb 1-2.1.4: zzz111,proc_setintf come here

<3>[  235.962165]  (1)[1394:CameraThread]usb 1-2.1.4: zzz222,proc_setintf come here

<3>[  235.963069]  (1)[1394:CameraThread]usb 1-2.1.4: zzz333,proc_setintf come here

<3>[235.963956]   (1)[1394:CameraThread]usb  1-2.1.4: zzz,proc_setintfproc_setintf here setintf.interface=1,setintf.altsetting=1

<6>[  235.965366]  (1)[1394:CameraThread]usb 1-2.1.4: zzz,usb_set_interface come,interface=1,alternate=1

<6>[  235.966485]  (1)[1394:CameraThread]usbfs 1-2.1.4:1.1: zzz,intf->altsetting[i].desc.bAlternateSetting=0, altnum=1

<6>[  235.967797]  (1)[1394:CameraThread]usbfs 1-2.1.4:1.1: zzz,intf->altsetting[i].desc.bAlternateSetting=1, altnum=1

<6>[  235.969389]  (1)[1394:CameraThread]usb 1-2.1.4: zzz,usb_set_interface product=USB 2.0 HD Camera ,manufacturer=(null),serial=(null),devnum=7,desc.bInterfaceNumber=1

<6>[  235.971774]  (5)[1394:CameraThread]usb 1-2.1.4: zzz,cur_alt && new_alt is true come here

<3>[  235.972890]  (5)[1394:CameraThread]xhci-hcd xhci-hcd.1.auto: zzz3,xhci_mtk_add_ep_quirk() type:1, speed:3, mpkt:1024, dir:1, ep:ffffffc076e62800

<3>[  235.974508]  (5)[1394:CameraThread]xhci-hcd xhci-hcd.1.auto: zzz,Not enough bandwidth!

<6>[  235.975501]  (5)[1394:CameraThread]usb 1-2.1.4: zzzzz,Not enough bandwidth for altsetting 1,ret=-28

<4>[  236.049537]  (0)[104:kworker/u12:1]mfg_2d: Power-off latency exceeded, new value 162616 ns

<4>[  242.132057]  (1)[140:kworker/u12:4]mfg_2d: Power-off latency exceeded, new value 174231 ns<222 -> 1338>

同样是提示带宽不足,错误序号-28(/* No space left on device */)

<3>[  235.974508]  (5)[1394:CameraThread]xhci-hcd xhci-hcd.1.auto: zzz,Not enough bandwidth!

<6>[  235.975501]  (5)[1394:CameraThread]usb 1-2.1.4: zzzzz,Not enough bandwidth for altsetting 1,ret=-28

 

至此,对于usb带宽和协议不是很了解的情况下,依然不晓得,应该怎样修复此问题。

https://github.com/saki4510t/UVCCamera/issues/8得知,即使相同规格,有部分摄像头是可以满足同时出图的。恰好手头有深蓝科技的一组摄像头,就可以正常使用,其kernel log如下:

<3>[ 9617.289236]  (1)[1498:CameraThread]usb 1-2.1.2: zzz,proc_setintfproc_setintf here setintf.interface=1,setintf.altsetting=2

<6>[ 9617.290630]  (1)[1498:CameraThread]usb 1-2.1.2: zzz,usb_set_interface come,interface=1,alternate=2

<6>[ 9617.291982]  (1)[1498:CameraThread]usbfs 1-2.1.2:1.1: zzz,intf->altsetting[i].desc.bAlternateSetting=0, altnum=2

<6>[ 9617.293637]  (1)[1498:CameraThread]usbfs 1-2.1.2:1.1: zzz,intf->altsetting[i].desc.bAlternateSetting=1, altnum=2

<6>[ 9617.295322]  (1)[1498:CameraThread]usbfs 1-2.1.2:1.1: zzz,intf->altsetting[i].desc.bAlternateSetting=2, altnum=2

<6>[ 9617.296613]  (1)[1498:CameraThread]usb 1-2.1.2: zzz,usb_set_interface product=USB2.0_CAM1,manufacturer=D-vitec,serial=0000,devnum=9,desc.bInterfaceNumber=1

<6>[ 9617.298352]  (1)[1498:CameraThread]usb 1-2.1.2: cur_alt && new_alt is true come here

<3>[ 9617.299343]  (1)[1498:CameraThread]xhci-hcd xhci-hcd.1.auto: zzz3,xhci_mtk_add_ep_quirk() type:1, speed:3, mpkt:512, dir:1, ep:ffffffc06f0dd800

通过上述log,发现GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc))这个值不一样,手头出错的 mpkt:1024, 深蓝科技的mpkt:512,通过代码追踪,在libusb的驱动文件中stream.cuvc_stream_start_bandwidth方法

uvc_error_t uvc_stream_start_bandwidth(uvc_stream_handle_t *strmh, uvc_frame_callback_t *cb, void *user_ptr, float bandwidth_factor, uint8_t flags) {


......

/* Find the endpoint with the number specified in the VS header */ 

for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) {

endpoint = altsetting->endpoint + ep_idx; 

if (endpoint->bEndpointAddress==format_desc->parent->bEndpointAddress){ 

endpoint_bytes_per_packet = endpoint->wMaxPacketSize; LOGE("zzz11,endpoint_bytes_per_packet=%d",endpoint_bytes_per_packet); // wMaxPacketSize: [unused:2 (multiplier-1):3 size:11] 

// bit10…0: maximum packet size 

// bit12…11: the number of additional transaction opportunities per microframe for high-speed 

// 00 = None (1 transaction per microframe) 

// 01 = 1 additional (2 per microframe) 

// 10 = 2 additional (3 per microframe) 

// 11 = Reserved 

//*/new add here

if ((endpoint_bytes_per_packet & 0x07ff) > 512) {

 endpoint_bytes_per_packet = endpoint_bytes_per_packet/2;

 }

//*/

endpoint_bytes_per_packet = (endpoint_bytes_per_packet & 0x07ff) * (((endpoint_bytes_per_packet >> 11) & 3) + 1); LOGE("zzz22,endpoint_bytes_per_packet=%d",endpoint_bytes_per_packet); break; 

} 

}

......

}

 

endpoint->wMaxPacketSize; 得到的值的前11位的值即为我们log中的mptk,在这边当此值大于512时,强行赋一半的值给它,则问题解决,两种完全相同规格的摄像头可以同时出预览图。

  由于对驱动模块不是很熟悉,对USB协议相关的知识也知之甚少,以上仅从当前代码的角度,提供一拖四或一拖二usbCamera相同规格摄像头不能同时出图的一种思路。但是应该有更好的,更彻底的解决方案。

 

猜你喜欢

转载自blog.csdn.net/Alice86/article/details/82667729