Skip to content

Commit 71ff031

Browse files
committed
Merge branch 'main' into dev
2 parents 01030fc + 622938f commit 71ff031

File tree

4 files changed

+202
-0
lines changed

4 files changed

+202
-0
lines changed

docs/doc/en/sidebar.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ items:
120120
label: RTSP streaming
121121
- file: video/rtmp_streaming.md
122122
label: RTMP streaming
123+
- file: video/uvc_streaming.md
124+
label: UVC streaming
123125

124126
- label: Network
125127
items:

docs/doc/en/video/uvc_streaming.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
title: MaixCAM MaixPy Video Streaming UVC Streaming / As a UVC camera to display custom image
3+
update:
4+
- date: 2024-12-20
5+
author: taorye
6+
version: 1.0.0
7+
content: 初版文档
8+
---
9+
10+
## Introduction
11+
12+
`MaixCAM` as a `UVC camera`, where `UVC` stands for `USB video(device) class`.
13+
14+
Here, two methods are provided to display custom content:
15+
16+
- Refresh the target image using the `show` method of `maix.uvc.UvcStreamer` (supports YUYV and MJPEG).
17+
- Refresh the target image by registering a custom image refresh callback function with `maix.uvc.UvcServer` (only supports MJPEG). Much more complex than the method above.
18+
19+
20+
## Example
21+
22+
**First, you need to enable the `UVC` function in the `USB settings` section of the `Settings` app.**
23+
24+
**Note:**
25+
Once the `UVC` function is enabled, due to Linux's implementation of the `UVC Gadget`, a user program is still required to handle `UVC` device events.
26+
Otherwise, the entire `USB` functionality will pause and wait, affecting other simultaneously enabled `Gadget` features like `Rndis` and `NCM`, which may cause network disconnection.
27+
Therefore, for users who also need other `USB` functionalities, it is recommended to use the `UvcStreamer` method when developing UVC display functionality based on `MaixPy`.
28+
Otherwise, ensure that the `MaixCAM` device has other network access methods, such as `WIFI`, to ensure proper development and debugging.
29+
30+
31+
### UvcStreamer
32+
33+
This method does not affect normal USB functionality. The underlying principle is to split the task into two processes. The official implementation uses a `server` process to handle `UVC` device events and encapsulates an easy-to-use, unified image refresh interface `show(img)` for users. You can treat it as a simple `display` linear logic operation.
34+
35+
**Reference example source code path:**
36+
`MaixPy/examples/vision/streaming/uvc_stream.py`
37+
38+
### **Example Source (Usage Instructions):**
39+
40+
1. **Initialize the UvcStreamer object**
41+
42+
```python
43+
uvcs = uvc.UvcStreamer()
44+
```
45+
46+
- (Optional) Switch to MJPEG streaming mode (YUYV default)
47+
48+
```python
49+
uvcs.use_mjpg(1)
50+
```
51+
52+
2. Refresh the image (automatically handles the format, medium performance loss for MJPEG, and high loss for YUYV)
53+
54+
```python
55+
uvcs.show(img)
56+
```
57+
58+
### UvcServer
59+
60+
This approach offers high performance with a single-process implementation, but USB functionality will only be available when the process is running. Therefore, when stopping this process, it's important to note that the enabled `Rndis` and `NCM` functionalities will temporarily become inactive, causing a network disconnection.
61+
62+
**Reference example source code path:**
63+
`MaixPy/examples/vision/streaming/uvc_stream.py`
64+
65+
**Also packaged as an app source code path:**
66+
`MaixCDK/projects/app_uvc_camera/main/src/main.cpp`
67+
68+
### **Example Source (Usage Instructions):**
69+
70+
1. **Initialize the UvcServer object (requires a callback function for image refresh)**
71+
72+
A helper function `helper_fill_mjpg_image` is provided to assist in placing more general `Image` objects into the `UVC` buffer.
73+
74+
```python
75+
cam = camera.Camera(640, 360, fps=60) # Manually set resolution
76+
# | 手动设置分辨率
77+
78+
def fill_mjpg_img_cb(buf, size):
79+
img = cam.read()
80+
return uvc.helper_fill_mjpg_image(buf, size, img)
81+
82+
uvcs = uvc.UvcServer(fill_mjpg_img_cb)
83+
```
84+
The reference implementation will `fill_mjpg_img_cb` only trigger a buffer refresh when it returns `0`.
85+
Therefore, it is recommended to use the helper function in the last line:
86+
`return uvc.helper_fill_mjpg_image(buf, size, img)`
87+
88+
2. Start the UVC, which launches a background thread, non-blocking operation:
89+
90+
```python
91+
uvcs.run()
92+
```
93+
94+
3. Stop the UVC when it's no longer needed. This will restore the background process from the `UvcStreamer` method implementation to ensure normal USB functionality.
95+
96+
Currently, there is a **BUG** in the MaixPy framework where it forcibly terminates processes upon exit, preventing the functions after the `while not app.need_exit():` loop from being executed, meaning the `stop()` method may not run as expected.
97+
Therefore, for users who require **normal USB functionality**, it is recommended to switch to the `UvcStreamer` method or use the original C++ API from **MaixCDK**.
98+
99+
**Reference example:**
100+
`MaixCDK/examples/uvc_demo/main/src/main.cpp`
101+
102+
```python
103+
uvcs.stop()
104+
```

docs/doc/zh/sidebar.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ items:
121121
label: RTSP 串流
122122
- file: video/rtmp_streaming.md
123123
label: RTMP 串流
124+
- file: video/uvc_streaming.md
125+
label: UVC 串流
124126

125127
- label: 网络通信
126128
items:

docs/doc/zh/video/uvc_streaming.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
---
2+
title: MaixCAM MaixPy 视频流 UVC 推流 / 化身 UVC 摄像头显示自定义内容
3+
update:
4+
- date: 2024-12-20
5+
author: taorye
6+
version: 1.0.0
7+
content: 初版文档
8+
---
9+
10+
## 简介
11+
12+
`MaixCAM` 化身 `UVC 摄像头`, `UVC` 全称为:USB video(device) class,这里提供两种方法供显示自定义内容:
13+
14+
- 通过 `maix.uvc.UvcStreamer``show` 方法来刷新目标图片(支持 YUYV 和 MJPEG),
15+
- 通过 `maix.uvc.UvcServer` 注册自定义刷图回调函数来刷新目标图片(仅支持 MJPEG),区别于上一个方法的顺序逻辑,使用有一定的难度
16+
17+
## 参考例程
18+
19+
首先需要在 `Settings` APP 的 `USB settings` 栏内启用 `UVC` 功能。
20+
21+
注意: `UVC` 功能启用后,因为 Linux 的 `UVC Gadget` 实现,仍需一个用户程序处理 `UVC` 设备的事件,
22+
否则整个 `USB` 功能会暂停等待,影响同时启用的其它 `Gadget` 功能,包括 `Rndis``NCM`,导致断网。
23+
故对于其它 `USB` 功能有需求的用户,在基于 `MaixPy` 开发 UVC 显示功能时建议采用 `UvcStreamer` 的实现。
24+
否则请保证 `MaixCAM` 设备有其它联网途径如 `WIFI` 以确保能正常开发调试。
25+
26+
### UvcStreamer
27+
28+
该方法不影响常态下 USB 功能,原理是分了两个进程。官方默认实现了一个 `server` 进程进行`UVC` 设备的事件处理,并封装了易用统一的刷图接口 `show(img)` 供用户使用,当成一个 `display` 线性逻辑操作即可。
29+
30+
参考示例源码路径: `MaixPy/examples/vision/streaming/uvc_stream.py`
31+
32+
示例分析(使用方法):
33+
34+
1. 初始化 UvcStreamer 对象
35+
36+
```python
37+
uvcs = uvc.UvcStreamer()
38+
```
39+
40+
- (可选)切换成 MJPEG 模式,默认 YUYV
41+
42+
```python
43+
uvcs.use_mjpg(1)
44+
```
45+
46+
2. 刷图(自动处理格式,MJPEG 中等性能损耗,YUYV 高损耗)
47+
48+
```python
49+
uvcs.show(img)
50+
```
51+
52+
53+
### UvcServer
54+
55+
高性能单进程实现,但仅在运行时 USB 全部功能才可用,故停止该进程时需要注意仍启用的 `Rndis``NCM` 会暂时失效,断开网络链接。
56+
57+
参考示例源码路径:`MaixPy/examples/vision/streaming/uvc_stream.py`
58+
59+
另有封装成 APP 的源码路径:`MaixCDK/projects/app_uvc_camera/main/src/main.cpp`
60+
61+
示例分析(使用方法):
62+
63+
1. 初始化 UvcServer 对象,需提供刷图回调函数实现
64+
65+
提供了 helper 函数 `helper_fill_mjpg_image` 帮助将更通用的 `Image` 对象刷入 `UVC` 的缓冲区。
66+
67+
```python
68+
cam = camera.Camera(640, 360, fps=60) # Manually set resolution
69+
# | 手动设置分辨率
70+
71+
def fill_mjpg_img_cb(buf, size):
72+
img = cam.read()
73+
return uvc.helper_fill_mjpg_image(buf, size, img)
74+
75+
uvcs = uvc.UvcServer(fill_mjpg_img_cb)
76+
```
77+
`fill_mjpg_img_cb` 参考实现仅当返回 `0` 时,才会正常触发缓冲区刷新。
78+
故推荐在最后一行使用 helper 函数即可:
79+
`return uvc.helper_fill_mjpg_image(buf, size, img)`
80+
81+
2. 启动 uvc,后台启动线程,非阻塞
82+
83+
```python
84+
uvcs.run()
85+
```
86+
87+
3. 停止 uvc,不再使用时需要调用,可恢复 `UvcStreamer` 方法实现中的后台进程,保证 `USB` 功能正常
88+
89+
目前有 BUG,MaixPy 框架在退出时会强制终止进程,导致并不能执行完 `while not app.need_exit():` 循环后的函数调用,即该 `stop()` 很难得到执行。
90+
故对 **保证 `USB` 功能正常** 有需求的用户可以换用 `UvcStreamer` 方法或是移步 `MaixCDK` 的原始 C++ API,参考例程:`MaixCDK/examples/uvc_demo/main/src/main.cpp`
91+
92+
```python
93+
uvcs.stop()
94+
```

0 commit comments

Comments
 (0)