媒体示例
支持的芯片:[RTL8735C]
概述
类别 |
示例 |
入口 / 源文件 |
说明 |
|---|---|---|---|
视频示例 |
|
V1 H.264 视频通过 RTSP 进行实时串流。 |
|
视频示例 |
|
双视频通道,同时进行 MP4 录制与 RTSP 串流。 |
|
音频示例 |
|
麦克风采集后直接回放到扬声器。 |
|
音频示例 |
|
AAC 编码 / 解码音频回环。 |
|
音频示例 |
|
通过 RTSP/RTP 实现全双工双向音频。 |
|
音频示例 |
|
使用 AEC、AGC 与噪声抑制的音频 VQE 测试。 |
|
AI 示例 |
|
SCRFD 人脸检测,支持 UVC 或 RTSP 输出与 OSD overlay。 |
|
AI 示例 |
|
在 V5 RGB 输入上运行 YOLO/NanoDet 目标检测。 |
|
AI 示例 |
|
级联人脸检测、embedding、识别与 OSD overlay。 |
|
整合示例 |
|
同时运行音频、视频录制、RTSP 串流与 NN 检测。 |
|
整合示例 |
|
AP 侧完整多媒体联合测试,包含录制、串流、NN、OSD 与文件保存。 |
视频示例
以下示例说明如何使用多媒体框架 (MMF) 建立视频 pipeline。
编译视频示例
编译视频示例前,必须先在 menuconfig 中启用必要选项:
./ameba.py menuconfig
进入以下路径:
(Top) > CONFIG VIDEO SOFTWARE > BUILD AP MEDIA EXAMPLE
启用该选项后,系统会自动打开视频示例所需的 module。
接着在 SDK 根目录执行以下命令,编译视频 AP 示例:
./ameba.py build --app video_ap
编译成功后,将 image 烧录到开发板,并打开串口控制台执行示例。
示例源文件
源文件位于:
component/soc/<soc>/sw/media_example/ap_media_example/video_example_src/
每个示例都会通过 VIDEO_APP_TABLE_SECTION 注册到应用表,并可通过串口控制台调用:
VIDEO list # 列出所有已注册的视频示例
VIDEO run [n] # 执行索引为 n 的示例(默认值为 0)
部分示例会导出多个应用表 entry。例如联合测试示例会提供独立的 UVC 与 RTSP entry,因此可直接从 VIDEO list 选择所需的输出路径,再执行对应索引。
备注
同一时间只能执行一个示例。切换到其他示例前,请先复位开发板。
备注
使用网络功能的示例(例如 RTSP 串流)需要先建立 Wi-Fi 连接。请先使用以下 AT 命令连接路由器:
AT+WLCONN=ssid,<your_ssid>,pw,<your_password>
等待出现 [$]wifi got ip 信息,确认 IP address 已分配后,再执行 video 示例。完整 Wi-Fi command 说明请参考
Wi-Fi AT Commands
。
mmf2_video_example_v1_rtsp_init
源文件: ap_media_example/video_example_src/mmf2_video_example_v1_rtsp_init.c
这是最简单的实时串流示例。V1 采集 H.264 视频并通过 RTSP 输出。对于刚开始使用 MMF 的开发者,建议从此示例开始;它只使用一个 video_module、一个 rtsp2_module 与一个 SISO linker。
数据流:
[Video V1: H.264 1920x1080 @ 30fps] --> SISO --> [RTSP server]
开发板运行后,可使用 VLC 或其他支持 RTSP 的播放器连接 rtsp://<device-ip>/stream。
编译时选项:
#define AINR_ENA 0 /* AI noise reduction on V1; set 1 to enable */
关键说明:
需要
CONFIG_LWIP_LAYER=1(否则会出现 compile-time error)。video module queue 必须使用
MMQI_FLAG_DYNAMIC,因为 H.264 frame size 会随每一帧变化。Queue depth
60可吸收 encoder burst output,并避免 frame drop。当新的 client 连接时,可在 RTSP connected callback 中调用
mm_module_ctrl(video_v1_ctx, CMD_VIDEO_FORCE_IFRAME, 0)强制产生 keyframe。
mmf2_video_example_v1v2_mp4_rtsp_init
源文件: ap_media_example/video_example_src/mmf2_video_example_v1v2_mp4_rtsp_init.c
这是一个双通道的视频示例。V1 以全分辨率采集 HEVC,用于 SD 卡上的 MP4 录制;V2 以较低分辨率采集 H.264,用于同时进行 RTSP 实时串流。两个通道共享同一个 MIMO linker,不包含音频。
数据流:
[Video V1: HEVC 2688x1520 @ 15fps] --+
+--> MIMO --> [mp4_module] (V1 -> SD card)
[Video V2: H.264 1280x720 @ 30fps] --+
+--> MIMO --> [rtsp2_module] (V2 -> RTSP)
编译时选项:
#define AINR_ENA 0 /* AI noise reduction; set 1 to enable */
关键说明:
需要
CONFIG_LWIP_LAYER=1。V1 与 V2 可使用各自独立的 frame rate 与 bitrate;V1 用于高画质保存,V2 则针对串流带宽优化。
mp4_params.record_type中设置为STORAGE_VIDEO``(仅 video)。若需要录制 audio,可改为 ``STORAGE_ALL并增加 audio chain。MIMO dependency mask 使两个输出彼此独立:MP4 使用
MMIC_DEP_INPUT0,RTSP 使用MMIC_DEP_INPUT1。
音频示例
以下示例说明如何使用多媒体框架 (MMF) 建立音频 pipeline。示例源文件位于:
component/soc/<soc>/sw/media_example/ap_media_example/audio_example_src/
每个示例都会通过 AUDIO_APP_TABLE_SECTION 注册到应用表,并可在串口控制台中执行:
AUDIO list # 列出所有已注册的音频示例
AUDIO run [n] # 执行索引为 n 的示例(默认值为 0)
备注
同一时间只能执行一个示例。切换到其他示例前,请先复位开发板。
mmf2_example_audioloop_init
源文件: ap_media_example/audio_example_src/mmf2_example_audioloop_init.c
这是一个简单的音频回环示例。音频从内建麦克风 (AMIC) 采集后,会通过 audio module 立即从扬声器播放。
数据流:
[Audio Module] --> SISO --> [Audio Module]
(capture) (playback)
关键参数:
audio_params.sample_rate = ASR_48KHZ;
mmf2_example_aacloop_init
源文件: ap_media_example/audio_example_src/mmf2_example_aacloop_init.c
这是一个音频编码/解码回环示例。从麦克风采集的音频会先编码为 AAC,再立即解码并播放。该示例用于说明 AAC encoder (module_aac) 与 AAC decoder (module_aad) 的 pipeline。
数据流:
[Audio] --> SISO --> [AAC Encoder] --> SISO --> [AAC Decoder] --> SISO --> [Audio]
(capture) (playback)
关键参数:
aac_params.sample_rate = 16000;
aac_params.channel = 1; // mono
aac_params.trans_type = AAC_TYPE_RAW;
aac_params.object_type = AAC_AOT_LC;
aac_params.bitrate = 32000; // 32 kbps
aad_params.sample_rate = 16000;
aad_params.channel = 1;
aad_params.trans_type = AAD_TYPE_RAW;
aad_params.object_type = AAD_AOT_LC;
mmf2_example_2way_audio_init
源文件: ap_media_example/audio_example_src/mmf2_example_2way_audio_init.c
这是一个使用 RTSP server 与 RTP client 的双向音频串流示例。麦克风采集的音频会编码为 AAC 并通过 RTSP 输出,同时设备也会接收 RTP 音频流、进行解码,并通过扬声器播放。该示例展示完整的全双工音频通信流程。
数据流:
[Audio] --> SISO --> [aac_module] --> SISO --> [rtsp2_module] -----> (Network)
(capture) (encode) (server) (stream)
[Audio] <-- SISO <-- [aad_module] <-- SISO <-- [rtp_module] <---- (Network)
(playback) (decode) (receive) (send)
关键参数:
// Audio capture/playback
audio_params.sample_rate = ASR_16KHZ;
// AAC Encoder
aac_params.sample_rate = 16000;
aac_params.channel = 1; // mono
aac_params.trans_type = AAC_TYPE_ADTS;
aac_params.object_type = AAC_AOT_LC;
aac_params.bitrate = 32000; // 32 kbps
// RTSP Server
rtsp2_params.codec_id = AV_CODEC_ID_MP4A_LATM;
rtsp2_params.channel = 1;
rtsp2_params.samplerate = 16000;
// RTP Receiver
rtp_params.port = 16384;
// AAC Decoder
aad_params.sample_rate = 16000;
aad_params.channel = 1;
aad_params.trans_type = AAD_TYPE_RTP_RAW;
aad_params.object_type = AAD_AOT_LC;
使用方式:
使用 VLC 或其他 RTSP client 连接 RTSP stream:
rtsp://<device_ip>:554/设备默认以 16 kHz mono AAC 格式输出音频
设备会同时在 port 16384 接收 RTP 音频并播放
从设备串流音频到 VLC Player
点击 Media -> Open Network Stream。
输入
rtsp://<device_ip>:554/,其中<device_ip>为 Ameba 的 IP 地址,RTSP server 默认 port 为 554。点击 Play。
从 VLC Player 串流音频到设备
点击 Media -> Stream。
选择 File,点击 Add,选择音频文件后点击 Stream。
备注
请选择与 decoder 设置一致的音频文件格式(mono,16 kHz sampling rate)。
确认选中的文件后,点击 Next。
选择 RTP Audio/Video Profile,点击 Add。
在 Address 字段输入设备 IP 地址,将 Base port 设为 16384,然后点击 Next。
确认 Activate Transcoding 未勾选,点击 Next -> Stream。
此时可从板子的 3.5 mm audio jack 听到声音。
audio_vqe_test
源文件: ap_media_example/audio_example_src/audio_vqe_test.c
这是一个使用 ASP (Audio Signal Processing) library 的音频 Voice Quality Enhancement (VQE) 测试示例。该示例展示包含 Acoustic Echo Cancellation (AEC)、Automatic Gain Control (AGC) 与 Noise Suppression (NS) 的音频处理 pipeline,并同时覆盖发送端(speaker)与接收端(microphone)路径。
数据流:
[Speaker] --> [VQE SND: AEC + AGC + NS] --> [Output]
^
| (farend reference)
[Microphone] -----+
[Input] --> [VQE RCV: NS + AGC] --> [Microphone TX]
关键组件:
VQE_SND(发送路径): 对麦克风输入进行 AEC、AGC 与 NS 处理,以消除回声并降低噪声。
VQE_RCV(接收路径): 对输出数据进行 NS 与 AGC 处理,用于传输路径。
关键参数:
// Frame configuration
#define AUDIO_DMA_PAGE_SIZE 640
#define FRAME_SIZE (AUDIO_DMA_PAGE_SIZE / 2) // 320 samples
Sample rate: 16000 Hz
// RX Path - Noise Suppression
RX_NS.NS_EN = 1;
RX_NS.NSLevel = 10; // Suppression level when no speech
RX_NS.HPFEnable = 0; // High-pass filter disabled
// RX Path - Automatic Level Control (ALC)
RX_AGC.AGC_EN = 1;
RX_AGC.AGCMode = CT_ALC; // ALC mode (vs. CT_LIMITER)
RX_AGC.ReferenceLvl = 0; // Target level 0 dBFS
RX_AGC.RatioFormat = 1; // 8.8 fix point ratio format
RX_AGC.AttackTime = 10; // 10 ms
RX_AGC.ReleaseTime = 50; // 50 ms
RX_AGC.Ratio[0..2] = 50 * 256; // Compression ratio
RX_AGC.Threshold[0] = 39; // Threshold1 in dB
RX_AGC.Threshold[1] = 70; // Threshold2 in dB
RX_AGC.Threshold[2] = 80; // Noise gate level in dB
RX_AGC.NoiseFloorAdaptEnable = 1;
RX_AGC.RMSDetectorEnable = 1;
RX_AGC.MaxGainLimit = 30; // 30 dB max gain
// RX Path - Acoustic Echo Cancellation
RX_AEC.AEC_EN = 1;
RX_AEC.EchoTailLen = 60; // Echo tail length in ms
RX_AEC.CNGEnable = 1; // Comfort noise generation enabled
RX_AEC.PPLevel = 4; // Post-processing level (1-18)
RX_AEC.DTControl = 1; // Double-talk control type
// TX Path - Noise Suppression
TX_NS.NS_EN = 1;
TX_NS.NSLevel = 10;
// TX Path - Automatic Level Control
TX_AGC.AGC_EN = 1;
TX_AGC.AGCMode = CT_ALC;
TX_AGC.ReferenceLvl = 0;
TX_AGC.RatioFormat = 1;
TX_AGC.AttackTime = 10;
TX_AGC.ReleaseTime = 50;
TX_AGC.Ratio[0..2] = 50 * 256;
TX_AGC.Threshold[0] = 39;
TX_AGC.Threshold[1] = 70;
TX_AGC.Threshold[2] = 80;
TX_AGC.NoiseFloorAdaptEnable = 1;
TX_AGC.RMSDetectorEnable = 1;
TX_AGC.MaxGainLimit = 30;
ASP API 函数:
函数 |
说明 |
|---|---|
|
初始化发送路径 VQE(AEC + AGC + NS) |
|
通过发送路径处理一帧数据 |
|
销毁发送路径 VQE context |
|
初始化接收路径 noise suppression |
|
通过接收路径 NS 处理一帧数据 |
|
销毁接收路径 NS context |
|
初始化接收路径 AGC |
|
通过接收路径 AGC 处理一帧数据 |
|
销毁接收路径 AGC context |
ASP 配置结构:
typedef struct CTNS_cfg_s {
int16_t NS_EN; // Enable noise suppression
int16_t NSLevel; // Suppression level (0-10)
int16_t HPFEnable; // High-pass filter enable
int16_t NSSlowConvergence; // Slow convergence time (ms)
int16_t QuickConvergenceEnable; // Quick convergence enable
} CTNS_cfg_t;
typedef struct CTAGC_cfg_s {
int16_t AGC_EN; // Enable AGC
CT_AGC_MODE AGCMode; // CT_ALC or CT_LIMITER
int16_t ReferenceLvl; // Reference level in dB
int16_t RatioFormat; // Ratio format (0: integer, 1: 8.8 fix point)
int16_t AttackTime; // Attack time in ms
int16_t ReleaseTime; // Release time in ms
int16_t Ratio[3]; // Compression ratios
int16_t Threshold[3]; // Thresholds (Threshold1, Threshold2, NoiseGateLvl)
int16_t KneeWidth; // Knee width
int16_t NoiseFloorAdaptEnable; // Noise floor adaptation enable
int16_t RMSDetectorEnable; // RMS detector enable
int16_t MaxGainLimit; // Maximum gain limit in dB
} CTAGC_cfg_t;
typedef struct CTAEC_cfg_s {
int16_t AEC_EN; // Enable AEC
int16_t EchoTailLen; // Echo tail length in ms
int16_t CNGEnable; // Comfort noise generation enable
int16_t PPLevel; // Post-processing level (1-18)
int16_t DTControl; // Double-talk control type
int16_t ConvergenceTime; // Convergence time
} CTAEC_cfg_t;
使用方式:
通过串口控制台执行:
audio run <index>``(可使用 ``audio list查看 index)。示例会从 SD card 读取
pink_noise.bin作为 farend input。处理后的输出会保存为
asp_rx.bin。测试时长为 30 秒(可通过
AUDIO_TEST_DURATION调整)。
注意事项:
需要在 SD card 中放置
pink_noise.bin测试文件作为 farend input。使用 16 kHz sample rate 与 320-sample frame(20 ms)。
麦克风输入会经过 AEC、AGC 与 NS pipeline 处理。
AI 示例
编译 NN 视频示例
NN 视频示例作为 AP 媒体示例应用的一部分进行编译。编译前,请在 menuconfig 中打开对应选项:
CONFIG MEDIA FRAMEWORK
-> CONFIG APPLICATION EXAMPLE
-> CONFIG EXAMPLE MEDIA FRAMEWORK
-> CONFIG MEDIA VIDEO APP
-> CONFIG ENABLE NN EXAMPLE
然后在 SDK 根目录下编译 video AP application:
python3 ameba.py build --app video_ap
编译成功后,将固件映像与 LittleFS 模型映像烧录到开发板,并打开串口终端。示例会注册到 video application table,可通过命令列出并运行:
help
mmf2_video_example_v1_init
RTSP 示例运行前需要先连接路由器:
AT+WLCONN=ssid,<your_ssid>,pw,<your_password>
等待 [$]wifi got ip 表示已获取 IP 地址后,再运行 RTSP 示例。UVC 示例需要使能 CONFIG_USBD_UVC=1。
人脸检测示例
源码: ap_media_example/video_example_src/mmf2_video_example_nn_face_detection_init.c
该示例将 V1 H.264 视频输出到 UVC 或 RTSP,同时在 V5 RGB stream 上运行 SCRFD 人脸检测。V1 是显示与 OSD 坐标空间,V5 是 NN 输入 stream。
数据流:
[Video V1: H.264 1920x1080@30fps] --> SISO --> [UVC / RTSP]
|
(OSD overlay)
[Video V5: RGB 576x320@10fps ] --> SISO --> [VIPNN: SCRFD face detection]
|
nn_display_cb()
(draws boxes & landmarks)
主要编译期选项:
#define FACEDET_STREAM_WIDTH 1920
#define FACEDET_STREAM_HEIGHT 1080
#define FACEDET_STREAM_FPS 30
#define FACEDET_NN_WIDTH 576
#define FACEDET_NN_HEIGHT 320
#define FACEDET_NN_FPS 10
该示例导出两个入口:mmf2_video_example_nn_face_detection_uvc_init 和 mmf2_video_example_nn_face_detection_rtsp_init。UVC 需要 CONFIG_USBD_UVC=1;RTSP 需要 CONFIG_LWIP_LAYER=1。
目标检测示例
源码: ap_media_example/video_example_src/mmf2_video_example_nn_object_detection_init.c
该示例在 V5 RGB stream 上运行 YOLO/NanoDet 目标检测,同时将 V1 H.264 输出到 UVC 或 RTSP 并叠加 OSD。NN 输入可选择 V5 RGB(OBJDET_USE_ARRAY_INPUT=0)或 synthetic array_module buffer(OBJDET_USE_ARRAY_INPUT=1)。
模型选择:
#include "model_yolo.h"
#include "model_yolov9.h"
#define OBJDET_MODEL_OBJ yolov4_tiny
#define OBJDET_MODEL_NAME "vfs:/yolov4_tiny_asymu8.nb"
#define OBJDET_NN_WIDTH 416
#define OBJDET_NN_HEIGHT 416
Model object:可从
yolov4_tiny、yolov7_tiny、nanodet_plus_m、yolov9_tiny等模型类型中选择。Model file path:支持 LittleFS(
vfs:/)和 SD card(sd:)两种存储路径。Resolution:
OBJDET_NN_WIDTH与OBJDET_NN_HEIGHT表示输入 RGB 帧尺寸。如果该尺寸与模型 tensor 尺寸不同,模型预处理代码会在推理前对完整帧进行 resize。Output sink:导出
mmf2_video_example_nn_object_detection_uvc_init和mmf2_video_example_nn_object_detection_rtsp_init两个入口。
人脸识别示例
源码: ap_media_example/video_example_src/mmf2_video_example_nn_face_recognition_init.c
该示例使用两阶段级联 NN pipeline 实现人脸检测与识别,并叠加 OSD。SCRFD 在 V5 RGB 帧中检测人脸,MobileFaceNet 提取 128 维 embedding,facerecog_module 将 embedding 与已保存数据库进行比对。已知人脸以绿色显示,未知人脸以红色显示。
数据流:
[Video V1: H.264 1920x1080 @ 30fps] --> SISO --> [UVC / RTSP]
|
(OSD overlay)
[Video V5: RGB 576x320 @ 10fps] --> SISO --> [VIPNN: SCRFD face detection]
|
(cascaded output)
|
[VIPNN: MobileFaceNet embedding]
|
[facerecog_module: identity match]
|
face_recognition_draw_object()
运行时 shell 命令:
命令 |
说明 |
|---|---|
|
进入注册模式。下一张检测到的人脸会以给定名称保存。 |
|
返回识别模式。 |
|
从 |
|
将已注册人脸特征保存到 |
|
清除 RAM 中的注册特征,不影响文件。 |
|
列出 RAM 中所有已注册人脸名称。 |
|
设置识别相似度阈值,整数除以 100。例如 |
备注
SCRFD 阶段必须使能模块输出(CMD_VIPNN_SET_OUTPUT),并配置为 data group 起点(MM_CMD_SET_DATAGROUP, MM_GROUP_START)。MobileFaceNet 配置为 group 终点(MM_GROUP_END),并使用 VIPNN_CMODE_ALL_ROI,使其针对每个检测到的人脸执行一次。
整合示例
mmf2_video_example_av_rtsp_mp4_nn_init
源文件: ap_media_example/video_example_src/mmf2_video_example_av_rtsp_mp4_nn_init.c
这是一个完整的音视频示例,可同时进行 RTSP 实时串流、MP4 SD 卡录制与 NN 物体检测。
数据流:
[Audio (16kHz AMIC)] --> SISO --> [AAC Encoder] ---+
|
[Video V1: HEVC 2688x1520@15fps] ---+ +--> MIMO --> [MP4 Recording]
[Video V2: H.264 1280x720@30fps ] --+ |
+-- MIMO ------+--> [RTSP Streaming (V2 + Audio)]
[Video V5: RGB 416x416@10fps ] --> SISO --> [VIPNN: YOLO object detection]
|
nn_display_cb()
编译时选项:
#define AINR_ENA 1 /* AI noise reduction on video channels */
#define AUDIO_ENA 1 /* enable audio for both RTSP and MP4 */
#define NN_ENA 1 /* enable NN object detection on V5 */
视频参数(V1 用于 MP4 录制):
video_v1_params.format = VIDEO_HEVC;
video_v1_params.width = 2688;
video_v1_params.height = 1520;
video_v1_params.fps = 15;
video_v1_params.bps = 2000000;
video_v1_params.rc_mode = ENC_VBR;
视频参数(V2 用于 RTSP 串流):
video_v2_params.format = VIDEO_H264;
video_v2_params.width = 1280;
video_v2_params.height = 720;
video_v2_params.fps = 30;
video_v2_params.bps = 500000;
MP4 录制参数:
mp4_params.record_length = 10; // seconds per file
mp4_params.record_file_num = 3; // rolling 3 files
mp4_params.record_file_name = "AmebaPro_recording";
mp4_params.mp4_audio_format = AUDIO_AAC;
NN model:
#define NN_MODEL_OBJ yolov4_tiny
#define NN_MODEL_NAME "vfs:/yolov4_tiny_asymu8.nb"
#define NN_WIDTH 416
#define NN_HEIGHT 416
mmf2_video_example_joint_test_uvc_init / rtsp_init
源文件: ap_media_example/video_example_src/mmf2_video_example_joint_test_init.c
这是完整的联合测试示例,最多可启用 5 个同时运行的视频通道,并可选择启用 AI 噪声抑制、实时串流(UVC 或 RTSP)、MP4 录制、带 OSD overlay 的 NN 检测,以及文件保存。该示例用于验证 AP 侧多媒体管线的完整功能。
SDK 现在会为该源文件注册两个 runtime entry:
mmf2_video_example_joint_test_uvc_init
mmf2_video_example_joint_test_rtsp_init
两个 entry 共用相同的内部初始化流程。所选的 VIDEO list entry 会在 module 打开前设置 V2 live-stream sink:UVC entry 将 V2 路由到 uvcd_module;RTSP entry 将 V2 路由到 rtsp2_module。
通道配置:
Ch |
ID |
默认分辨率 / 格式 |
用途 |
|---|---|---|---|
V1 |
0 |
HEVC 2688x1520 @ 15fps |
视频录制 (MP4) |
V2 |
1 |
H.264 1280x720 @ 30fps |
实时串流 (UVC / RTSP) |
V3 |
2 |
JPEG 1920x1080 @ 1fps |
JPEG 抓图 |
V4 |
3 |
NV12 640x480 @ 10fps |
运动检测 |
V5 |
4 |
RGB 416x416 @ 10fps |
NN AI 检测 |
编译时选项:
#define V1_ENA 1 /* enable V1 channel */
#define V2_ENA 1 /* enable V2 channel */
#define V3_ENA 1 /* enable V3 channel */
#define V4_ENA 1 /* enable V4 channel */
#define V5_ENA 1 /* enable V5 channel */
#define AINR_ENA 1 /* AI noise reduction */
#define MP4_ENA 1 /* MP4 SD card recording on V1 */
#define NN_ENA 0 /* NN object detection on V5 */
#define NN_OSD_ENA 1 /* draw NN detection result on V2 stream */
#define V5_RGB_WIDTH 416
#define V5_RGB_HEIGHT 416
V2 输出目标不再由 VAPP 命令选择。请先通过 VIDEO list 选择 UVC entry 或 RTSP entry,再执行该示例。UVC entry 需要 CONFIG_USBD_UVC=1。RTSP entry 需要 CONFIG_LWIP_LAYER=1,并会等待 Wi-Fi 连接完成后再打开 rtsp2_module。
NN 模型选择:
/* Supported models: yolov4_tiny, yolov7_tiny, nanodet_plus_m */
#define NN_MODEL_OBJ yolov4_tiny
#define NN_MODEL_NAME "vfs:/yolov4_tiny_asymu8.nb" /* or "sd:yolov4_tiny_asymu8.nb" */
#define NN_WIDTH 416
#define NN_HEIGHT 416
如果所选 .nb 包含预处理或缩放 layer,请将 V5_RGB_WIDTH / V5_RGB_HEIGHT 设为实际 V5 RGB 输出尺寸,并维持 NN_WIDTH / NN_HEIGHT 为 detector 的逻辑输入尺寸。示例会将两组数值都传给 VIPNN:
static nn_data_param_t nn_input_params = {
.img = {
.width = V5_RGB_WIDTH,
.height = V5_RGB_HEIGHT,
.model_width = NN_WIDTH,
.model_height = NN_HEIGHT,
},
.codec_type = AV_CODEC_ID_RGB888
};
NN 物体类别过滤:
该示例支持依照 class ID 过滤检测到的物体:
static int desired_class_list[] = {0}; /* 0: person (COCO dataset) */
只有符合 desired_class_list[] 中 class ID 的物体才会显示。可参考 COCO dataset class labels 获取可用的 class ID。
NN OSD overlay 功能:
启用 NN_OSD_ENA 后,该示例会使用 nn_osd_group API 将检测到的物体 bounding box 绘制到 V2 串流通道。该 group 会为每个 color layer 管理一个 1bpp bitmap canvas,自动分配 hardware OSD index,并可在 NN callback 停止时通过 watchdog 清除过期 overlay。
OSD group 会初始化一次(lazy initialization,可每帧安全调用),并在每次 callback 中更新:
static nn_osd_group_t osd_group;
static const nn_osd_layer_config_t osd_layer[] = {
{
.stream_id = V2_STREAM_ID,
.alpha = 128, /* OSD alpha */
.y = 0, /* green Y */
.u = 0, /* green U */
.v = 0, /* green V */
},
};
/* In the NN display callback: */
nn_osd_group_init(&osd_group, im_w, im_h, osd_layer, 1, 0 /* no watchdog */);
nn_osd_group_lock(&osd_group);
nn_osd_group_clear(&osd_group);
nn_osd_coord_map_t map;
nn_osd_coord_map_init(&map, im_w, im_h, im, NN_OSD_SCALE_STRETCH);
/* for each detection: */
nn_osd_canvas_t *canvas = nn_osd_group_canvas(&osd_group, NN_OSD_LAYER);
nn_osd_coord_map_bbox(&map, rx0, ry0, rx1, ry1, &xmin, &ymin, &xmax, &ymax);
nn_osd_draw_rect(canvas, xmin, ymin, xmax, ymax, 10);
nn_osd_draw_stringf(canvas, xmin, ymin - 24, 3, "%s %d", label, score);
nn_osd_group_flush(&osd_group);
nn_osd_group_unlock(&osd_group);
运行时测试命令:
联合测试示例也会注册 CmdApVideoAppTest(),并通过 VAPP console command 暴露。以下命令用于在不重新编译 firmware 的情况下进行动态验证:
与 encoder 相关的运行时命令只覆盖 bitrate/QP、GOP 与 force-I-frame,不会修改只适合初始化阶段设置的 encoder header、VUI、HRD 或 profile-level 配置。其他 VAPP command,例如 OSD、AINR 与 NN 控制,是示例层级的运行时控制,不会修改 encoder init-only 设置。
命令 |
说明 |
|---|---|
|
在 runtime 修改 channel |
|
修改 channel |
|
修改 channel |
|
强制通道 |
|
手动更新 hardware OSD bitmap 参数。例如: |
|
全局关闭或启用 AI noise reduction。例如: |
|
暂停或恢复 VIPNN inference。当 |
|
停止 joint test 示例,并以反向顺序 de-initialize linker/module。 |
备注
VAPP command 不再用于切换 V2 sink。如需切换,请先使用 VAPP stop 停止当前示例,再通过 VIDEO list 与 VIDEO run [n] 启动 UVC 或 RTSP joint-test entry。
FileSaver module:
当某个 channel 的主要输出通过编译时 flag 关闭时,该 channel 可能会 fallback 到 filesaver_module consumer。MP4_ENA=0 时,V1 会使用 FileSaver;V3(JPEG snapshot)与 V4(NV12 motion detection)始终路由到 FileSaver;NN_ENA=0 时,V5 会路由到 FileSaver。V2 在此示例中不再具有 none / FileSaver sink:所选 entry 会将 V2 路由到 UVC 或 RTSP。