How to create a virtual UVC device to stream video as webcam

This article demonstrates how to create a virtual UVC device to stream video as webcam on SP7350 platforms.

 

Table of Contents

Kernel Setup

Enter the kernel configuration by running the following command in the top directory of project.

# make kconfig

 

  1. If USB 2.0 device controller is selected for the uvc gadget, select submenus for USB 2.0 controller : Device Drivers > USB support > USB Gadget Support > USB Peripheral Controller. Select <*> for “Sunplus USB 2.0 Device Controller“.

image-20240628-071046.png

 

  1. If USB 3.0 device controller is selected for the uvc gadget, select submenus for USB 3.0 controller : Device Drivers > USB support. Select <*> for “DesignWare USB3 DRD Core Support“ and select “Dual Role mode“ for “DWC3 Mode Selection“.

image-20240628-071240.png

 

  1. Select submenus for USB Gadget configfs : Device Drivers > USB support > USB Gadget Support. Select <M> for “USB Gadget functions configurable through configfs“. Select [*] for “USB Webcam function“.

 

  1. Execute the make command to build the Linux image.

ConfigFS

Configure uvc gadget through configfs saved as a file named setup_uvc shown below.

For USB 2.0 uvc gadget, UDC_NAME=”f8102800.usb”.

For USB 3.0 uvc gadget, UDC_NAME=”f80a1000.dwc3”.

#!/bin/sh CONFIGFS_HOME=/sys/kernel/config VID=0xabcd PID=0x1234 serial_number="myserial" manufacturer="mymfg" product="myproduct" name="c" number="1" configuration="" maxpower="120" ### UVC gadget function CONFIG="configs/$name.$number" # FUNCTION="<name>.<instance name>" # where <name> corresponds to one of allowed function names and instance name is an arbitrary string allowed in a filesystem FUNCTION="uvc.0" STREAM_MAXPACKET="2048" # where <udc name> is one of those found in /sys/class/udc/* UDC_NAME="f8102800.usb" # UDC_NAME="f80a1000.dwc3" # load libcomposite module modprobe libcomposite # disable debug message echo 0 > /sys/module/sunplus_udc/parameters/dmsg ### 1. Create a gadget ### mount -t configfs none $CONFIGFS_HOME mkdir -p $CONFIGFS_HOME/usb_gadget/g1 # cd to its configfs node cd $CONFIGFS_HOME/usb_gadget/g1 # Each gadget needs to have its vendor id <VID> and product id <PID> specified: # configure it (vid/pid can be anything if USB Class is used for driver compat) echo $VID > idVendor echo $PID > idProduct # A gadget also needs its serial number, manufacturer and product strings # In order to have a place to store them, a strings subdirectory must be createdfor each language # Create English string mkdir -p strings/0x409 # Then the strings can be specified(configure its serial/mfg/product): echo $serial_number > strings/0x409/serialnumber echo $manufacturer > strings/0x409/manufacturer echo $product > strings/0x409/product ### 2. Creating the configurations ### # Each gadget will consist of a number of configurations, their corresponding directories must be created: # where <name> can be any string which is legal in a filesystem and the <number> is the configuration's number mkdir -p configs/$name.$number # Each configuration also needs its strings, so a subdirectory must be created for each language. mkdir -p configs/$name.$number/strings/0x409 # Then the configuration string can be specified: # echo $configuration > configs/c.1/strings/0x409/configuration # Some attributes can also be set for a configuration, e.g.: # echo $maxpower > configs/$name.$number/MaxPower ### 3. Creating the functions ### # The gadget will provide some functions, for each function its corresponding directory must be created: # Create UVC gadget function mkdir -p functions/$FUNCTION # Each function provides its specific set of attributes, with either read-only or read-write access. # Where applicable they need to be written to as appropriate. create_function() { # Example usage: # create_function <width> <height> <format> <name> WIDTH=$1 HEIGHT=$2 FORMAT=$3 NAME=$4 wdir=functions/$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p mkdir -p $wdir echo $WIDTH > $wdir/wWidth echo $HEIGHT > $wdir/wHeight echo 29491200 > $wdir/dwMinBitRate echo 29491200 > $wdir/dwMaxBitRate echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize # dwFrameInterfal is in 100-ns units (fps = 1/(dwFrameInterval * 10000000)) # 333333 -> 30 fps # 666666 -> 15 fps # 5000000 -> 2 fps cat <<EOF > $wdir/dwFrameInterval 333333 666666 5000000 EOF } # YUY2 resolution create_function 640 360 uncompressed u create_function 640 480 uncompressed u create_function 1280 720 uncompressed u # MJPEG resolution create_function 640 360 mjpeg m create_function 640 480 mjpeg m create_function 1280 720 mjpeg m # Create header mkdir -p 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 -p header/h ln -s header/h class/fs ln -s header/h class/ss cd ../../../ # Configure max packet size echo $STREAM_MAXPACKET > functions/$FUNCTION/streaming_maxpacket ### 4. Associating the functions with theireirthe functions with theirheir eir configurations # At this moment a number of gadgets is created, each of which has a number of # configurations specified and a number of functions available. What remains # is specifying which function is available in which configuration (the same # function can be used in multiple configurations). This is achieved with # creating symbolic links: # Assign configuration to function ln -s functions/$FUNCTION configs/$name.$number ### 5. Enabling the gadget # In order to enable the gadget it must be bound to a UDC (USB Device Controller). # Bind USB Device Controller (UDC) echo $UDC_NAME > UDC

 

Userspace Application

The UVC gadget userspace enhancement sample application (uvc-gadget) is adapted for UVC gadget test and it is available on the website https://github.com/wlhe/uvc-gadget.

UVC Gadget Test

When USB 2.0 device controller is configured as the uvc gadget, an USB webcam will be connected to the USB 3.0 port for the test.

 

When USB 3.0 device controller is configured as the uvc gadget, an USB webcam will be connected to the USB 2.0 port for the test.

 

After updating the image to the platform and booting the system, use sh setup_uvc command to configure USB 2.0 or USB 3.0 device controllers as uvc gadgets.

 

/dev/video0 is the device file representing the uvc gadget. After connecting an USB webcam to the USB 2.0 / USB 3.0 port, /dev/video1 is the device file representing it.

 

After connecting the SP7350 board to a Windows PC through an USB cable, use the following command to be ready to capture videos from the USB webcam with the format of 640x360 YUY2.

./uvc-gadget -u /dev/video0 -v /dev/video1 -f0 -o1 -r0

 

In Device Manager of the Windows PC, UVC Camera will show up in Cameras.

 

In Windows PC, a multimedia player PotPlayer is used to play the videos from the uvc gadget.

 

Use the following command to be ready to capture videos from the USB webcam with the format of 640x360 MJPEG.

 

In Windows PC, a multimedia player PotPlayer is used to play the videos from the uvc gadget.