1

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/bash
GADGET_NAME=virtcam
GADGET_ROOT=/sys/kernel/config/usb_gadget/$GADGET_NAME
mkdir $GADGET_ROOT
cd $GADGET_ROOT
echo 0x1d6b > idVendor
echo 0x0104 > idProduct
echo 0x0100 > bcdDevice
echo 0x0200 > bcdUSB
echo 0xEF > bDeviceClass
echo 0x02 > bDeviceSubClass
echo 0x01 > bDeviceProtocol
mkdir strings/0x409
cd strings/0x409
echo 100000000d2386db > serialnumber
echo "Samsung" > manufacturer
echo "Webcam" > product
cd $GADGET_ROOT
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
cd configs/c.1/strings/0x409
echo "UVC" > configuration
cd $GADGET_ROOT/configs/c.1
echo 500 > MaxPower
cd $GADGET_ROOT
mkdir functions/uvc.usb0
cd functions/uvc.usb0
echo 2048 > streaming_maxpacket
mkdir control/header/h
cd control
ln -s header/h class/fs
ln -s header/h class/ss
cd $GADGET_ROOT/functions/uvc.usb0/streaming/uncompressed
mkdir -p u/720p
cd u/720p
cat <<EOF > dwFrameInterval
666666
1000000
5000000
EOF
cat <<EOF > wWidth
1280
EOF
cat <<EOF > wHeight
720
EOF
cat <<EOF > dwMinBitRate
29491200
EOF
cat <<EOF > dwMaxBitRate
29491200
EOF
cat <<EOF > dwMaxVideoFrameBufferSize
1843200
EOF
mkdir $GADGET_ROOT/functions/uvc.usb0/streaming/header/h
cd $GADGET_ROOT/functions/uvc.usb0/streaming
ln -s uncompressed/u header/h
ln -s header/h class/fs
ln -s header/h class/hs
ln -s header/h class/ss
cd $GADGET_ROOT
ln -s functions/uvc.usb0 configs/c.1/uvc.usb0
# ln -s functions/acm.usb0 configs/c.1/acm.usb0
udevadm 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_ROOT
echo "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?

winwin
  • 141
  • 4

0 Answers0