Alios USB camera 常见需求处理
配置说明
组件配置
每个组件都有一个 .yaml
配置文件,主要关注:
1 | def_config: # 组件的可配置项 |
def_config
下的配置都会以宏定义的形式来影响代码。就相当于在编译时多了 -DCONFIG_XXX=1
这样。
Solution 配置
Solution 也有一个 yaml
的配置文件,也包含 depends
、def_config
等配置项,这里单独来讲主要是想强调 def_config
这个配置,Solution 下的配置文件中,可以修改任意组件的 def_config
。也就是说,每个组件下的配置文件中,def_config
下配置相当于是默认配置。如果 Solution 下的配置项与组件的下配置不一致,以 Solution 的为准。
❗❗强调:Solution 下的配置会对所有组件生效,所以在定义配置的时候,注意配置名是否与其他组件重复了(可以重复,但要确认这是你期望的)。
用户常用改动
板卡内存大小
1
CONFIG_DRAM_CFG: "128m"
配置 UVC 数量。有的客户是单目,有的客户是双目。
1
CONFIG_USBD_UVC_NUM: 2
修改 PID, VID。(设备描述符里面)
修改设备名称(视频控制接口描述符里面。双目场景一般一个rgb摄像头 + 一个红外摄像头,需要分别设置名字以区分)。
修改序列号。(设备描述符里面)
修改 PRODUCT ID(设备描述符里面)
视频码率控制。(MJPEG/H264 H265)
1
2CONFIG_UVC_MJPEG_BITRATE: 20480 # UVC 推流时,设置视频编码器 MJPEG 的码率,单位 kbps
CONFIG_UVC_H264_H265_BITRATE: 4096 # UVC 推流时,设置视频编码器 H264/H265 的码率,单位 kbps灯光亮度控制。(通过 PWM 调控)
分辨率。(不同客户需要支持的分辨率不一样)
支持高分辨率(vpss 仅一个通道支持2880x1620)
-
1
CONFIG_UVC_COMM_FUNC: 0 # USB camera 使能亮度、色调、对比度等调整功能
-
1
CONFIG_UVC_CROP_BEFORE_SCALE: 1
板卡内存大小
1811c,1810c 等内存大小不一样,需要更具客户使用的具体芯片来调整。
配置选项:
1 | CONFIG_DRAM_CFG: "128m" |
默认配置:64m
用户(特定项目)配置位置:solutions/usb_cam/customization/{项目xxx}/package.xxx.yaml
UVC 数量
配置选项:
1 | CONFIG_USBD_UVC_NUM: 1 |
默认配置:1
组件配置位置(默认配置):components/cvi_platform/package.yaml
用户(特定项目)配置位置:solutions/usb_cam/customization/{项目xxx}/package.xxx.yaml
PID/VID 修改
暂未定义宏。直接修改对应文件。
配置位置:components/cvi_platform/protocol/usb_devices/usbd_composite/src/usbd_comp.c
1 |
|
修改序列号
序列号iSerialNumber
是在设备描述中指定的(指定字符串描述符的ID)。要修改的话只需修改对应的字符串描述符。
配置位置:components/cvi_platform/protocol/usb_devices/usbd_composite/src/usbd_comp.c
1 | static const struct usb_descriptor_header * const comp_string_descriptors[] = { |
动态修改序列号✨
基本都会用到。
修改 PRODUCT ID
product ID
也是在设备描述中指定的iProduct
(指定字符串描述符的ID)。要修改的话只需修改对应的字符串描述符。
配置位置:components/cvi_platform/protocol/usb_devices/usbd_composite/src/usbd_comp.c
1 | static const struct UVC_STRING_DESCRIPTOR(10) dev_string_descriptor_product = { |
设备名称修改
设备名称也是通过字符串描述符传递。视频控制接口描述符中的 iInterface
指定了名称对应的字符串描述符的下标。
配置位置:components/cvi_platform/protocol/usb_devices/usbd_composite/src/usbd_comp.c
1 | static const struct usb_descriptor_header * const comp_string_descriptors[] = { |
目前最大支持三个摄像头,所以这里预留了三个设备描述符。如需修改名称,修改对应的描述符即可。
❗❗注意:修改之后,Windows 需要在设备管理器中卸载设备,再插上设备才能看的修改后的名字。(Windows自身有缓存)
视频码率控制
目前 H264/H265
都是吃配置 CONFIG_UVC_H264_H265_BITRATE
。
MJPEG
格式的码率则是通过 CONFIG_UVC_MJPEG_BITRATE
配置。
配置选项:
1 | CONFIG_UVC_MJPEG_BITRATE: 20480 # UVC 推流时,设置视频编码器 MJPEG 的码率,单位 kbps |
组件配置位置(默认配置):components/cvi_platform/package.yaml
用户(特定项目)配置位置:solutions/usb_cam/customization/{项目xxx}/package.xxx.yaml
视频格式设置
目前支持 YUY2
,H264
,H265
,MJPEG
4 种格式出流。其中 H264, H265 有一个 DISABLE 配置选项,因为这两种编解码方式需要一个固件,H264 的固件大小约为253k,h265 约为 147k,某些场景下flash 大小不够需要严格控制固件大小,就可以考虑disable h264/h265。
不过目前release 版本中,codec 是以.a 静态库的形式提供的,默认是使能了的。所以该配置意义不大。
配置选项:
1 | CONFIG_DISABLE_VENC_H264: 0 # 是否禁用 H264 编码 |
用户(特定项目)配置位置:solutions/usb_cam/customization/{项目xxx}/package.xxx.yaml
分辨率设置
可为不同视频格式配置多种不同的分辨率,直接修改对于的描述数组。
配置位置:components/cvi_platform/protocol/usb_devices/usbd_class/usbd_uvc/src/usbd_uvc.c
1 | static struct uvc_frame_info_st yuy2_frame_info[] = { |
格式为:{序号,宽,高,帧率,是否旋转}
。
支持高分辨率
视频流处理过程中,会用到一些中间变量来存放图像数据,目前该变量的大小是预先确定的,即 DEFAULT_FRAME_SIZE
。默认分配的大小是1920x1080x1.5。
在大多数情况下,MJEPG/H264/H265 等需要存放的都是编码后的数据,即使是 2560x1440 经过编码后也完全能存放下,但我们还支持未压缩的 YUY2 格式,若需要输出 1920x1080 的 YUY2 格式,则上述空间就不够用了。需要设置为 1920x1080x2,另外,处理过程中还需要再原始图像数据的基础上,每1012字节加上12字节的header,所以还需额外分配 些空间。目前建议设置 1920x1120x2
配置位置:components/cvi_platform/protocol/usb_devices/usbd_class/usbd_uvc/src/usbd_uvc.c
1 |
修改为
1 |
支持 2880x1440 等高分辨率
参考 《Cvitek Debug SOP》
这个问题是由vpss各scaler硬件性能差异导致的,这种情况下需要使用最强的scaler-1进行所需图像处理。具体的,对于single mode,需要设置vpss chn的chn号为1,对于dual mode,需要设置 grp 属性中的u8VpssDev为1且设置vpss chn的chn号为0。
推荐解决办法:即使单个设备也使用dual mode。
备选方案:使用 single mode 并设置通道为1的话,目前还会启用通道0,会占用额外的VB,也可以合入这笔代码 https://gerrit-ai.sophgo.vip:8443/#/c/114453/,不启用chn0。这样还需修改uvc 使用的通道号为1. VPSS 和venc的绑定关系在:components/cvi_platform/protocol/usb_devices/usbd_class/usbd_uvc/src/usbd_uvc.c
中uvc
这个全局变量下配置。
1 | static struct uvc_device_info uvc[USBD_UVC_MAX_NUM] = { |
USBcamera通用功能
其他项目也会用到 usbcamera,但并不需要调整色调等功能,所以目前 SDK 默认并未启用这些功能。
如需启用,需要通过配置
CONFIG_UVC_COMM_FUNC:1
,则将目前支持的功能都启用。
配置选项:
1 | CONFIG_UVC_COMM_FUNC: 0 # USB camera 使能亮度、色调、对比度等调整功能 |
默认配置:0
未启用。
组件配置位置(默认配置):components/cvi_platform/package.yaml
用户(特定项目)配置位置:solutions/usb_cam/customization/{项目xxx}/package.xxx.yaml
注意:由于有多目 sensor 的场景,在特定摄像头下进行配置的时候,会区分设备的。设备需要与对应的 VPSS GRP, VI_PIPE 绑定,必须满足以下关系:
SENSOR0 -> VI_PIPE0 -> GRP0
SENSOR1 -> VI_PIPE1 -> GRP1
否则设置无法生效。
VI 绑定 VPSS 是在 solutions/usb_cam/customization/{xxx}/param/custom_vpssparam.c
中,Group 配置中有如下内容:
1 | .bBindMode = CVI_TRUE, |
目前支持的功能有:
- PROCESSING UNIT
- 亮度
- 对比度
- 色调
- 饱和度
- 锐度
- INPUT TERMINAL(CAMERA TERMINAL)
- PANTILE上下左右移动(绝对)
- EXTENSION UNIT
- REBOOT(发送 reboot 会重启,无插拔烧录时用)
保持输出长宽比
当sensor的输入图像为 16:9 时,若输出的分辨率为 4:3 ,会看到输出的图像明显发生畸变 / 或者说有黑边(取决于 vpss 通道的 ASPECT_RATIO_S 参数设置)。可以使能该配置 CONFIG_UVC_CROP_BEFORE_SCALE:1
,在进行缩放前先进行裁剪,使裁剪后的大小与输出的长宽比一致,并且尽可能提供更大的视野。这样经过缩放就不会发生畸变。
配置选项:
1 | CONFIG_UVC_CROP_BEFORE_SCALE: 1 |
默认配置:1
组件配置位置(默认配置):components/cvi_platform/package.yaml
用户(特定项目)配置位置:solutions/usb_cam/customization/{项目xxx}/package.xxx.yaml
保持输出长宽比2–是否插黑边
VPSS 在缩放处理时,可以指定参数是否保存长宽比。
如 1280x720的屏幕,如果输出的画面是 800x400,
- AUTO 保持比例的话就会拉伸为960x720,左右两边就会有黑边。
- NONE 不进行处理,原始大小输出。(画面可能会变形,比如16:9的输入,输出为4:3时)
- MANUAL 手动指定显示的位置,以及显示画面的宽、高。
1 | typedef struct _ASPECT_RATIO_S { |
用户(特定项目)配置位置:solutions/usb_cam/customization/{项目xxx}/param/custom_vpssparam.c
为每个 vpss 通道单独配置。
1 | PARAM_CLASSDEFINE(PARAM_VPSS_CHN_CFG_S, CHNCFG, GRP0, CHN) [] = |
启用 pqtool 支持
❗❗注意编译时要指定正确的 CHIP_ARCH
,否则会导致 pqtool 工具使用时报错。通过 export CHIP_ARCH=cv181x; make usb_cam PROJECTS="XXXX"
编译。
1 | CONFIG_PQTOOL_SUPPORT: 1 |
启用 pqtool_support 以及 rndis 网络才能让pc端工具连上。使用 UVC 出流效果比 rtsp 更好。
DMA 与 rndis 不兼容,所以要关闭。不过目前不开 DMA 会有概率屏闪,所以仅推荐在调试时关闭DMA。
RTSP 与 UVC 不兼容,所以要关闭。
目前 RNDIS 有概率出错,发现连不上的话在设备管理器中,禁用 rndis 对应的设备再启用。
板端默认的 IP 地址是 192.168.11.10
,PC端对应的 rndis 网卡的 IP 也需要手动设置到相同网段,才能使用 Pqtool 工具进行连接。
快启说明
为了能使用USB烧录,在rom阶段会等待1s检测usb连接,还有uart烧录的引脚被占用,也会等待1s。
快启1:通过写 efuse 跳过 rom 阶段的烧录检测。
- 配置:
CONFIG_ENABLE_FASTBOOT=1
,启用后,app_main 中会调用CVI_EFUSE_EnableFastBoot
去烧写 efuse 使能快启。 - 收益:1s整或2s整。
- 配置:
快启2:boot0 阶段通过拉高 SPI 的速率加速从flash load固件的过程。来提升启动速度。
- 配置:
CONFIG_QUICK_STARTUP_SUPPORT
。启用后 boot0 中会拉高 spi 的时钟。 - 收益:看yoc.bin,或者是否需要从flash加载模型吧,收益不大,可能就几十ms。
- 配置:
AE 快速收敛
若 sensor 的自动曝光调整较慢,在刚打开sensor时,可能会看到明显的画面亮度调整的过程。可以调整pq参数,调大自动曝光的调整速率。
摄像头开启关闭时进行额外处理
目前是为每个摄像头建立了一个处理线程,完成 UVC 推流。该线程中每一次调用vedio_streaming_send
发送一帧,通过检查stream_on的变化情况,确定当前的状态。stream_on 由 0->1 时表示打开了设备。反之关闭摄像头。
1 | static void *send_to_uvc(void *arg) |
灯光控制
推流时开灯,停止推流时关灯。简单的开关可直接在上面的流程中实现,有些场景可考虑使用UVC 处理单元中的 backlight, 通过pwm去控制灯光。
standby sensor 降低功耗
在不出流的时候(待机状态),将 sensor standby,以降低整机功耗。standby 一般有两中方式:
- 软件standby:通过I2C发送指令,让sensor进入standby模式(仍会有较低的功耗,以确保能接受I2C的唤醒指令)
- 硬件standby:拉低sensor的powerdown引脚,进行standby。功耗比软件更低。
超频
clkstat 命令可以看时钟。
带宽控制
测试
1 | # 初始化计数器 |