Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 2593

Raspberry Pi OS • Help on UVC Gadget for Pi Zero 2 W for Webcam Simulator

$
0
0
Hi,

I am a newbie to Raspberry Pi and hardware devices, so I apologize in advance if this is a dumb question/post. I also probably overshared a lot of detail here, but I wanted to make sure there was enough info to be useful.

I am trying to create a "webcam simulator" that will show up on my mac as a webcam, but instead of streaming from a camera, it will stream from an MP4 file on the device using ffmpeg.

I have a Zero 2 W device running Raspberry Pi OS Lite (64-bit). I am using a v4l2loopback to create a device on /dev/video0 which seems to be working.

My setup code, which I cobbled together from various posts is:

Code:

#!/bin/bash# Variables we need to make things easier later on.CONFIGFS="/sys/kernel/config"GADGET="$CONFIGFS/usb_gadget"VID="0x0525"PID="0xa4a2"SERIAL="0123456789"MANUF=$(hostname)PRODUCT="UVC Gadget"BOARD=$(strings /proc/device-tree/model)UDC=`ls /sys/class/udc` # will identify the 'first' UDC# Later on, this function is used to tell the usb subsystem that we want# to support a particular format, framesize and frameintervalscreate_frame() {    # Example usage:    # create_frame <function name> <width> <height> <format> <name> <intervals>    FUNCTION=$1    WIDTH=$2    HEIGHT=$3    FORMAT=$4    NAME=$5    wdir=functions/$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p    mkdir -p $wdir    echo $WIDTH > $wdir/wWidth    echo $HEIGHT > $wdir/wHeight    echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize    cat <<EOF > $wdir/dwFrameInterval$6EOF}# This function sets up the UVC gadget function in configfs and binds us# to the UVC gadget driver.create_uvc() {    CONFIG=$1    FUNCTION=$2    echo "    Creating UVC gadget functionality : $FUNCTION"    mkdir functions/$FUNCTION    create_frame $FUNCTION 640 480 uncompressed u "333333416667500000666666100000013333332000000"    create_frame $FUNCTION 1280 720 uncompressed u "100000013333332000000"    create_frame $FUNCTION 1920 1080 uncompressed u "2000000"    create_frame $FUNCTION 640 480 mjpeg m "333333416667500000666666100000013333332000000"    create_frame $FUNCTION 1280 720 mjpeg m "333333416667500000666666100000013333332000000"    create_frame $FUNCTION 1920 1080 mjpeg m "333333416667500000666666100000013333332000000"    mkdir functions/$FUNCTION/streaming/header/h    cd functions/$FUNCTION/streaming/header/h    ln -s ../../uncompressed/u    ln -s ../../mjpeg/m    cd ../../class/fs    ln -s ../../header/h    cd ../../class/hs    ln -s ../../header/h    cd ../../class/ss    ln -s ../../header/h    cd ../../../control    mkdir header/h    ln -s header/h class/fs    ln -s header/h class/ss    cd ../../../    # This configures the USB endpoint to allow 3x 1024 byte packets per    # microframe, which gives us the maximum speed for USB 2.0. Other    # valid values are 1024 and 2048, but these will result in a lower    # supportable framerate.    echo 2048 > functions/$FUNCTION/streaming_maxpacket    ln -s functions/$FUNCTION configs/c.1}# This loads the module responsible for allowing USB Gadgets to be# configured through configfs, without which we can't connect to the# UVC gadget kernel driver########################### RDS# First, Unload existing video hardwaremodprobe -r bcm2835_v4l2modprobe -r bcm2835_codecmodprobe -r bcm2835_isp# Then load the loopback as video0modprobe v4l2loopback devices=1 video_nr=0 card_label="VirtualCam" exclusive_caps=1# Ensure that video0 is therels /dev/video*##########################echo "Loading composite module"modprobe libcomposite# This section configures the gadget through configfs. We need to# create a bunch of files and directories that describe the USB# device we want to pretend to be.if[ ! -d $GADGET/g1 ]; then    echo "Detecting platform:"    echo "  board : $BOARD"    echo "  udc   : $UDC"    echo "Creating the USB gadget"    echo "Creating gadget directory g1"    mkdir -p $GADGET/g1    cd $GADGET/g1    if[ $? -ne 0 ]; then        echo "Error creating usb gadget in configfs"        exit 1;    else        echo "OK"    fi    echo "Setting Vendor and Product ID's"    echo $VID > idVendor    echo $PID > idProduct    echo "OK"    echo "Setting English strings"    mkdir -p strings/0x409    echo $SERIAL > strings/0x409/serialnumber    echo $MANUF > strings/0x409/manufacturer    echo $PRODUCT > strings/0x409/product    echo "OK"    echo "Creating Config"    mkdir configs/c.1    mkdir configs/c.1/strings/0x409    echo "Creating functions..."    create_uvc configs/c.1 uvc.0    echo "OK"    echo "Binding USB Device Controller"    echo $UDC > UDC    echo "OK"fi
Running that script produces:

Code:

root@raspberrypi:~ # ./setup.sh/dev/video0Loading composite moduleDetecting platform:  board : Raspberry Pi Zero 2 W Rev 1.0  udc   : 3f980000.usbCreating the USB gadgetCreating gadget directory g1OKSetting Vendor and Product ID'sOKSetting English stringsOKCreating ConfigCreating functions...    Creating UVC gadget functionality : uvc.0OKBinding USB Device ControllerOK
After running the script, I can see two v4l2 devices:

Code:

root@raspberrypi:~ # v4l2-ctl --list-devices3f980000.usb (gadget.0):/dev/video1VirtualCam (platform:v4l2loopback-000):/dev/video0
However, no USB device is showing up on my Mac at that point, which is what I was expecting when it bound to the UDC.

Code:

On my mac:system_profiler SPUSBDataTypeUSB:    USB 3.1 Bus:      Host Controller Driver: AppleT6000USBXHCI    USB 3.1 Bus:      Host Controller Driver: AppleT6000USBXHCI    USB 3.1 Bus:      Host Controller Driver: AppleT6000USBXHCI
More investigation led me to believe that I need uvc-gadget to make this work.

I have downloaded and built two different uvc-gadget devices, each of which has different switches:

- https://gitlab.freedesktop.org/camera/uvc-gadget (which seems relatively new) which I built and installed as "uvc-gadget"
- https://github.com/wlhe/uvc-gadget (which appears to be older) and which I built and installed as "uvc-gadget2"

Trying to use uvc-gadget, I am getting:

Code:

root@raspberrypi:~ # uvc-gadget -d /dev/video1 uvc.0Device /dev/video1 opened: 3f980000.usb (gadget.0).v4l2 device does not support video captureroot@raspberrypi:~ # uvc-gadget -d /dev/video0 uvc.0Error: driver returned invalid frame ival type 2Error opening device /dev/video0: unable to enumerate formats.
Trying to use uvc-gadget2:

Code:

root@raspberrypi:~ # uvc-gadget2 -d /dev/video1 -u /dev/video0 -r 1 -f 1 &[1] 637root@raspberrypi:~ # uvc device is VirtualCam on bus platform:v4l2loopback-000uvc open succeeded, file descriptor = 3
It appears to work! But sadly no, still no USB device is showing up on my mac.

So... what am I doing wrong?

Any help appreciated, thanks in advance!

Statistics: Posted by meydey — Fri Nov 29, 2024 8:54 pm



Viewing all articles
Browse latest Browse all 2593