Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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

Table of Contents

Table of Contents
minLevel1
maxLevel6
outlinefalse
styledefault
typelist
printabletrue

Kernel Setup

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

Code Block
# 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“.

image-20240619-073724.png

  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”.

Code Block
#!/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

### 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.

image-20240702-031833.png

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.

image-20240702-031736.png

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.

image-20240702-024146.png

/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.

image-20240702-052542.png

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.

Code Block
./uvc-gadget -u /dev/video0 -v /dev/video1 -f0 -o1 -r0
image-20240702-054029.png

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

image-20240702-062105.pngImage Removedimage-20240801-042036.pngImage Added

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

image-20240702-063206.pngImage Removedimage-20240801-051053.pngImage Added

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

Code Block
./uvc-gadget -u /dev/video0 -v /dev/video1 -f1 -o1 -r0
image-20240702-060734.png

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

image-20240702-064230.pngImage Removedimage-20240801-051224.pngImage Added