5.2 KiB
5.2 KiB
PRD_06 多硬件解耦计划(RK3588/Atlas/Jetson)
1. 背景与目标
当前工程深度绑定 RK3588(RKNN/RGA/MPP/DMA-BUF),限制了 Atlas、Jetson 等平台的接入。目标是在不破坏现有功能的前提下,通过接口解耦与默认实现保留现有行为,实现多硬件可插拔支持。
目标
- 以接口层抽象 推理、图像处理、编解码、缓冲区 四个核心模块。
- 默认实现保持 RK3588 行为与性能路径(零拷贝/DMA-BUF)。
- 逐步迁移现有节点,避免一次性大改。
非目标
- 不改变业务逻辑(检测/识别流程、RTSP/HLS 业务)。
- 不在本阶段引入新 UI/协议或跨平台发布流程。
2. 现状摘要(关键路径)
- 推理:
include/ai_scheduler.h,src/ai_scheduler.cpp(RKNN + DMA-BUF 输入) - 图像处理:
plugins/preprocess/preprocess_node.cpp(RGA 或 swscale) - 编解码:
plugins/input_rtsp/*,plugins/input_file/*,plugins/publish/*(MPP + FFmpeg 混用) - 缓冲:
include/frame/frame.h(dma_fd/planes/data_owner)
3. 总体方案
引入四类接口与默认实现:
- IInferBackend:推理后端抽象(默认 RKNN)
- IImageProcessor:图像预处理抽象(默认 RGA + swscale 兜底)
- IDecoder / IEncoder:编解码抽象(默认 MPP,必要时 FFmpeg)
- FrameBuffer:统一缓冲区语义与同步
所有接口通过工厂/配置注入,保持现有 JSON 配置兼容。
4. 实施步骤、里程碑与单元测试
Step 1:建立基础抽象与工厂
实施内容
- 新建
include/hw/下接口定义:i_infer_backend.h,i_image_processor.h,i_decoder.h,i_encoder.h,frame_buffer.h - 定义最小能力集:
- IInferBackend:
LoadModel,Infer,InferBorrowed - IImageProcessor:
Resize,CvtColor,Normalize - IDecoder/IEncoder:
Open,Send,Receive,Close - FrameBuffer:
Planes(),DmaFd(),SyncStart/End()
- IInferBackend:
- 新建工厂:
hw_factory.h/cpp,根据配置返回默认实现
关键里程碑
- 接口头文件编译通过;工程无行为变化
- 工厂默认返回 RK3588 实现(空实现也可先用占位)
单元测试(GTest)
HwFactory_Defaults_ReturnsRk3588ImplsFrameBuffer_Metadata_Preserved(dma_fd/planes 赋值一致性)
Step 2:推理模块解耦(RKNN → IInferBackend)
实施内容
- 将
AiScheduler包装为RknnInferBackend实现 ai_*节点依赖IInferBackend接口注入(保留默认行为)- 保留
InferBorrowed以支持零拷贝输入
关键里程碑
- 现有模型推理链路无回归,性能基准一致(同配置)
- RKNN 仍可多上下文并发
单元测试(GTest)
InferBackend_LoadModel_Smoke(加载模型返回成功)InferBackend_BorrowedInput_UsesDmaFd(检查传入 dma_fd 路径被调用)
Step 3:图像预处理解耦(RGA/CPU → IImageProcessor)
实施内容
- 抽取 RGA 路径为
RgaImageProcessor - 抽取 swscale 路径为
SwscaleImageProcessor preprocess_node仅面向接口调用
关键里程碑
use_rga=true/false行为完全一致- RGA 限流逻辑(RgaGate)保留
单元测试(GTest)
ImageProcessor_RgaVsSwscale_OutputShape(输出尺寸一致)ImageProcessor_ColorConversion_Nv12ToRgb(像素格式转换)
Step 4:编解码解耦(MPP/FFmpeg → IDecoder/IEncoder)
实施内容
MppDecoder,FfmpegDecoder实现IDecoderMppEncoder,FfmpegEncoder实现IEncoderinput_rtsp/input_file/publish/storage节点仅面向接口
关键里程碑
- RTSP 输入与 HLS 输出链路不变
- MPP 仍为默认路径,FFmpeg 作为兜底/平台适配
单元测试(GTest)
Decoder_Open_Close_SmokeEncoder_Open_Close_SmokeCodec_Pipeline_EncodeDecode_OneFrame(小尺寸样例帧)
Step 5:缓冲区抽象(Frame → FrameBuffer)
实施内容
- 新增
FrameBuffer,替代直接使用Frame的 dma_fd/data_owner Frame保留为业务结构,内部持有FrameBuffer- 统一 DMA 同步接口以便多硬件适配
关键里程碑
- DMA-BUF 与内存缓冲区均可通过统一接口访问
Frame兼容旧字段,最小侵入替换完成
单元测试(GTest)
FrameBuffer_Sync_NoCrashFrameBuffer_PlaneAccess_Consistent
Step 6:多硬件适配接入(Atlas/Jetson)
实施内容
- 新增
AtlasInferBackend/AtlasImageProcessor/AtlasCodec实现(占位/实验性) - 新增
JetsonInferBackend/JetsonImageProcessor/JetsonCodec实现 - 通过配置切换平台实现
关键里程碑
- 不影响 RK3588 默认路径
- 新平台可在单机完成 smoke 测试
单元测试(GTest)
HwFactory_SelectsBackend_ByConfigPlatformImpls_Smoke_Construct(构造/释放)
5. 风险与缓解
- 接口过宽导致迁移成本增加 → 控制最小接口集,逐步扩展
- 性能回退 → 保留 RK3588 默认实现与 DMA-BUF 快路径
- 迁移破坏现有节点 → 节点逐个替换,保持旧路径可回退
6. 验证与回滚
验证命令
scripts/build_host.sh
ctest --test-dir build/host --output-on-failure
回滚策略
- 以编译开关/配置切换回旧路径
- 保留 RK3588 实现作为默认后端