Linux USB – Using Multiple USB Webcams in Linux

bandwidthdebianlinuxusbwebcam

Running more than one USB webcam in Debian/Linux results in the the following error:

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

What initially seemed to be a programming issue in OpenCV turned into a quest for a mysterious hardware/software problem after the same errors were produced by running cheese and xawtv.

Apparently it's caused by webcams requesting all the available bandwidth on the USB host controller. With that in mind I decided to run wireshark and capinfos to see just how much bandwidth a single camera used.

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

Interesting! That might explain why two cameras at 320×240 work but any higher resolution fails. It's as if my USB controller is only operating at USB 1 speeds, yet lsusb shows both webcams belonging to a device which supposedly supports 480 megabits per second.

One solution proposed forcing the webcams to calculate their bandwidth usage instead of requesting their maximum by running the following commands:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

Unfortunately that made no difference, so I decided to try another solution. A post on StackOverflow suggested telling my webcams to use a lower FPS or compressed video format like MJPEG, but after running v4lctl list it doesn't appear either of my webcams support changing their video mode.

And that's where I'm stuck. Why would two webcams operating well below the maximum speed of USB 2 would produce this error?

ps: It's not a disk space issue, df displays no change when the webcams are started.

pps: If it makes a difference, here's the output of lsusb

Best Answer

Ding ding! Managed to figure this one out with some help from the nice people in #v4l on freenode.

Long story short: v4l2-ctl is the best tool for debugging USB camera issues. Read all the available commands and the man page, it'll be fun I promise. Using v4l2-ctl I discovered one of my cameras did not support any compressed video modes. You can check what modes your cameras support by running the following command:

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

Which should output something like this.

 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)

If the only pixel format returned is "YUYV", "IUYV", "I420", or "GBRG" you'll only be able to run one camera per USB controller* since those formats are uncompressed. Using multiple webcams which support MJPEG or some other form of compression will work fine.

If you use OpenCV like me, don't worry if the default pixel format isn't compressed as it appears OpenCV defaults to using compression anyway.

**Unless you're happy with 320x240 resolution or lower.*

Related Question