Skip to content

Commit

Permalink
samples: usb: add new UVC sample
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
josuah committed Feb 12, 2025
1 parent 7753a49 commit 8c93fd9
Show file tree
Hide file tree
Showing 14 changed files with 462 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ supported:
- gpio
- spi
- i2c
- usbd
vendor: arduino
2 changes: 2 additions & 0 deletions doc/connectivity/usb/device/usb_device.rst
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,8 @@ The following Product IDs are currently used:
+----------------------------------------------------+--------+
| :zephyr:code-sample:`uac2-implicit-feedback` | 0x000F |
+----------------------------------------------------+--------+
| :zephyr:code-sample:`uvc` | 0x0011 |
+----------------------------------------------------+--------+
| :zephyr:code-sample:`usb-dfu` (DFU Mode) | 0xFFFF |
+----------------------------------------------------+--------+

Expand Down
4 changes: 4 additions & 0 deletions doc/connectivity/usb/device_next/usb_device.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Samples

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

* :zephyr:code-sample:`uvc`

Samples ported to new USB device support
----------------------------------------

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

CDC ACM UART
============
Expand Down
3 changes: 2 additions & 1 deletion samples/subsys/usb/common/sample_usbd_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ static void sample_fix_code_triple(struct usbd_context *uds_ctx,
IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS) ||
IS_ENABLED(CONFIG_USBD_CDC_NCM_CLASS) ||
IS_ENABLED(CONFIG_USBD_MIDI2_CLASS) ||
IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS)) {
IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS) ||
IS_ENABLED(CONFIG_USBD_VIDEO_CLASS)) {
/*
* Class with multiple interfaces have an Interface
* Association Descriptor available, use an appropriate triple
Expand Down
8 changes: 8 additions & 0 deletions samples/subsys/usb/uvc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(usb_video)

include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake)
target_sources(app PRIVATE src/main.c)
9 changes: 9 additions & 0 deletions samples/subsys/usb/uvc/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

# Source common USB sample options used to initialize new experimental USB
# device stack. The scope of these options is limited to USB samples in project
# tree, you cannot use them in your own application.
source "samples/subsys/usb/common/Kconfig.sample_usbd"

source "Kconfig.zephyr"
193 changes: 193 additions & 0 deletions samples/subsys/usb/uvc/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
.. zephyr:code-sample:: uvc
:name: USB Video sample
:relevant-api: usbd_api video_interface

Send video frames over USB.

Overview
********

This sample demonstrates how to use a USB Video Class instance to
send video data over USB.

Upon connection, a video interface would show-up in the operating system,
using the same protocol as most webcams, and be detected as such.

Any host-side video processing software would then be able to access the
video streams.

Requirements
************

The requirements for this sample is an USB driver using the latest
``device_next`` API.

If a ``zephyr,camera`` node is chosen for the board, it will be used as source.
If not, this sample can be built using this command to use an emulated video source:

.. code-block:: console
west build -b <board> -- -DEXTRA_DTC_OVERLAY_FILE=video-emul.overlay
The USB descriptors are generated from the video API, and the user does not need
to configure them.

Building and Running
********************

Build the sample application and flash the resulting binaries.

.. zephyr-app-commands::
:zephyr-app: samples/subsys/usb/uvc
:board: nrf52840dongle
:goals: build flash
:compact:

.. zephyr-app-commands::
:zephyr-app: samples/subsys/usb/uvc
:board: rpi_pico
:goals: build flash
:compact:

Upon reboot, the device is expected to be detected as a webcam device:

.. tabs::

.. group-tab:: Ubuntu

The ``dmesg`` logs are expected to mention a ``generic UVC device``.

The ``lsusb`` is expected to show an entry for a Zephyr device.

Refers to `Ideas on board FAQ <https://www.ideasonboard.org/uvc/faq/>`_
for how to get more debug information.

.. group-tab:: MacOS

The ``dmesg`` logs are expected to mention a video device.

The ``ioreg -p IOUSB`` command list the USB devices including cameras.

The ``system_profiler SPCameraDataType`` command list video input devices.

.. group-tab:: Windows

The Device Manager or USBView utilities permit to list the USB devices.

The 3rd-party USB Tree View allows to review and debug the descriptors.

In addition, the `USB3CV <https://www.usb.org/document-library/usb3cv>`_ tool
from USB-IF can check that the device is compliant with the UVC standard.


Playing the Stream
==================

The device is recognized by the system as a native webcam and can be used by any video application.

For instance with VLC:
``Media`` > ``Open Capture Device`` > ``Capture Device`` > ``Video device name``.

Or with Gstreamer and FFmpeg:

.. tabs::

.. group-tab:: Ubuntu

Assuming ``/dev/video0`` is your Zephyr device.

.. code-block:: console
ffplay -i /dev/video0
.. code-block:: console
gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! autovideosink
.. group-tab:: MacOS

Assuming ``0:0`` is your Zephyr device.

.. code-block:: console
ffplay -f avfoundation -i 0:0
.. code-block:: console
gst-launch-1.0 avfvideosrc device-index=0 ! autovideosink
.. group-tab:: Windows

Assuming ``UVC sample`` is your Zephyr device.

.. code-block:: console
ffplay.exe -f dshow -i video="UVC sample"
.. code-block:: console
gst-launch-1.0.exe ksvideosrc device-name="UVC sample" ! videoconvert ! autovideosink
The video device can also be used by web and video call applications systems.

Android and iPad (but not yet iOS) are also expected to work via dedicated applications.

Accessing the Video Controls
============================

On the host system, the controls would be available as video source
control through various applications, like any webcam.

.. tabs::

.. group-tab:: Ubuntu

Assuming ``/dev/video0`` is your Zephyr device.

.. code-block:: console
$ v4l2-ctl --device /dev/video0 --list-ctrls
Camera Controls
auto_exposure 0x009a0901 (menu) : min=0 max=3 default=1 value=1 (Manual Mode)
exposure_dynamic_framerate 0x009a0903 (bool) : default=0 value=0
exposure_time_absolute 0x009a0902 (int) : min=10 max=2047 step=1 default=384 value=384 flags=inactive
$ v4l2-ctl --device /dev/video0 --set-ctrl auto_exposure=1
$ v4l2-ctl --device /dev/video0 --set-ctrl exposure_time_absolute=1500
.. group-tab:: Windows

The `VLC <https://www.videolan.org/vlc/>`_ client and `Pot Player <https://potplayer.tv/>`_
client permit to further access the video controls.

.. group-tab:: MacOS

The `VLC <https://www.videolan.org/vlc/>`_ client and the system Webcam Settings panel
allows adjustment of the supported video controls.


Software Processing
===================

Software processing tools can also use the video interface directly.

Here is an example with OpenCV:

.. code-block:: python
import cv2
# Number of the /dev/video# interface
devnum = 2
cv2.namedWindow("preview")
vc = cv2.VideoCapture(devnum)
while (val := vc.read())[0]:
cv2.waitKey(20)
cv2.imshow("preview", val[1])
cv2.destroyWindow("preview")
vc.release()
11 changes: 11 additions & 0 deletions samples/subsys/usb/uvc/app.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) 2025 tinyVision.ai Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
uvc: uvc {
compatible = "zephyr,uvc-device";
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright (c) 2025 tinyVision.ai Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "../app.overlay"
#include "../video-dcmi.overlay"
12 changes: 12 additions & 0 deletions samples/subsys/usb/uvc/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CONFIG_LOG=y
CONFIG_VIDEO=y
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=4
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=7300
CONFIG_VIDEO_LOG_LEVEL_WRN=y
CONFIG_USB_DEVICE_STACK_NEXT=y
CONFIG_USBD_LOG_LEVEL_WRN=y
CONFIG_USBD_VIDEO_CLASS=y
CONFIG_USBD_VIDEO_LOG_LEVEL_DBG=y
CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y
CONFIG_SAMPLE_USBD_PID=0x0011
CONFIG_SAMPLE_USBD_PRODUCT="UVC sample"
17 changes: 17 additions & 0 deletions samples/subsys/usb/uvc/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
sample:
name: USB Video sample
tests:
sample.subsys.usb.uvc:
depends_on:
- usbd
tags: usb
integration_platforms:
- nrf52840dk/nrf52840
- nrf54h20dk/nrf54h20/cpuapp
- frdm_k64f
- stm32f723e_disco
- nucleo_f413zh
- mimxrt685_evk/mimxrt685s/cm33
- mimxrt1060_evk/mimxrt1062/qspi
extra_args:
- EXTRA_DTC_OVERLAY_FILE="video-emul.overlay"
Loading

0 comments on commit 8c93fd9

Please sign in to comment.