跳转至

应用框架

应用框架(Application Framework)位于应用层与组件层之间,将媒体、AI、录像等底层能力收敛为一组功能级 API:业务程序无需了解 VI→VPSS→VENC 的初始化顺序,一次调用即可完成整条通路。同一组 API 支持同进程直调与跨进程 IPC 两种形态——媒体管道始终单一进程归属,业务程序、命令行工具与脚本以客户端身份共用同一路硬件,互不干扰。

读者对象:在 Hi-AIoT-Solution 上开发业务的嵌入式应用开发者。 前置条件:已阅读《软件架构》。

1 设计动机与收益

面临的问题 设计做法 对开发者的价值
底层接口粒度细、初始化顺序有约束 收敛为功能级 API,内部按序初始化并管理状态 减少样板代码,无需掌握初始化顺序
媒体管道对 MPP 是独占资源 管道只在单一进程建立 多个应用、工具与脚本共享同一路摄像头
命令行、脚本、业务程序均需操作硬件 各类调用方接入同一套 IPC 通道 无需为每种调用方单独封装
多客户端接入,需防越权与滥用 SERVER 端客户端注册鉴权:模块权限隔离、连接数量配额 越权调用被拒,连接数量受控,各端互不干扰
跨进程传输码流开销大 以地址传递替代数据拷贝 大码流跨进程传输开销低
嵌入式存储与内存受限 Kconfig(COMP_FW_API_*)按需编译 只包含实际使用的能力

以上设计共同服务于:同一套 API 支撑单进程直调与跨进程 IPC 两种部署形态。

2 架构设计

2.1 总体框架

应用框架是应用与底层能力之间的一层:向上提供统一的 api_* 接口,向下对接组件层与芯片 SDK。调用方经三条路径抵达框架:业务程序在 SERVER 层内直调;命令行工具 fw_cli 以 CLIENT 身份经 UDS 接入;micropython 技能脚本经 Python 封装接口调用。AI Agent(zeroclaw)产生的操作由模型按 SKILL.md 执行 micropython 技能脚本(如 capture_picture.py),经 Python 封装接口与命令行工具汇入同一 CLIENT 通道——无论何种调用方,抵达的都是同一组 API 与同一路硬件(见图 1)。

应用框架总体结构图

图 1 应用框架总体结构。自上而下为图例、应用层、应用框架、组件层。应用框架内部由 CLIENT 进程与 SERVER 层两个子框构成,经 UDS 通信层对接。CLIENT 进程有两条入口:CLI Proxy(fw_cli)接入 Client API 层;AI Agent(zeroclaw)调用 MicroPython 执行技能脚本(如 capture_picture.py),经 python_api 封装接口汇入同一 Client API 层,再经消息处理层、UDS Client 通信层抵达 SERVER 层。SERVER 层由应用层的业务程序启动,内部链路为 UDS Server 通信层(含客户端注册与鉴权)→ 直调 API 层 → 业务处理 → 消息处理层 → 组件适配层,最终对接组件层。

框架的设计取向可归纳为三点:

设计要点 说明
统一 API 音视频、AI、录像等能力收敛为功能级接口,应用只依赖框架头文件
双运行形态 同一组 API 支持 DIRECT(本进程直调)与 CLIENT/SERVER(跨进程)两种部署方式
单一硬件归属 媒体管道只在单个进程建立,业务、工具与脚本通过 IPC 共用同一路硬件

2.2 分层结构

框架源码位于 components/media/framework/,依赖方向单向:应用层 → 框架层 → 组件层。应用框架内部自上而下分为以下几层:

分层 组成
接入层 CLI Proxy(fw_cli)、MicroPython(执行技能脚本,如 capture_picture.py)
Python 封装接口 python_api 封装的接口
Client API 层 CLIENT 进程统一入口,CLI 与 Python 两条路径在此汇合
消息处理层 同步与异步消息分发
UDS 通信层 UDS Client ↔ UDS Server,服务端含客户端注册与鉴权
直调 API 层 SERVER 层内直调接口
业务处理 业务逻辑处理
组件适配层 对接组件层

2.3 关键设计

同接口、双实现:业务代码只维护一份。链接 api_media 即为本进程直调,链接 api_media_client 即为跨进程调用,业务代码无需修改。

控制与数据通道分离:控制类小消息经 Unix Domain Socket 同步或异步传递;编码码流等大数据由 SERVER 下发缓冲地址,调用方映射后直接读取,不产生数据拷贝;编码回调与 AI 结果跨进程对上层透明。

场景化参数:音视频参数预置为场景(CAPTURE、FACTORY_LCD、ZEROCLAW、DUAL_SENSOR 等),一次初始化即可完成整条通路的参数选择,无需逐项配置 ISP 与 VENC 参数。

3 能力清单

模块 提供的能力 跨进程
api_media 媒体系统、音视频采集/编解码/显示、抓拍与 OSD 支持
api_aidetect AI 目标检测(人脸、人体、车辆、宠物等) 支持
api_fr 人脸识别与人脸库管理 支持
api_human_track 人体/目标跟踪与结果叠加 支持
api_liveserver 点播服务,视频/音频推流 支持
api_record MP4 录像与 SD 卡存储 支持
api_webrtc WebRTC 点对点音视频对讲 支持

模块能力由 Kconfig 开关控制,仅编译实际使用的部分。接口参数与返回值见框架层接口文档。

4 使用指南

4.1 运行模式选择

适用场景 建议模式
单进程功能验证、对时延敏感 DIRECT
多调用方共享硬件,或需要命令行、脚本随时接入 CLIENT/SERVER
需要进程隔离:媒体栈故障不拖累业务进程,或按权限拆分部署 CLIENT/SERVER

两种模式使用同一组 API,业务代码无需修改;切换部署形态时更换链接库并调整初始化入口(CLIENT 需连接服务端端点,SERVER 需增加 channel_server_init)。

注意:同一时刻硬件管道只能归属一个进程。SERVER 内部同样基于直调实现建立管道,若再运行一个 DIRECT 应用,则两个进程重复初始化同一套硬件而发生冲突,二者不可同时运行。

4.2 编译配置

# 以 framework_media 示例为例,编译后得到 DIRECT / SERVER / CLIENT 三个可执行文件与 fw_cli
bash scripts/build.sh build --target cv610_ev_board samples framework_media

能力开关位于 components/media/framework/Kconfig(COMP_FW_API_MEDIA、COMP_FW_API_AIDETECT、COMP_FW_API_RECORD 等)。

4.3 调用方式

以抓拍一张 JPEG 为例,三类调用方的写法如下:

调用方 接入方式 抓拍调用
C 应用 包含 api_media.h;直连链接 api_media,跨进程链接 api_media_client hi_fw_media_capture_jpeg(0, "/tmp/photo.jpg", 1);
命令行 板端运行 fw_cli,以 CLIENT 身份连接服务端 ./fw_cli camera_capture /tmp/photo.jpg 1 0
MicroPython 使用 hi_media_encode 模块(CLIENT 构建) hi_media_encode.photo("/mnt/photo.jpg")

4.4 最小示例

# 板端:先启动服务端,媒体管道在其中建立
/root/sample_framework_media_server &

# 通过命令行代理抓拍(capture 场景的 JPEG 通道为 venc0)
./fw_cli camera_open capture
./fw_cli camera_capture /tmp/photo.jpg 1 0
./fw_cli camera_close
# 亦可使用 MicroPython:对应 micropython_sample 的 media_server,监听 /var/run/media_server/ipc_media.sock,与上例 framework_media(/tmp/media_pipeline.sock)各自独立
import hi_media_encode
hi_media_encode.init("/var/run/media_server/ipc_media.sock")
hi_media_encode.photo("/mnt/photo.jpg")
hi_media_encode.deinit()

4.5 注意事项

  1. SERVER 必须先于 CLIENT 启动,且调用方的 endpoint 需与服务端监听地址一致(fw_cli 默认 /tmp/media_pipeline.sock,MicroPython 默认 /var/run/media_server/ipc_media.sock)。
  2. 抓拍通道号需与已建立的场景匹配:capture 与 zeroclaw 场景使用 venc0,factory_lcd 场景使用 venc1;管道已由其它程序建立时,不应再执行 camera_open。

5 应用示例:Zeroclaw 场景

5.1 场景结构

apps/cv610_ev_board/references/zeroclaw_base 是 zeroclaw 智能体在 CV610 上的基础镜像案例,其形态为"一个媒体服务进程 + 多个业务客户端进程",可用于验证多客户端共享同一路音视频硬件。

服务端进程 zeroclaw_base_main 启动时建立以下通路并常驻:

通路 配置
视频 ZEROCLAW 场景,双 VENC:venc0 用于 JPEG 抓拍(VPSS chn1,768×448),venc1 用于 H.265 推流(VPSS chn0,2560×1440)
音频 ZEROCLAW 场景,双 AENC:h0 为 AAC,供推流取流;h1 为 OPUS,供本地语音;ADEC(MP3)→ AO 用于 TTS 播放
AI aidetect 直连初始化
IPC channel_server_init("/tmp/media_pipeline.sock", ...) 对外提供服务

上板后由 init 脚本按序启动:加载内核模块 → 启动 zeroclaw_base_main → 启动 push_stream。

接入同一服务端的客户端进程及其分工:

客户端 注册模块 用途
push_stream media 注册 VENC 与 AENC 回调,取 venc1 码流与 AENC h0 音频,推送 RTMP
local_voice media 注册 ACAP 回调获取 16 kHz PCM(供 KWS/ASR),启动 OPUS AENC h1;TTS 经 ADEC 下发播放
fw_cli media 命令行抓拍,ZEROCLAW 场景的 JPEG 通道为 venc0
zeroclaw 技能脚本 media MicroPython CLIENT 模式,capture_picture.py 抓拍、ai_component_skill 目标检测,显式指定 /tmp/media_pipeline.sock

5.2 服务端业务流程

sequenceDiagram
    participant C as 客户端进程
    participant S as 服务端 channel_server
    participant A as 权限上下文 client_auth
    C->>S: channel_client_init(endpoint)
    C->>S: MSG_CLIENT_REGISTER 声明所用模块
    S->>A: 分配模块 slot 并登记连接
    A-->>C: 返回 client_id
    C->>S: 业务消息(携带 client_id)
    S->>A: 校验 client_id、连接绑定与模块权限
    A-->>S: 校验通过
    S-->>C: 返回处理结果

流程说明:

  1. 服务端启动:channel_server_init(endpoint, &handle, module_count) 打开 Unix Domain Socket 并进入监听,建立权限上下文,并按编译开关自动注册内置模块的处理函数(media、liveserver、aidetect、fr、human_track、record),业务层无需手工注册。
  2. 接入连接:每 accept 到一个连接,服务端为其分配独立线程与 client_id。
  3. 客户端注册:客户端 channel_client_init(endpoint) 后发送 MSG_CLIENT_REGISTER 声明所需模块(各 api_*_client_init 已自动完成),服务端在该模块的客户端池中分配 slot 并返回 client_id。
  4. 请求校验:后续每条消息均需通过权限校验——client_id 有效、slot 已占用、连接与注册记录一致(防止跨连接重放)、消息所属模块在该客户端的权限掩码内;任一条件不满足则返回 CHN_EAUTH。
  5. 断开回收:连接断开时服务端触发断连通知并回收 slot,供后续客户端复用。

module_count 需与编译进服务端的模块数一致。zeroclaw_base 启用 media、liveserver、record、aidetect 共 4 个模块,故取 4;少于实际数量会导致服务端初始化失败。

5.3 权限模型与配置

维度 配置方式 说明
模块可见性 构建期 Kconfig(COMP_FW_API_*) 决定服务端注册哪些模块;未启用的模块不注册,客户端无法连接使用
客户端配额 client_auth_module_config_register(module_id, max_count) 每个模块维护独立的客户端池,默认上限为 media 4、liveserver 4、aidetect 8、fr 8、human_track 8、record 4,超出返回 CHN_EAUTH_MAX_CLIENTS
模块权限位 客户端注册时自动授予 客户端注册哪个模块即获得该模块的权限位,采用 1024 bit 掩码,校验复杂度为 O(1)
自定义权限上下文 channel_server_set_auth_context 默认配额不满足时,可自建 client_auth_context 后挂载;模块存在活跃客户端时不允许重配置

6 相关文档

  • 框架层接口总览:七个能力模块的接口说明
  • 《软件架构》:框架所在的分层结构
  • 示例目录:apps/cv610_ev_board/samples/framework_media/、apps/cv610_ev_board/samples/micropython_sample/、apps/cv610_ev_board/references/zeroclaw_base/