MaixCAM MaixPy 视频流 UVC 推流 / 化身 UVC 摄像头显示自定义内容

更新历史
日期 版本 作者 更新内容
2024-12-20 1.0.0 taorye 初版文档

简介

MaixCAM 化身 UVC 摄像头, UVC 全称为:USB video(device) class,这里提供两种方法供显示自定义内容:

  • 通过 maix.uvc.UvcStreamershow 方法来刷新目标图片(支持 YUYV 和 MJPEG),
  • 通过 maix.uvc.UvcServer 注册自定义刷图回调函数来刷新目标图片(仅支持 MJPEG),区别于上一个方法的顺序逻辑,使用有一定的难度

参考例程

首先需要在 Settings APP 的 USB settings 栏内启用 UVC 功能。

注意: UVC 功能启用后,因为 Linux 的 UVC Gadget 实现,仍需一个用户程序处理 UVC 设备的事件,
否则整个 USB 功能会暂停等待,影响同时启用的其它 Gadget 功能,包括 RndisNCM,导致断网。
故对于其它 USB 功能有需求的用户,在基于 MaixPy 开发 UVC 显示功能时建议采用 UvcStreamer 的实现。
否则请保证 MaixCAM 设备有其它联网途径如 WIFI 以确保能正常开发调试。

UvcStreamer

该方法不影响常态下 USB 功能,原理是分了两个进程。官方默认实现了一个 server 进程进行UVC 设备的事件处理,并封装了易用统一的刷图接口 show(img) 供用户使用,当成一个 display 线性逻辑操作即可。

参考示例源码路径: MaixPy/examples/vision/streaming/uvc_stream.py

示例分析(使用方法):

  1. 初始化 UvcStreamer 对象
uvcs = uvc.UvcStreamer()
  • (可选)切换成 MJPEG 模式,默认 YUYV
uvcs.use_mjpg(1)
  1. 刷图(自动处理格式,MJPEG 中等性能损耗,YUYV 高损耗)
uvcs.show(img)

UvcServer

高性能单进程实现,但仅在运行时 USB 全部功能才可用,故停止该进程时需要注意仍启用的 RndisNCM 会暂时失效,断开网络链接。

参考示例源码路径:MaixPy/examples/vision/streaming/uvc_stream.py

另有封装成 APP 的源码路径:MaixCDK/projects/app_uvc_camera/main/src/main.cpp

示例分析(使用方法):

  1. 初始化 UvcServer 对象,需提供刷图回调函数实现

提供了 helper 函数 helper_fill_mjpg_image 帮助将更通用的 Image 对象刷入 UVC 的缓冲区。

cam = camera.Camera(640, 360, fps=60)   # Manually set resolution
                                        # | 手动设置分辨率

def fill_mjpg_img_cb(buf, size):
    img = cam.read()
    return uvc.helper_fill_mjpg_image(buf, size, img)

uvcs = uvc.UvcServer(fill_mjpg_img_cb)

fill_mjpg_img_cb 参考实现仅当返回 0 时,才会正常触发缓冲区刷新。
故推荐在最后一行使用 helper 函数即可:
return uvc.helper_fill_mjpg_image(buf, size, img)

  1. 启动 uvc,后台启动线程,非阻塞
uvcs.run()
  1. 停止 uvc,不再使用时需要调用,可恢复 UvcStreamer 方法实现中的后台进程,保证 USB 功能正常

目前有 BUG,MaixPy 框架在退出时会强制终止进程,导致并不能执行完 while not app.need_exit(): 循环后的函数调用,即该 stop() 很难得到执行。
故对 保证 USB 功能正常 有需求的用户可以换用 UvcStreamer 方法或是移步 MaixCDK 的原始 C++ API,参考例程:MaixCDK/examples/uvc_demo/main/src/main.cpp

uvcs.stop()