skip to content
busstop.dev

Webcam "in use by another program" caused by USB speed

/ 2 min read

I got this weird issue where teams always reported my camera as in use, when it is not, at least it shouldn’t be. The LED was also not on, so naturally, this rang some alarm bells. Long story short, it’s just on the wrong port.

One cause of this is USB bandwidth. If the camera, or the hub/dock/monitor it connects through, is on a USB 2.0 port, there may not be enough bandwidth to start the video stream, and the driver fails the stream start. The application reports the failure as “in use”.

My setup: Arch, a Logitech BRIO connected through a Dell U4025QW monitor’s built-in USB hub/KVM, which also carries a 2.5GbE NIC and other peripherals on the same bus.

Check for a process holding the device

sudo fuser -v /dev/video*
sudo lsof /dev/video*

Run these with sudo; unprivileged fuser does not report all processes. If a process appears, close it. If nothing holds the device and the application still fails, continue.

Get the error from the driver

Stream from the device directly (v4l2-ctl --list-devices lists the nodes; substitute yours):

v4l2-ctl -d /dev/video0 --stream-mmap

This returns the underlying errno. For a bandwidth limit:

VIDIOC_STREAMON returned -1 (No space left on device)

To start a stream, uvcvideo requests an isochronous bandwidth reservation from the USB host controller. When the bus has no bandwidth left to reserve, the request fails with ENOSPC.

Requesting a compressed format instead of raw, might work, and is a sign its bandwidth limited:

v4l2-ctl -d /dev/video0 --set-fmt-video=width=640,height=480,pixelformat=MJPG --stream-mmap --stream-count=5 --stream-to=/dev/null

If output shows <<<<< while raw fails, the problem is most likely bandwidth.

Check the negotiated USB speed

lsusb -t

The rightmost column is the link speed. Find the camera’s line (Driver=uvcvideo):

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/10p, 480M
    |__ Port 2: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M

480M is USB 2.0 (high speed). USB 3 shows 5000M or 10000M. In my case, I also had a 2.5Gbe NIC in my monitor’s KVM, which took up all the available bandwidth.

Fix

The fix for me was just plugging it in to a USB3 port.