Skip to content

Commit 0230764

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 fallback video-emul.overlay is provided for test and debugging purpose for devices without a camera. Signed-off-by: Josuah Demangeon <[email protected]>
1 parent f33cf06 commit 0230764

File tree

11 files changed

+385
-1
lines changed

11 files changed

+385
-1
lines changed

doc/connectivity/usb/device/usb_device.rst

+2
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,8 @@ The following Product IDs are currently used:
604604
+----------------------------------------------------+--------+
605605
| :zephyr:code-sample:`uac2-implicit-feedback` | 0x000F |
606606
+----------------------------------------------------+--------+
607+
| :zephyr:code-sample:`uvc` | 0x0011 |
608+
+----------------------------------------------------+--------+
607609
| :zephyr:code-sample:`usb-dfu` (DFU Mode) | 0xFFFF |
608610
+----------------------------------------------------+--------+
609611

doc/connectivity/usb/device_next/usb_device.rst

+4
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

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ static void sample_fix_code_triple(struct usbd_context *uds_ctx,
8181
IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS) ||
8282
IS_ENABLED(CONFIG_USBD_CDC_NCM_CLASS) ||
8383
IS_ENABLED(CONFIG_USBD_MIDI2_CLASS) ||
84-
IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS)) {
84+
IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS) ||
85+
IS_ENABLED(CONFIG_USBD_VIDEO_CLASS)) {
8586
/*
8687
* Class with multiple interfaces have an Interface
8788
* Association Descriptor available, use an appropriate triple

samples/subsys/usb/uvc/CMakeLists.txt

+8
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

+9
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

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

samples/subsys/usb/uvc/app.overlay

+11
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+
};
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

samples/subsys/usb/uvc/prj.conf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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_USBD_LOG_LEVEL_WRN=y
9+
CONFIG_USBD_VIDEO_CLASS=y
10+
CONFIG_USBD_VIDEO_LOG_LEVEL_WRN=y
11+
CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y
12+
CONFIG_SAMPLE_USBD_PID=0x0011
13+
CONFIG_SAMPLE_USBD_PRODUCT="UVC sample"

samples/subsys/usb/uvc/sample.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
sample:
2+
name: USB Video sample
3+
tests:
4+
sample.subsys.usb.uvc.camera:
5+
depends_on:
6+
- usbd
7+
tags: usb video
8+
filter: dt_chosen_enabled("zephyr,camera")
9+
integration_platforms:
10+
- arduino_nicla_vision/stm32h747xx/m7

0 commit comments

Comments
 (0)