Skip to content

Commit 35a9324

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 2dc5790 commit 35a9324

File tree

12 files changed

+433
-1
lines changed

12 files changed

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

0 commit comments

Comments
 (0)