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:
Running that script produces:After running the script, I can see two v4l2 devices: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.
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:Trying to use uvc-gadget2: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!
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
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
Code:
root@raspberrypi:~ # v4l2-ctl --list-devices3f980000.usb (gadget.0):/dev/video1VirtualCam (platform:v4l2loopback-000):/dev/video0
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
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.
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
So... what am I doing wrong?
Any help appreciated, thanks in advance!
Statistics: Posted by meydey — Fri Nov 29, 2024 8:54 pm — Replies 0 — Views 22