This chapter introduces the GK7206 UVC (USB Video Class) webcam sample, uvc_app. It shows how to present the board to a host as a USB camera, so the host can access the video stream over USB.
The source lives in sample/uvc_app/ in the SDK and serves as a reference template for USB camera work.
| Parameter | Value |
|---|---|
USB interface |
USB 2.0 Device |
Video format |
MJPEG |
Resolution |
640x480, 320x240, etc. |
Frame rate |
30 FPS |
Dependency |
USB connection to a host; sensor |
sample/uvc_app/
├── Makefile # build script
├── ConfigUVC.sh # UVC configuration script
├── application.c # main program
└── uvc_gadget.c # UVC gadget implementation
Before building this application, make sure the following are ready:
# enter the sample directory
cd <SDK_PATH>/sample
# build the uvc_app sample
make -C uvc_app clean && make -C uvc_app
# transfer to the board over SCP
scp sample/uvc_app/application root@<board-IP>:/sd_card/
scp sample/uvc_app/ConfigUVC.sh root@<board-IP>:/sd_card/
# make it executable
chmod +x /sd_card/application
chmod +x /sd_card/ConfigUVC.sh
# enter the SD card directory
cd /sd_card
# configure the UVC gadget
sh ConfigUVC.sh
# run the application
./application
# or set the log level explicitly
./application 1
# view the camera with guvcview
guvcview /dev/video0
# or use ffmpeg
ffmpeg -f v4l2 -i /dev/video0 -f sdl output
After a successful start the terminal prints output like this:
uvc application running
configfs gadget setup complete
USB gadget connected
streaming started...
The host then shows the live camera image.
This application uses the following architecture:
Sensor -> VI -> VPSS -> VENC(MJPEG) -> USB Gadget -> host
// Step 1: configure the USB gadget
system("sh ConfigUVC.sh");
// Step 2: initialize the video pipeline
sample_comm_sys_init(&sys_config);
sample_comm_isp_init();
sample_comm_vi_start(...);
sample_comm_vpss_start(...);
sample_comm_venc_start(...);
// Step 3: initialize the UVC gadget
uvc_gadget_init();
// Step 4: start pushing the video stream
uvc_gadget_start_streaming();
// Step 5: push frames in a loop
while (running) {
xmedia_venc_get_stream(venc_chn, &stream, -1);
uvc_gadget_send_frame(&stream);
xmedia_venc_release_stream(venc_chn, &stream);
}
// Step 6: release resources
uvc_gadget_stop_streaming();
uvc_gadget_exit();
sample_comm_venc_stop(...);
The ConfigUVC.sh script configures the USB gadget:
#!/bin/sh
# load the USB gadget driver
modprobe libcomposite
# configure configfs
cd /sys/kernel/config/usb_gadget
mkdir g1
cd g1
# set the device information
echo 0x1d6b > idVendor
echo 0x0104 > idProduct
echo "GK7206 UVC" > product
# create the configuration
mkdir configs/c.1
cd configs/c.1
echo 250 > MaxPower
# create the UVC function
cd ../../
mkdir functions/uvc.usb0
cd functions/uvc.usb0
# link the configuration to the function
ln -s configs/c.1 functions/uvc.usb0
# enable the gadget
echo "$(ls /sys/class/udc)" > UDC
xmedia_venc_chn_attr_t venc_chn_attr;
venc_chn_attr.type = XMEDIA_PT_MJPEG;
venc_chn_attr.max_width = 640;
venc_chn_attr.max_height = 480;
venc_chn_attr.rc_mode = VENC_RC_MODE_MJPEGCBR;
xmedia_venc_create_chn(venc_chn, &venc_chn_attr);
// get a frame from VENC
xmedia_venc_get_stream(venc_chn, &stream, -1);
// send the frame over USB
uvc_gadget_send_frame(stream.pack[0].vir_addr, stream.pack[0].len);
// release the frame
xmedia_venc_release_stream(venc_chn, &stream);
| Problem | Likely cause | Fix |
|---|---|---|
| Host does not detect the USB device | USB gadget configuration failed | Check that ConfigUVC.sh ran correctly |
| Host detects it but there is no stream | Video pipeline failed to initialize | Check the sensor and the VI/VPSS/VENC configuration |
| Stream stutters | Not enough USB bandwidth | Lower the resolution or frame rate |
| Wrong colors | Wrong MJPEG encoding parameters | Check the VENC configuration |