Skip to content

Commit 886a956

Browse files
committed
samples: usb: add new UVC sample
Following the addition of USB Video Class, this adds a sample that makes use of the zephyr,camera chosen node of any board to stream the video source to the host. A snippet video-sw-generator can be used to test and debug devices without a zephyr,camera chosen node. Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent 00399b8 commit 886a956

File tree

12 files changed

+439
-1
lines changed

12 files changed

+439
-1
lines changed

doc/connectivity/usb/device/usb_device.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,8 @@ The following Product IDs are currently used:
551551
+----------------------------------------------------+--------+
552552
| :zephyr:code-sample:`uac2-implicit-feedback` | 0x000F |
553553
+----------------------------------------------------+--------+
554+
| :zephyr:code-sample:`uvc` | 0x0011 |
555+
+----------------------------------------------------+--------+
554556
| :zephyr:code-sample:`usb-dfu` (DFU Mode) | 0xFFFF |
555557
+----------------------------------------------------+--------+
556558

doc/connectivity/usb/device_next/usb_device.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Samples
3232

3333
* :zephyr:code-sample:`uac2-implicit-feedback`
3434

35+
* :zephyr:code-sample:`uvc`
36+
3537
Samples ported to new USB device support
3638
----------------------------------------
3739

@@ -223,6 +225,8 @@ instance (``n``) and is used as an argument to the :c:func:`usbd_register_class`
223225
+-----------------------------------+-------------------------+-------------------------+
224226
| Bluetooth HCI USB transport layer | :ref:`bt_hci_raw` | :samp:`bt_hci_{n}` |
225227
+-----------------------------------+-------------------------+-------------------------+
228+
| USB Video Class (UVC) | Video device | :samp:`uvc_{n}` |
229+
+-----------------------------------+-------------------------+-------------------------+
226230

227231
CDC ACM UART
228232
============

samples/subsys/usb/common/sample_usbd_init.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ static void sample_fix_code_triple(struct usbd_context *uds_ctx,
8383
IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS) ||
8484
IS_ENABLED(CONFIG_USBD_CDC_NCM_CLASS) ||
8585
IS_ENABLED(CONFIG_USBD_MIDI2_CLASS) ||
86-
IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS)) {
86+
IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS) ||
87+
IS_ENABLED(CONFIG_USBD_VIDEO_CLASS)) {
8788
/*
8889
* Class with multiple interfaces have an Interface
8990
* Association Descriptor available, use an appropriate triple

samples/subsys/usb/uvc/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(usb_video)
6+
7+
include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake)
8+
target_sources(app PRIVATE src/main.c)

samples/subsys/usb/uvc/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright The Zephyr Project Contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# Source common USB sample options used to initialize new experimental USB
5+
# device stack. The scope of these options is limited to USB samples in project
6+
# tree, you cannot use them in your own application.
7+
source "samples/subsys/usb/common/Kconfig.sample_usbd"
8+
9+
source "Kconfig.zephyr"

samples/subsys/usb/uvc/README.rst

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
.. zephyr:code-sample:: uvc
2+
:name: USB Video sample
3+
:relevant-api: usbd_api video_interface
4+
5+
Send video frames over USB.
6+
7+
Overview
8+
********
9+
10+
This sample demonstrates how to use a USB Video Class instance to
11+
send video data over USB.
12+
13+
Upon connection, a video device will show-up on the host,
14+
usable like a regular webcam device.
15+
16+
Any software on the host can then access the video stream as a local video source.
17+
18+
Requirements
19+
************
20+
21+
This sample uses the new USB device stack and requires the USB device
22+
controller ported to the :ref:`udc_api`.
23+
24+
Building and Running
25+
********************
26+
27+
If a board does not have a camera supported, the ``video-sw-generator`` snippet can be used
28+
to test without extra hardware than the USB interface, via a software-generated test pattern:
29+
30+
.. zephyr-app-commands::
31+
:zephyr-app: samples/subsys/usb/uvc
32+
:board: frdm_mcxn947/mcxn947/cpu0
33+
:snippets: video-sw-generator
34+
:goals: build flash
35+
:compact:
36+
37+
If a board is equipped with a supported image sensor configured as the ``zephyr,camera`` chosen
38+
node, then it will be used as the video source. The sample can then be built as follows:
39+
40+
.. zephyr-app-commands::
41+
:zephyr-app: samples/subsys/usb/uvc
42+
:board: arduino_nicla_vision/stm32h747xx/m7
43+
:goals: build flash
44+
:compact:
45+
46+
The device is expected to be detected as a webcam device:
47+
48+
.. tabs::
49+
50+
.. group-tab:: Ubuntu
51+
52+
The ``dmesg`` logs are expected to mention a ``generic UVC device``.
53+
54+
The ``lsusb`` is expected to show an entry for a Zephyr device.
55+
56+
Refers to `Ideas on board FAQ <https://www.ideasonboard.org/uvc/faq/>`_
57+
for how to get more debug information.
58+
59+
.. group-tab:: MacOS
60+
61+
The ``dmesg`` logs are expected to mention a video device.
62+
63+
The ``ioreg -p IOUSB`` command list the USB devices including cameras.
64+
65+
The ``system_profiler SPCameraDataType`` command list video input devices.
66+
67+
.. group-tab:: Windows
68+
69+
The Device Manager or USBView utilities permit to list the USB devices.
70+
71+
The 3rd-party USB Tree View allows to review and debug the descriptors.
72+
73+
In addition, the `USB3CV <https://www.usb.org/document-library/usb3cv>`_ tool
74+
from USB-IF can check that the device is compliant with the UVC standard.
75+
76+
Playing the Stream
77+
==================
78+
79+
The device is recognized by the system as a native webcam and can be used by any video application.
80+
81+
For instance with VLC:
82+
``Media`` > ``Open Capture Device`` > ``Capture Device`` > ``Video device name``.
83+
84+
Or with Gstreamer and FFmpeg:
85+
86+
.. tabs::
87+
88+
.. group-tab:: Ubuntu
89+
90+
Assuming ``/dev/video0`` is your Zephyr device.
91+
92+
.. code-block:: console
93+
94+
ffplay -i /dev/video0
95+
96+
.. code-block:: console
97+
98+
gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! autovideosink
99+
100+
.. group-tab:: MacOS
101+
102+
Assuming ``0:0`` is your Zephyr device.
103+
104+
.. code-block:: console
105+
106+
ffplay -f avfoundation -i 0:0
107+
108+
.. code-block:: console
109+
110+
gst-launch-1.0 avfvideosrc device-index=0 ! autovideosink
111+
112+
.. group-tab:: Windows
113+
114+
Assuming ``UVC sample`` is your Zephyr device.
115+
116+
.. code-block:: console
117+
118+
ffplay.exe -f dshow -i video="UVC sample"
119+
120+
.. code-block:: console
121+
122+
gst-launch-1.0.exe ksvideosrc device-name="UVC sample" ! videoconvert ! autovideosink
123+
124+
The video device can also be used by web and video call applications systems.
125+
126+
Android and iPad (but not yet iOS) are also expected to work via dedicated applications.
127+
128+
Accessing the Video Controls
129+
============================
130+
131+
On the host system, the controls would be available as video source
132+
control through various applications, like any webcam.
133+
134+
.. tabs::
135+
136+
.. group-tab:: Ubuntu
137+
138+
Assuming ``/dev/video0`` is your Zephyr device.
139+
140+
.. code-block:: console
141+
142+
$ v4l2-ctl --device /dev/video0 --list-ctrls
143+
144+
Camera Controls
145+
146+
auto_exposure 0x009a0901 (menu) : min=0 max=3 default=1 value=1 (Manual Mode)
147+
exposure_dynamic_framerate 0x009a0903 (bool) : default=0 value=0
148+
exposure_time_absolute 0x009a0902 (int) : min=10 max=2047 step=1 default=384 value=384 flags=inactive
149+
150+
$ v4l2-ctl --device /dev/video0 --set-ctrl auto_exposure=1
151+
$ v4l2-ctl --device /dev/video0 --set-ctrl exposure_time_absolute=1500
152+
153+
.. group-tab:: MacOS
154+
155+
The `VLC <https://www.videolan.org/vlc/>`_ client and the system Webcam Settings panel
156+
allows adjustment of the supported video controls.
157+
158+
.. group-tab:: Windows
159+
160+
The `VLC <https://www.videolan.org/vlc/>`_ client and `Pot Player <https://potplayer.tv/>`_
161+
client permit to further access the video controls.
162+
163+
Software Processing
164+
===================
165+
166+
Software processing tools can also use the video interface directly.
167+
168+
Here is an example with OpenCV (``pip install opencv-python``):
169+
170+
.. code-block:: python
171+
172+
import cv2
173+
174+
# Number of the /dev/video# interface
175+
devnum = 2
176+
177+
cv2.namedWindow("preview")
178+
vc = cv2.VideoCapture(devnum)
179+
180+
while (val := vc.read())[0]:
181+
cv2.waitKey(20)
182+
cv2.imshow("preview", val[1])
183+
184+
cv2.destroyWindow("preview")
185+
vc.release()

samples/subsys/usb/uvc/app.overlay

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright (c) 2025 tinyVision.ai Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
uvc: uvc {
9+
compatible = "zephyr,uvc-device";
10+
};
11+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Enough two 320x240 YUYV frames
2+
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=163840
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=40000
2+
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=2

samples/subsys/usb/uvc/prj.conf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CONFIG_LOG=y
2+
CONFIG_POLL=y
3+
CONFIG_VIDEO=y
4+
CONFIG_VIDEO_LOG_LEVEL_WRN=y
5+
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=2
6+
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=24576
7+
CONFIG_USB_DEVICE_STACK_NEXT=y
8+
CONFIG_UDC_BUF_POOL_SIZE=2048
9+
CONFIG_USBD_LOG_LEVEL_WRN=y
10+
CONFIG_USBD_VIDEO_CLASS=y
11+
CONFIG_USBD_VIDEO_LOG_LEVEL_WRN=y
12+
CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y
13+
CONFIG_SAMPLE_USBD_PID=0x0011
14+
CONFIG_SAMPLE_USBD_PRODUCT="UVC sample"

0 commit comments

Comments
 (0)