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
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“.
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“.
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“.
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.
./uvc-gadget -u /dev/video0 -v /dev/video1 -f1 -o1 -r0
In Windows PC, a multimedia player PotPlayer is used to play the videos from the uvc gadget.