|
| 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() |
0 commit comments