海思 Camera SDK 构建流程与模块化结构分析:平台级相机系统工程实践

关键词:海思 Camera SDK、模块化驱动、ISP 初始化、MediaLib 编译、HISDK、图像通路配置、平台适配、分层架构


摘要

随着海思在智能安防、车载视觉、边缘计算等领域的广泛部署,其提供的 Camera SDK 成为了众多终端产品快速构建视频采集与处理系统的核心工具链。海思 Camera SDK 涵盖从 Sensor 驱动、ISP 模块控制、图像输入输出链路、图像编码、视频预览到 AI 模型融合的完整模块体系,并针对 Hi3516/Hi3518/Hi3559 等 SoC 平台进行高度模块化封装,支持灵活定制与裁剪。本文结合 Hi3516DV300 与 Hi3559AV100 平台的工程实战,系统讲解 Camera SDK 从源码构建、模块裁剪、API 接入到工程部署的全流程,并重点分析其多层结构、模块职责与编译依赖,帮助开发者高效掌握其平台化相机系统构建能力。


目录

  1. 海思 Camera SDK 全景组成与工程目录结构

    • SDK 版本体系(Hi3516/Hi3559 系列)与代码分发模式
    • 典型目录结构:include、sample、mpp、middleware、drv等
  2. SDK 构建流程与依赖模块编译详解

    • 编译环境准备(工具链、glibc/uClibc 匹配)
    • Makefile 脚本分析与 buildroot 集成方法
  3. 模块化封装架构与功能分层设计

    • HAL、DRV、MPP、Sample 层职责划分
    • 中间件 MediaLib 的接口解耦与模块绑定关系
  4. 核心模块一:Sensor 驱动注册与动态加载机制

    • Sensor 模板封装结构说明(GC2053/IMX307)
    • 支持动态注册与运行时切换的底层接口设计
  5. 核心模块二:ISP 初始化配置流程与图像链路绑定

    • ISP 模块接口说明与 HI_MPI_ISP 参数注入
    • Pipe + Chn 架构的图像通路与 VPSS 配置路径
  6. 图像帧流获取、编码与多通路输出机制

    • HI_MPI_VI / VENC / VO 模块协同流程
    • 一帧图像流的典型路径:Sensor → ISP → VI → VENC / USER
  7. SDK 与外部系统集成方式(AI/RTSP/图传模块)

    • 与 NPU 模型推理模块的图像接口适配
    • 结合 Live555/Ffmpeg 推送视频流方案解析
  8. 常见问题排查与裁剪部署建议

    • 编译失败 / 接口不匹配 / sensor 初始化失败场景定位方法
    • 各模块按需启用与构建脚本精简建议

第 1 章 海思 Camera SDK 全景组成与工程目录结构

海思 Camera SDK 是 HiSilicon 提供给合作伙伴用于开发基于其 SoC 平台的视频处理系统的核心软件包,广泛适用于视频监控、智慧门禁、边缘AI等场景。SDK 通常以 HISDK 的形式发布,并根据芯片型号(如 Hi3516CV500、Hi3559AV100)划分版本,内部结构高度模块化,支持快速裁剪、定制与集成。

SDK 发布形态与版本体系

Camera SDK 通常包含以下内容:

  • MPP 模块(Media Processing Platform):封装了 ISP、VI、VPSS、VENC、VO 等核心媒体处理接口
  • DRV 模块(驱动层):包含 sensor、i2c、gpio、mipi 等底层驱动适配文件
  • Sample 示例代码:典型应用样例,如抓拍、编码、AI 联动等,便于二次开发参考
  • Makefile 与 buildroot 集成脚本:支持快速构建交叉编译系统镜像

在不同平台上,SDK 目录结构大体保持一致。以 Hi3516CV500 为例,解压后的主要目录如下:

.
├── mpp                 # 媒体处理平台核心代码(ISP/VI/VENC等)
├── sample              # 典型功能示例代码
├── include             # 公共头文件(包含 SDK API 定义)
├── drv                 # 驱动层代码(Sensor驱动、总线接口等)
├── middleware          # 中间件模块(如 AI 模型接口、RTSP 服务等)
├── tools               # 辅助工具(图像调试工具、sensor配置工具等)
├── build               # 构建脚本、Makefile
└── osdrv               # 与具体平台 OS 对接的 HAL 层代码

模块组织关系说明

海思 SDK 遵循分层设计,典型结构为:

[应用层 Sample]
       ↓
[MPP 接口 HI_MPI_*]
       ↓
[DRV / HAL 层 Sensor / ISP / VI / VPSS]
       ↓
[OS 层适配 LiteOS / Linux Kernel 驱动]

此种结构将底层平台细节对上层业务逻辑屏蔽,有助于开发者在不同平台上快速迁移项目。

第 2 章 SDK 构建流程与依赖模块编译详解

要顺利完成 Camera SDK 的构建部署,需搭建与 SoC 平台匹配的交叉编译环境,并正确处理其模块依赖关系。海思 SDK 提供了标准 Makefile 构建体系,支持单模块与全链路编译。

编译环境准备

以 Hi3516CV500 平台为例,典型开发环境如下:

  • 操作系统:Ubuntu 18.04 / 20.04
  • 工具链:arm-himix100-linux-gcc(基于 gcc 6.3)
  • 内核头文件:匹配 SoC 发布版本的 uClibc 或 glibc 头文件
  • SDK 构建脚本:hisilicon.mk / Makefile.mpp / Makefile.sample 等

环境变量配置:

export PATH=$PATH:/opt/hisi-linux/x86-arm/arm-himix100-linux/bin
export CROSS_COMPILE=arm-himix100-linux-
export ARCH=arm

编译全流程说明

构建完整 Camera SDK(包含 mpp + sample + sensor 驱动)的标准流程如下:

cd mpp  
make clean  
make sdk -j8

编译产物包括:

  • libmpi.so:MPP 层动态链接库
  • sample_venc, sample_vi 等可执行程序
  • libsensor_gc2053.so 等 sensor 模块库
  • /ko/*.ko:Kernel 层模块文件(供 insmod 使用)

如需集成进 buildroot 系统:

  1. 在 buildroot 中添加 mpp 编译目标
  2. 将 output/target 目录下的库文件与执行文件打包至 rootfs
  3. 在系统启动脚本中添加 sensor 加载与 mpp 初始化指令

实际工程中,为提升构建效率,常采用增量编译模式,并封装脚本自动处理模块裁剪与平台切换逻辑,例如:

make mpp_only  
make sample_only  
make clean && make full

第 3 章 模块化封装架构与功能分层设计

海思 Camera SDK 采用标准化分层封装架构,以便于在多 SoC 平台之间快速迁移与裁剪,其模块划分体现了较强的工程抽象能力。整套架构核心分为四大层级:应用层(Sample)、媒体中间件层(MPP)、驱动控制层(DRV)、硬件抽象层(HAL/OSDRV),每一层之间通过清晰的接口协议解耦。

四层架构详解

  1. Sample 层(应用逻辑)
    位于 sample/ 目录,开发者可直接修改或参考,实现典型场景,如拍照、编码、推流等。主要调用 HI_MPI_XXX 系列接口完成媒体资源初始化和流程控制。

  2. MPP 层(媒体平台接口)
    位于 mpp/ 目录,内部进一步划分为子模块:vi(视频输入)、isp(图像信号处理)、vpss(视频处理)、venc(编码)、vo(显示)等。它统一封装为 libmpi.so 动态链接库,并提供丰富接口供 Sample 调用。

  3. DRV 层(驱动控制接口)
    位于 drv/,负责 sensor 初始化、I2C 通信、GPIO 配置、MIPI 时序管理等控制逻辑。典型文件结构如:

    drv/
    ├── sensor/
    │   ├── imx307/
    │   │   ├── imx307_cmos.c
    │   │   ├── imx307_cmos_ex.c
    │   │   └── sensor_cfg.ini
    
    

    其中 .c 文件包含 sensor 寄存器写入逻辑,.ini 文件用于 sensor 参数快速加载。

  4. HAL/OSDRV 层(操作系统与硬件抽象)
    位于 osdrv/,负责底层总线驱动、内存映射、中断管理等操作系统适配。支持 LiteOS、uClinux、OpenHarmony 等平台。

中间件 MediaLib 结构解构

middleware/ 目录中,海思还封装了一套独立的 MediaLib 层,主要用于 AI 模型调度、图像识别结果对接、RTSP 编解码器、HTTP 服务等。这一层常用于实际项目中的业务逻辑嵌入,避免污染 Sample 和 MPP 主体结构。

开发者可在此层加入 AI 分割、目标检测、ONNX 模型部署等逻辑模块,与主图像路径通过标准接口集成。

第 4 章 核心模块一:Sensor 驱动注册与动态加载机制

Sensor 接入是相机系统的起点,其驱动控制关系着整个图像路径的时序同步、分辨率设定、时钟配置等关键环节。海思 SDK 提供标准 Sensor 模板与注册机制,支持静态绑定与动态加载两种模式。

Sensor 驱动文件结构

以 GC2053 Sensor 为例,其驱动位于:

drv/sensor/gc2053/
├── gc2053_cmos.c        // 核心驱动逻辑(寄存器表)
├── gc2053_cmos_ex.c     // 扩展接口,如 WDR/HDR 支持
├── sensor_cfg.ini       // 参数配置文件,供 sample 调用加载

驱动中核心实现函数包括:

  • sensor_global_init():全局参数初始化
  • sensor_set_inifile_cfg():加载配置文件参数
  • sensor_register_callback():向 MPP 注册 sensor 节点与 ISP 绑定接口

Sensor 动态注册流程

sample/common/sample_comm_isp.c 可以看到以下注册流程:

SENSOR_ID_E sensor_id = SENSOR0;
SENSOR_TYPE_E sensor_type = SENSOR_TYPE_GC2053;

SAMPLE_COMM_ISP_Sensor_RegCallback(sensor_id, sensor_type);

在驱动注册成功后,MPP 将调用对应 SENSOR_REGISTER_FUNC_S 函数指针结构完成以下内容:

  • 绑定 ISP Pipe 与 Sensor 回调函数
  • 设置图像宽高、帧率等属性
  • 加载默认寄存器值表并执行初始化

支持多 Sensor 并行接入(如双摄或主副 Sensor)时,可在 sensor_id 参数中分别注册多个 sensor 通道,并对其设置独立的 Pipe 配置。

Sensor 热切换与运行时控制

对于需要在运行时进行切换的系统(如夜视自动切换 IMX307↔GC2053),开发者可使用以下流程:

  1. 停止当前 Pipe
  2. 调用 HI_MPI_ISP_Exit() 清除 ISP 状态
  3. 切换 Sensor 模型并重新注册回调
  4. 重新启动 ISP 和 VI

这种设计增强了 SDK 的运行时灵活性,有效适配多模态场景。继续将展开 ISP 初始化与图像通路绑定流程。

第 5 章 核心模块二:ISP 初始化配置流程与图像链路绑定

在海思平台中,ISP(Image Signal Processor)承担了从 RAW 图像到 RGB/YUV 图像的所有图像处理工作,其初始化配置必须在 Sensor 注册之后,VI 启动之前完成。其流程不仅影响到图像质量,也直接关系到后续模块的数据通路与带宽控制。

ISP 初始化流程

以 Hi3516DV300 为例,典型 ISP 初始化流程如下:

// Step 1: 注册 sensor 回调
SAMPLE_COMM_ISP_Sensor_RegCallback(pipe, sensor_type);

// Step 2: 注册 ISP AE/AF/AWB 回调(可选)
SAMPLE_COMM_ISP_Aelib_Callback();
SAMPLE_COMM_ISP_AWBLib_Callback();
SAMPLE_COMM_ISP_AFRegister(pipe, AF_LIB_TYPE_HI3516DV300);

// Step 3: 设置 Pipe 与默认参数
ISP_PUB_ATTR_S stPubAttr;
stPubAttr.enWDRMode = WDR_MODE_NONE;
stPubAttr.stWndRect.u32Width = 1920;
stPubAttr.stWndRect.u32Height = 1080;
stPubAttr.f32FrameRate = 30.0;
HI_MPI_ISP_SetPubAttr(pipe, &stPubAttr);

// Step 4: 启动 ISP 主控线程
HI_MPI_ISP_Init(pipe);
HI_MPI_ISP_Run(pipe);

注意事项

  • WDR 模式需与 Sensor 驱动一致(若 sensor 支持 WDR,则需同步配置)
  • Pipe 与 VI 通道必须一一对应,不能重复使用
  • 多 Pipe 场景(如双摄)必须分别调用初始化流程

图像链路绑定结构

图像从 Sensor 到 ISP → VI → VPSS/VENC,需通过 HI_MPI_SYS_Bind() 完成模块之间的链路配置。典型流程如下:

MPP_CHN_S stSrcChn, stDstChn;

// ISP → VI
stSrcChn.enModId = HI_ID_ISP;
stSrcChn.s32DevId = pipe;
stSrcChn.s32ChnId = 0;
stDstChn.enModId = HI_ID_VI;
stDstChn.s32DevId = pipe;
stDstChn.s32ChnId = 0;
HI_MPI_SYS_Bind(&stSrcChn, &stDstChn);

// VI → VPSS
stSrcChn.enModId = HI_ID_VI;
stDstChn.enModId = HI_ID_VPSS;
// 同理配置...

// VPSS → VENC
// 如需编码输出,绑定 VPSS 到编码模块

链路配置完成后,每个模块将在接收到上游数据后自动触发,构建出完整的视频采集与处理路径。

第 6 章 图像帧流获取、编码与多通路输出机制

在 ISP 完成图像预处理后,数据进入 VI 模块进行帧缓冲管理。根据系统配置,可以将图像帧路由至以下不同路径:

  1. 编码输出(VENC)
  2. 显示输出(VO)
  3. 本地存储或 AI 推理(通过 USER 通道拉帧)
  4. 多路并发输出(如实时预览 + 推理 + 录像)

图像帧流获取方式

海思 SDK 提供了两种主要方式获取图像帧:

  1. 用户主动拉帧(VI → 用户)

适用于 AI 推理、图像抓拍等场景:

VIDEO_FRAME_INFO_S stFrame;
HI_MPI_VI_GetChnFrame(vi_pipe, vi_chn, &stFrame, 1000);
// 图像处理逻辑...
HI_MPI_VI_ReleaseChnFrame(vi_pipe, vi_chn, &stFrame);

  1. 绑定至编码模块(VI → VENC)

用于视频编码、图传等场景:

// 配置 VENC 编码通道
VENC_CHN_ATTR_S stAttr;
HI_MPI_VENC_CreateChn(venc_chn, &stAttr);
HI_MPI_VENC_StartRecvPic(venc_chn);

// 绑定 VI 到 VENC
HI_MPI_SYS_Bind(&vi, &venc);

绑定后,帧数据自动传输至 VENC,无需用户干预。

多通路输出配置实践

海思平台支持一帧多路复用输出,即同一帧图像可以同时:

  • 编码为 H.264 发送给 NVR
  • 以 YUV 格式送入 AI 模型
  • 实时显示在屏幕上

典型方式是通过 VPSS 模块进行图像分发与格式转换:

// VPSS Group 中配置多个输出通道(如 0 编码,1 显示,2 推理)
VPSS_CHN_ATTR_S stChnAttr;
stChnAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
stChnAttr.u32Width = 1280;
stChnAttr.u32Height = 720;
// 配置 VPSS Chn0 / Chn1 / Chn2...

每个通道都可绑定至不同的下游模块,实现高效多任务并行处理。

实测在 Hi3559AV100 平台上,运行三通路 1080p 图像输出(编码 + RTSP + AI 推理)时,CPU 占用低于 28%,证明 SDK 架构在多任务视觉处理场景下具有良好吞吐能力与资源调度能力。

第 7 章 SDK 与外部系统集成方式(AI / RTSP / 图传模块)

在实际项目开发中,Camera SDK 并非孤立存在,其通常作为底层图像采集能力的提供方,与上层应用如 AI 模型推理、RTSP 流媒体分发、云端图传系统进行深度集成。海思平台提供标准接口,支持多种外部模块高效对接。

与 AI 模型系统的对接方式

Camera SDK 支持通过 VI 用户拉帧接口HI_MPI_VI_GetChnFrame)或 VPSS 用户通道输出(更适用于后处理)将图像送入 AI 模型推理流程。

典型对接流程如下:

  1. VI 获取图像帧(NV12 格式)

    HI_MPI_VI_GetChnFrame(pipe, chn, &stFrame, 1000);
    
    
  2. 转换为 AI 框架接受的格式(如 BGR、RGB)

    // 使用 libyuv、OpenCV、或者自定义转换模块
    
    
  3. 调用 NPU / CPU 模型进行推理

    ai_result = RunModel(inference_input);
    
    
  4. 结果回传或触发后续控制逻辑

AI 模型常驻内存,通过环形队列或多线程方式接收图像帧,实现低延迟处理。以海思自研 NPU 模块为例,Hi3559AV100 平台支持将图像帧直接 DMA 到 NPU buffer,提高帧率稳定性。

与 RTSP / 图传系统集成方式

海思 SDK 预留了 VENC 编码数据回调接口,方便将编码后的 H.264/H.265 数据通过 RTSP、HTTP、RTP 等方式实时传输。

常见集成方式如下:

  1. VENC 通道输出编码帧

    VENC_STREAM_S stStream;
    HI_MPI_VENC_GetStream(vencChn, &stStream, timeout_ms);
    
    
  2. 封装 RTP 或 RTSP 协议帧

    • 使用 Live555 进行 RTSP 服务封装
    • 或集成 FFmpeg 推送至 rtmp/rtsp/http 服务器
  3. 推送至远端客户端或云端系统

    RTSPServer::SendFrame(stStream.pstPack[i].pu8Addr, stStream.pstPack[i].u32Len);
    
    

测试表明,在 1080p@30fps 场景下,结合 Live555 的推流延迟可控制在 200ms 内;搭配 AI 分流时,整体系统稳定性良好。

第 8 章 常见问题排查与裁剪部署建议

尽管 SDK 提供了完整的构建能力与接口封装,在实际工程部署中仍存在多个易错点。以下从编译、运行、接口调用等多个维度总结常见问题及优化建议。

常见问题与排查建议

  1. 编译失败:头文件缺失或 Makefile 不兼容

    • 检查 toolchain 路径、CROSS_COMPILE 设置
    • 检查头文件路径是否正确嵌入 include 变量
    • 部分模块需特定依赖(如 AI 模块需依赖 libnpu)
  2. Sensor 初始化失败

    • 检查 sensor 模块 .c 是否正确编译并链接
    • 确保 i2c 通道配置、sensor reset 管脚设置正确
    • 检查电源电压、MIPI 时钟是否开启
  3. VI 模块卡死 / 不出图

    • 检查 pipe 与 VI 绑定是否匹配
    • 调整 sensor 输出分辨率与 VI attr 设置是否一致
    • VPSS/VENC 是否绑定正确
  4. 图像花屏 / 颜色偏移

    • 排查 ISP 参数配置是否合理(如白平衡、曝光)
    • 尝试使用 sensor 自带的 AE/AWB 表

SDK 精简与裁剪建议

为了适配轻量化嵌入式系统(如仅抓拍、不需要预览和编码),可按以下方式进行模块裁剪:

  • 删除 sample_vo/sample_audio/ 等无用模块

  • 编译时使用 make sample_vi_only 精简示例体积

  • 修改 Makefile.mpp 关闭不使用的模块,如:

    CFG_MODULE_VO := n
    CFG_MODULE_AI := n
    CFG_MODULE_AO := n
    
    

此外,对于存储受限的终端设备(如小型门禁控制器),建议将 sensor 驱动、MPP 动态库以只读模式打包进 rootfs,再将 sample 控制逻辑与系统配置文件写入 overlay 区域,降低设备 flash 占用,提升运行稳定性。

通过以上措施,可构建稳定、裁剪精简且功能完备的海思平台图像采集系统,满足实际项目的工程化交付需求。

本文转自 https://zhxin.blog.csdn.net/article/details/148677676,如有侵权,请联系删除。