Create a virtual UVC device to stream video as webcam

camerausb

I'm looking for a way to use a video file and stream it so it looks like it's a real UVC device.

I did some research and I found uvc-gadget But I can't work out if this does what I am after. I have to use UVC because eventually I want to be able to stream the video over usb from another device without having any extra software installed on the receiver. But for now just a tool that can run on the same device and emulate a UVC device will work.

Are there any tools available that can do this?

Best Answer

USB is asymmetric: There are USB masters (your PC) and USB slaves (the devices). That's why there are two different types of USB connectors, type A for masters and type B for slaves, though the distinction is becoming blurred by hardware designers using type A everywhere, and USB OTG can do both.

Linux USB gadget devices are kernel modules that represent a USB device on a USB slave controller. They need a (slave-) host controller (HC) to connect to; on an embedded Linux system representing the device, that would be the driver for the USB controller. On a PC there is no hardware.

But there's another kernel module which can simulate an USB slave controller: dummy_hcd. This module will provide a virtual (slave-) host controller for the gadgets to connect to, and a virtual (master-) host controller which gives you an additional USB bus where those devices show up.

Example:

# modprobe dummy_hcd
# lsusb
...
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
# modprobe g_serial
# lsusb
...
Bus 005 Device 002: ID 0525:a4a7 Netchip Technology, Inc. Linux-USB Serial Gadget (CDC ACM mode)
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

And you get two new device nodes, /dev/ttyGS0 from g_serial for the gadget and /dev/ttyACM0 from the automatically loaded cdc_serial module which represents the device. You can test that they communicate by writing into one and reading from the other.

There is also g_webcam a a gadget UVC driver. It creates a new /dev/video* device, and just like /dev/ttyGS0 above, you can stream video into this device to use the gadget. And that's what your uvc-gadget user space program does: It either takes a static image, or another existing "real" UVC device is input, and streams it into the newly created /dev/video*, so you can feed your USB device real data and see if it comes out correctly on the USB master that uses this device.

However, it doesn't seem to work with the dummy_hcd bus (I tried just now): Just like above, a second /dev/video* device should be created by the USB kernel module on the master side that uses the webcam. That doesn't happen; instead, the USB system becomes so confused after a short time I can't use my keyboard and mouse anymore.

So either g_webcam is buggy, or possibly the video subsystem tries to create both devices with the same identifier and then breaks, or maybe something else. I don't know.

So it might work only on a real embedded system with a real (slave-) host controller.

So, yes, there are tools available that can do this, but unfortunately the simulation is buggy if you want the simulated device to appear on the same computer (an ordinary PC). It might still work on an embedded system (you didn't say where and how you want to use the emulated device).

Related Question