-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
usb: device_next: new USB Video Class (UVC) implementation #76798
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Copyright (c) 2024 tinyVision.ai Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
description: | | ||
USB Video Class instance | ||
|
||
The Video Class will present a video endpoint to interconnect with any video | ||
device. It supports multiple endpoints, each becoming its own video streaming | ||
interface to the host. | ||
|
||
The devices that are connected will receive calls to all query and configure | ||
the formats, frame intervals, video controls, and get the feed started via | ||
their video API. Some of this information is used to generate the USB device | ||
descriptors sent to the host, with the supported format and controls listed. | ||
|
||
Example for single endpoint connected to mipi0: | ||
|
||
uvc0: uvc { | ||
compatible = "zephyr,uvc-device"; | ||
port { | ||
uvc0_ep_in: endpoint { | ||
remote-endpoint-label = "mipi0_ep_out"; | ||
}; | ||
}; | ||
}; | ||
|
||
Example for multiple endpoints connected to mipi0 and mipi1: | ||
|
||
uvc0: uvc { | ||
compatible = "zephyr,uvc-device"; | ||
port { | ||
#address-cells = <1>; | ||
#size-cells = <0>; | ||
|
||
uvc0_ep0_in: endpoint@0 { | ||
reg = <0x0>; | ||
remote-endpoint-label = "mipi0_ep_out"; | ||
}; | ||
|
||
uvc0_ep1_in: endpoint@1 { | ||
reg = <0x1>; | ||
remote-endpoint-label = "mipi1_ep_out"; | ||
}; | ||
}; | ||
}; | ||
|
||
compatible: "zephyr,uvc-device" | ||
|
||
include: base.yaml | ||
|
||
on-bus: usb | ||
|
||
child-binding: | ||
child-binding: | ||
include: video-interfaces.yaml |
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) |
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" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
.. zephyr:code-sample:: uvc | ||
:name: USB Video sample | ||
:relevant-api: usbd_api video_interface | ||
|
||
USB Video sample sending frames over USB. | ||
|
||
Overview | ||
******** | ||
|
||
This sample demonstrates how to use an 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 software application to read and process video would then be able | ||
to access the stream. | ||
|
||
Requirements | ||
************ | ||
|
||
USB is the only requirement for this sensor, as an emulated image | ||
sensor and MIPI receiver is used to provide a test pattern from | ||
software. | ||
|
||
The USB descriptor configuration is extracted from these drivers, and | ||
the user does not need to provide 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: mini_stm32h734 | ||
: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 by the operating | ||
system. | ||
|
||
On Linux, OSX and BSDs this is visible using the ``dmesg`` and ``lsusb`` commands. | ||
|
||
On Windows, this is visible using the "Windows Device Manager" application. | ||
|
||
Playing the Stream | ||
================== | ||
|
||
Some example of client to open the video stream on a Linux | ||
environment, assuming ``/dev/video2`` is your Zephyr demo freshly | ||
attached. | ||
|
||
Play it using `FFplay <https://ffmpeg.org/ffplay.html>`_ | ||
|
||
.. code-block:: console | ||
|
||
ffplay /dev/video2 | ||
|
||
Play it using `GStramer <https://gstreamer.freedesktop.org/>`_: | ||
|
||
.. code-block:: console | ||
|
||
gst-launch-1.0 v4l2src device=/dev/video2 ! videoconvert ! autovideosink | ||
|
||
Play it using `MPV <https://mpv.io/>`_: | ||
|
||
.. code-block:: console | ||
|
||
mpv /dev/video2 | ||
|
||
Play it using `VLC <https://www.videolan.org/vlc/>`_: | ||
|
||
.. code-block:: console | ||
|
||
vlc v4l2:///dev/video2 | ||
|
||
The video device can also be used by web applications and video | ||
conferencing systems, as it is recognized by the system as a native | ||
webcam. | ||
|
||
On Windows, accessing the video can be done with the default "Camera" application, | ||
by switching the camera source. | ||
|
||
Android and iPad (but not yet iOS) are also expected to work via | ||
dedicated applications. | ||
|
||
Accessing the Video Controls | ||
============================ | ||
|
||
On Linux, the ``v4l2-ctl`` command permits to list the supported controls: | ||
|
||
.. code-block:: console | ||
|
||
$ v4l2-ctl --device /dev/video2 --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/video2 --set-ctrl auto_exposure=1 | ||
$ v4l2-ctl --device /dev/video2 --set-ctrl exposure_time_absolute=1500 | ||
|
||
On Windows, the `VLC <https://www.videolan.org/vlc/>`_ client and `Pot Player <https://potplayer.tv/>`_ | ||
client permit to further access the 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() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (c) 2024 tinyVision.ai Inc. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/ { | ||
imager0: emul_imager_0 { | ||
compatible = "zephyr,video-emul-imager"; | ||
|
||
port { | ||
imager0_ep_out: endpoint { | ||
remote-endpoint-label = "mipi0_ep_in"; | ||
}; | ||
}; | ||
}; | ||
|
||
mipi0: video_emul_rx_0 { | ||
compatible = "zephyr,video-emul-rx"; | ||
|
||
port { | ||
#address-cells = <1>; | ||
#size-cells = <0>; | ||
|
||
mipi0_ep_in: endpoint@0 { | ||
reg = <0x0>; | ||
remote-endpoint-label = "imager0_ep_out"; | ||
}; | ||
|
||
mipi0_ep_out: endpoint@1 { | ||
reg = <0x1>; | ||
remote-endpoint-label = "uvc_ep_in"; | ||
}; | ||
}; | ||
}; | ||
}; | ||
|
||
&zephyr_udc0 { | ||
uvc: uvc { | ||
compatible = "zephyr,uvc-device"; | ||
|
||
port { | ||
uvc_ep_in: endpoint { | ||
remote-endpoint-label = "mipi0_ep_out"; | ||
}; | ||
}; | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Temporary workaround a build-time incompatibility | ||
CONFIG_VIDEO_OV7670=n | ||
CONFIG_DMA_MCUX_SMARTDMA=n | ||
CONFIG_VIDEO_MCUX_SDMA=n | ||
CONFIG_USBD_LOG_LEVEL_DBG=y |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Switch from CDC ACM to UART | ||
CONFIG_USB_DEVICE_STACK=n | ||
CONFIG_USBD_CDC_ACM_CLASS=n | ||
CONFIG_UART_CONSOLE=y | ||
CONFIG_SERIAL=y | ||
|
||
# Avoid --- 1113 messages dropped --- when debugging | ||
CONFIG_LOG_MODE_MINIMAL=y |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright (c) 2024 tinyVision.ai Inc. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "../app.overlay" | ||
|
||
/* Do not use the CDC-ACM based logger to avoid interfering in the logs */ | ||
|
||
/ { | ||
chosen { | ||
zephyr,console = &usart3; | ||
zephyr,shell-uart = &usart3; | ||
}; | ||
}; | ||
|
||
&usb_cdc_acm_uart { | ||
status = "disabled"; | ||
}; | ||
|
||
&usart3 { | ||
pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; | ||
pinctrl-names = "default"; | ||
status = "okay"; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Switch from CDC ACM to UART | ||
CONFIG_USB_DEVICE_STACK=n | ||
CONFIG_USBD_CDC_ACM_CLASS=n | ||
CONFIG_UART_CONSOLE=y | ||
CONFIG_SERIAL=y |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Copyright (c) 2024 tinyVision.ai Inc. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "../app.overlay" | ||
|
||
/* Do not use the CDC-ACM based logger to avoid interfering in the logs */ | ||
|
||
/ { | ||
chosen { | ||
zephyr,console = &uart0; | ||
zephyr,shell-uart = &uart0; | ||
}; | ||
}; | ||
|
||
&cdc_acm_uart { | ||
status = "disabled"; | ||
}; | ||
|
||
&uart0 { | ||
status = "okay"; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
CONFIG_LOG=y | ||
CONFIG_LOG_MODE_MINIMAL=y | ||
CONFIG_VIDEO=y | ||
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=4 | ||
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=7300 | ||
CONFIG_VIDEO_EMUL_IMAGER=y | ||
CONFIG_VIDEO_EMUL_RX=y | ||
CONFIG_VIDEO_LOG_LEVEL_DBG=y | ||
CONFIG_USB_DEVICE_STACK=n | ||
CONFIG_USB_DEVICE_STACK_NEXT=y | ||
CONFIG_USBD_VIDEO_CLASS=y | ||
CONFIG_USBD_VIDEO_LOG_LEVEL_DBG=y | ||
CONFIG_SAMPLE_USBD_PID=0x000B | ||
CONFIG_SAMPLE_USBD_PRODUCT="UVC sample" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
sample: | ||
name: USB Video sample | ||
tests: | ||
sample.subsys.usb.uvc: | ||
depends_on: | ||
- usbd | ||
- video | ||
tags: usb video | ||
platform_allow: | ||
- nrf52840dongle | ||
- mini_stm32h743 | ||
- rpi_pico | ||
harness: TBD | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TBD ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TBD for "To Be Done", TODO would have been more conventional... I need to add a proper test harness for this sample. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nordic ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a Kconfig copy-pasted from Nordic unchanged:
zephyr/samples/subsys/usb/uac2_implicit_feedback/Kconfig
Lines 1 to 9 in 1baf93b