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).
Best Answer
I can't test this because the app crashes on ICS, but this should be possible using v4l2loopback and gstreamer.
Compile and load the v4l2loopback kernel module. Note down the v4l2 device it creates (
/dev/videoX
).Then use something like the following:
While the gstreamer pipeline is running, the video should appear in
/dev/videoX
and the device can be used like a normal webcam.