这个问题也是困扰自己好久,终于解决了。有必要写个文章mark一下。
先说下原因,Linux中为usb camera提供了一个统一的驱动以方便使用,只要符合驱动规范就可以实现即插即用usb camera设备,即免驱动安装乐。usb bus的 bandwidth是有限的,而本着贪心原则,camera会要求获取最大带宽(usb2.0 camera480?);而将两个camera接入一路usb bus,打开第二个camera就会出现”No space left on device”的错误。
解决方法一:
接在不同的usb bus上,使用lsusb 命令查看bus信息, 类似“Linux Foundation 2.0 root hub”表示该总线为usb 2.0;
解决方法二:
降低打开视频流的分辨率,改为320x240;并对uvcvideo驱动设置参数,强制为camera分配带宽时计算所需带宽而非申请全部带宽;(只对YUYV格式有效,对有些camera此方法可以支持640x480分辨率)
sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128
解决方法三:
以上两种都是搜索到的绝大部分的解决方法,但都不能解决我的问题,最后也是查资料尝试。终于解决了,因此写了这篇文章mark一下;
1.下载kernel源码
这个可能会很慢,我实在官网下载的,为此还给Git配置了代理=-=
看造化了,不过好像去github上下载会好很多。
2.切换版本
#查看现在运行系统内核版本
uname -r
#切换到相应版本,我的是4.2.0-27-generic
git checkout v4.2
3.拷贝UVC Driver源码
cp linux/drivers/media/usb/uvc .
4.修改Makefile
cd uvc
vim Makefile
obj-m += uvcvideo.o
uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
uvc_status.o uvc_isight.o uvc_debugfs.o
ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
uvcvideo-objs += uvc_entity.o
endif
obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
5.修改UVC Driver
cd uvc
vim uvc_video.c
#跳转到函数uvc_fixup_video_ctrl(),在该函数最后添加下代码
if (format->flags & UVC_FMT_FLAG_COMPRESSED) {
ctrl->dwMaxPayloadTransferSize = 0x400;
}
6.编译修改后的驱动并移除原本的uvcvideo驱动和装载修改后的驱动
make
sudo rmmod uvcvideo
sudo insmod ./uvcvideo.ko quirks=128
7.到这里基本上就成功了,我在ubuntu14.04上就可以了,实现一路usb bus打开两个camera,运行3个也是可以的,但在Ubuntu16.04上却没有装成功,这是属于开发驱动一块遇到的问题了。
这里写一下自己在解决这问题时,用到的一些命令,防止忘记了以后。
#查看运行系统usb bus的使用情况
sudo cat /sys/kernel/debug/usb/devices | grep "B: "
#查看usb设备和属性
lsusb
#查看camera支持的格式和分辨率以及帧率信息
v4l2-ctl -d /dev/video1 --list-formats-ext
#如果配置了ffmepg
ffmpeg -f v4l2 -list_formats all -i /dev/video1