在Linux中使用多个USB网络摄像头


30

在Debian / Linux中运行多个USB网络摄像头会导致以下错误:

libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device

在运行Cheese和xawtv产生相同的错误之后,最初似乎是OpenCV中的编程问题变成了对神秘的硬件/软件问题的寻求。

显然,这是由网络摄像头请求USB主机控制器上的所有可用带宽引起的。考虑到这一点,我决定运行wiresharkcapinfos来查看单个摄像机使用了多少带宽。

4 megabits per second at 320x240
14 megabits per second at 640x480
32 megabits per second at 1280x720

有趣!这也许可以解释为什么两台320x240的摄像机都可以工作,但任何更高的分辨率都失败了。好像我的USB控制器仅以USB 1速度运行,但是lsusb显示两个网络摄像头都属于一个设备,该设备据说每秒可支持480兆位。

一种解决方案建议通过运行以下命令来强制网络摄像头计算其带宽使用量,而不是请求其最大使用量:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

不幸的是,这没有什么区别,所以我决定尝试另一种解决方案。StackOverflow上的一则帖子建议告诉我的网络摄像头使用较低的FPS或压缩视频格式(例如MJPEG),但是在运行v4lctl list之后,我的网络摄像头均未显示支持更改其视频模式。

那就是我被困住的地方。为什么两个网络摄像头在USB 2的最大速度以下运行时会产生此错误?

ps:这不是磁盘空间问题,启动网络摄像头时df不会显示任何更改。

pps:如果有所作为,这是lsusb的输出

Answers:


25

叮叮!在freenode上#v4l中的好人的帮助下设法设法解决了这一问题。

长话短说:v4l2-ctl是调试USB摄像头问题的最佳工具。阅读所有可用的命令和手册页,我保证这会很有趣。使用v4l2-ctl,我发现我的一台相机不支持任何压缩视频模式。您可以通过运行以下命令检查相机支持的模式:

v4l2-ctl -d /dev/video0 --list-formats

哪个应该输出这样的东西。

 ioctl: VIDIOC_ENUM_FMT
 Index       : 0
 Type        : Video Capture
 Pixel Format: 'MJPG' (compressed)
 Name        : MJPEG

 Index       : 1
 Type        : Video Capture
 Pixel Format: 'YUYV'
 Name        : YUV 4:2:2 (YUYV)

如果返回的唯一像素格式是“ YUYV”,“ IUYV”,“ I420”或“ GBRG”,则每个USB控制器只能运行一台相机*,因为这些格式未经压缩。使用支持MJPEG或其他某种压缩形式的多个网络摄像头可以正常工作。

如果像我一样使用OpenCV,请不要担心默认像素格式是否会被压缩,因为OpenCV默认会使用压缩。

**除非您对320x240或更低的分辨率满意。*


1
嗨,如果可以的话,您能告诉我如何设置2台摄像机的像素格式,以便同时捕获640x480的像素吗?我正在使用OpenCV,目前遇到的情况与您一样,两个摄像机都只能在320x240或更低的分辨率下工作
lexma 2012年

啊哈!v4l2-ctl确实是调试的绝佳工具。发现了很多有关我的相机的信息,并能够解决此问题。无论如何,我可以通过将相机的分辨率强制为320x240YUYV用作相机输出模式来修复它。guvcview也帮了很多忙。
Sheharyar 2014年

使用320x240或更低的分辨率时,我得到的结果好坏参半。我买了4个便宜的USB网络摄像头,所有的品牌/型号都相同。尝试以160x120的分辨率运行2时,其中一些可以正常工作,而另一些则给出了内存错误。我看不出押韵或理由。当然,这些网络摄像头的价格为每台$ 3,所以我想我付了钱。
塞林2015年

即使通过USB2.0集线器,也可以将其中两个或多个相机连接到USB3.0。与YUYV确认。
米哈尔莱昂

7

答案是使用上文描述的SwDevRefugee编写的uvcvideo修改。他和我共同努力,成功为OpenWrt编译了经过修改的代码。我正在其上运行的版本是tplink wdr3600路由器上的OpenWRT DESIGNDTED DRIVER(出血边缘,r48130):

结果:我可以通过USB 2.0集线器以1280x960和15fps的MJPG格式同时运行3 * c270(logitech)。对不起,我没有第四台C270可以连接。

我还可以使用YUV格式的2 * c270和1 * GEMBIRD 640 * 480 * 15fps,但是添加第二个GEMBIRD会导致可怕的“无法开始捕获:设备上没有空间”(这里的space == bandwidth)熟悉:))。请注意,GEMBIRD(1908:2311)== http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/

在wdr3600上3 * c270的CPU使用率是相当合理的:

Mem: 50600K used, 75444K free, 320K shrd, 3436K buff, 8800K cached

CPU:  16% usr  27% sys   0% nic  45% idle   0% io   0% irq  10% sirq

Load average: 1.20 0.85 0.44 4/60 2546

  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND

 2240  1679 root     S    15348  12%  17% mjpg_streamer --input input_uvc.so --

 2505  1679 root     S    15368  12%  11% mjpg_streamer --input input_uvc.so --

 2239  1679 root     S    15532  12%  11% mjpg_streamer --input input_uvc.so --

如果社区给予了一定的声誉和支持,我认为SwDevRefugee愿意将代码导入uvc-linux。


4

我查看了uvcvideo驱动程序,如果流是mjpeg压缩的,则quirks = 128模块参数将被忽略。

我选择的网络摄像头是Logitech C500和Logitech C270,我发现C500在1280x1024分辨率下生成的图像为100 KB,而C270在1280x960分辨率下生成的图像为200KB。

如果我以10fps的速度运行C270,则所需的比特率是10x200000x8 = 16Mbit / s。在Ubuntu 14.04中,无论帧速率如何,uvcdriver模块始终分配196Mbits / s。对于C500,它的性能要好一些,但仍然是带宽消耗。

我已经修改了uvcvideo驱动程序,以便可以通过V4L2接口为驱动程序提供“压缩”因子。这是一个“小问题”,因为我在struct v4l2_pix_format中使用了priv属性来指定值。在驱动程序中,它计算未压缩图像的大小,然后除以压缩系数,得出要使用的USB带宽。

默认情况下,我使用10的压缩因子,如果相机遇到特别难压缩的图像,则可以留出较大的余量。以1280x960和10fps的速度运行的C270现在使用41Mbit / s,我可以轻松地在一条总线上运行4个摄像机。

如果有人对此功能感兴趣,那么我将尝试让uvcvideo维护人员考虑“压缩”因素的概念。


我和OpenROV社区中的其他人可能希望看到您的uvc驱动程序@SwDevRefugee的mod。我正在尝试将两个网络摄像头集成到OpenROV中(一个用于向下看视觉测距,另一个用于正常驾驶/观看),但是遇到了相同的带宽问题。您是否考虑过发布您的国防部/或提交拉动更改请求?

请求更改uvc驱动程序的官方方法是通过以下邮件列表:linux-uvc-devel@lists.sourceforge.net。我在2015年12月30日发布了变更请求以及其他后续发布的更多信息。我没有得到维护者的回应。另外两个人对此变化表示了兴趣。我不知道要采取任何行动需要多少人。也许@laughlinb也可以发布到邮件列表中。
SwDevAlien

@SwDevRefugee:我想要您的建议unix.stackexchange.com/q/287279/52764
Ragav

@Ragav:我认为您需要通过使用行为良好的应用程序(例如luvcview)以适当的分辨率同时打开所有摄像机,以找出问题所在,如果出现故障,则应向您提供丰富的错误消息。
SwDevAlien

1
Ragav的问题是他的摄像机仅支持YUYV,并且当他使用quirks = 0x80标志时,驱动程序迫使他每个摄像机至少使用1024字节/微帧(65.5 Mbit / s)。摄像机支持的最低更大带宽为2040字节/微帧,这使事实更加复杂,因此,即使他只希望以6fps的速度获得320x240的带宽,他在一条USB总线上也只能拥有2个摄像机。uvcvideo驱动程序在内核的2.6.32和3.16版本之间添加了至少1024个字节/微帧的限制。
SwDevAlien

-1

我也因为空间不足而出错。可行的方法是拔下一个摄像头,然后将其插入固定式PC上的另一个USB端口-周围散布着大约6或7个USB端口。运行“ show_webcams 0 1”,然后突然显示两个图像。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.