I've been trying to create a loopback USB Webcam device with the help of dummy_hcd
kernel module. Steps I've taken:
I load libcomposite
via modprobe libcomposite
.
Then I load dummy_hcd
via modprobe dummy_hcd
. This creates a software-emulated UDC chip. More on that I've found here.
Then I use a script to create and configure the USB webcam device. I've based my script on this and this. Here it is:
#!/bin/bashGADGET_NAME=virtcamGADGET_ROOT=/sys/kernel/config/usb_gadget/$GADGET_NAMEmkdir $GADGET_ROOTcd $GADGET_ROOTecho 0x1d6b > idVendorecho 0x0104 > idProductecho 0x0100 > bcdDeviceecho 0x0200 > bcdUSBecho 0xEF > bDeviceClassecho 0x02 > bDeviceSubClassecho 0x01 > bDeviceProtocolmkdir strings/0x409cd strings/0x409echo 100000000d2386db > serialnumberecho "Samsung" > manufacturerecho "Webcam" > productcd $GADGET_ROOTmkdir configs/c.1mkdir configs/c.1/strings/0x409cd configs/c.1/strings/0x409echo "UVC" > configurationcd $GADGET_ROOT/configs/c.1echo 500 > MaxPowercd $GADGET_ROOTmkdir functions/uvc.usb0cd functions/uvc.usb0echo 2048 > streaming_maxpacketmkdir control/header/hcd controlln -s header/h class/fsln -s header/h class/sscd $GADGET_ROOT/functions/uvc.usb0/streaming/uncompressedmkdir -p u/720pcd u/720pcat <<EOF > dwFrameInterval66666610000005000000EOFcat <<EOF > wWidth1280EOFcat <<EOF > wHeight720EOFcat <<EOF > dwMinBitRate29491200EOFcat <<EOF > dwMaxBitRate29491200EOFcat <<EOF > dwMaxVideoFrameBufferSize1843200EOFmkdir $GADGET_ROOT/functions/uvc.usb0/streaming/header/hcd $GADGET_ROOT/functions/uvc.usb0/streamingln -s uncompressed/u header/hln -s header/h class/fsln -s header/h class/hsln -s header/h class/sscd $GADGET_ROOTln -s functions/uvc.usb0 configs/c.1/uvc.usb0# ln -s functions/acm.usb0 configs/c.1/acm.usb0udevadm settle -t 5 || :
The script completes without errors on both machines I've tested (5.15.16-1-MANJARO
and raspberrypi 5.10.94-v7+
), but then when I actually do try to connect the created USB device to the dummy UDC, it errors out.
cd $GADGET_ROOTecho "dummy_udc.0" > UDC# it returns 'bash: echo: write error: Invalid argument'
It basically means that this device cannot be connected to this UDC chip. When I dmesg -Tw
, I get the following:
[Fri Feb 4 00:00:00 2022] configfs-gadget gadget: uvc: uvc_function_bind()[Fri Feb 4 00:00:00 2022] configfs-gadget gadget: uvc: Unable to allocate streaming EP[Fri Feb 4 00:00:00 2022] configfs-gadget dummy_udc.0: failed to start virtcam: -22
Error is the same on both devices, so it's not device specific. So I had to hit google with this error. I've found this thread, where a guy says:
I know it's late, but just for anyone else that tries to use g_webcam or the uvc configfs with dummy_hcd ... UVC functions use isochronous transfers, so it won't work.
And, in fact, if we look at the source code, it says in the comments:
Note: The emulation does not include isochronous transfers!
So I'm basically really stuck. It turns out that dummy_hcd
doesn't support isochrounous transfers, but webcams seem to use them, so it's either buy a hardware UDC chip (or some device which has it) or find a way around.
Is there really no way to create a fully virtual loopback webcam on Linux? Do webcams really require isochronous transfer to work?
Is there a way to run it someway without writing kernel modifications of dummy_hcd.c
? Or should I just buy hardware hoping it works?