2、高通平台Camera软件架构:Camera HAL、Chi架构、Usecase与Pipeline
做多路编码延迟优化,第一件事不是调参数,而是搞清楚软件架构。我见过太多人一上来就改QOS、调线程优先级,结果发现根本走错了路径——问题出在Pipeline的拓扑结构上。
高通平台的Camera软件架构,说白了就是三层:Camera HAL、Chi架构、以及上层的Usecase与Pipeline。这三层各管各的事,但又紧密耦合。咱们一层层拆开看。
2.1 Camera HAL:硬件抽象层
Camera HAL是Android Camera框架与硬件之间的桥梁。高通平台用的是CamX(Camera eXtension)作为HAL实现。CamX不是简单的接口封装,它内部有一套完整的模块化框架。
我习惯把CamX分成几个核心模块:
- CSL(Camera Service Layer):直接跟驱动打交道,负责buffer分配、stream on/off、request提交。
- HAL Interface:实现Android标准的
camera3_device_ops_t,处理process_capture_request、flush等回调。 - Session管理:管理多个camera session的生命周期,每个session对应一个Usecase。
举个例子,当你调用camera3_device_t->ops->process_capture_request()时,CamX内部会做这些事情:
// CamX内部简化流程
process_capture_request(request) {
// 1. 解析request中的metadata
// 2. 根据Usecase找到对应的Pipeline
// 3. 将request拆分成多个sub-request(每个sensor/ISP一个)
// 4. 通过CSL提交到驱动
// 5. 等待结果回调
}
2.2 Chi架构:Camera Hardware Interface
Chi(Camera Hardware Interface)是高通在CamX之上加的一层抽象。它的核心作用是解耦——让OEM可以定制算法和pipeline,而不需要动HAL层代码。
Chi架构里,有几个关键概念:
| 概念 | 说明 | 我踩过的坑 |
|---|---|---|
| ChiNode | 算法节点,比如美颜、HDR、EIS | 多路编码时,每个ChiNode都会引入额外延迟,尤其是需要GPU/CPU的节点 |
| ChiPipeline | 由多个ChiNode串联成的处理链路 | Pipeline深度直接影响延迟,我见过有人把10个Node串在一起,延迟直接翻倍 |
| ChiSession | 一个完整的拍照/录像会话 | 多路场景下,Session之间的资源竞争是隐藏的坑 |
| ChiUsecase | 定义业务场景,比如Preview、VideoRecord、Snapshot | Usecase配置错了,Pipeline拓扑就全错了 |
Chi架构的设计哲学是插件化。每个ChiNode可以独立加载、卸载,OEM可以写自己的Node替换高通默认的。但这也带来了一个问题——Node之间的数据传递开销。
ChiBufferManager做zero-copy传递。
2.3 Usecase与Pipeline:业务场景到处理管线的映射
Usecase是Chi架构里最上层的概念。它定义了你要做什么——是预览、录像、拍照,还是多路编码。每个Usecase对应一个或多个Pipeline。
Pipeline则是怎么做——它描述了数据从sensor到最终输出的完整路径。一个典型的Pipeline包含:
- Sensor Node:从硬件获取raw数据
- IFE(Image Front End):做Bayer处理、降噪、缩放
- IPE(Image Processing Engine):做颜色校正、伽马、锐化
- ChiNode(可选):OEM自定义算法
- Encoder Node:视频编码
多路编码场景下,Usecase的配置是关键。我举个例子:
// 多路编码Usecase配置示例
UsecaseConfig {
name: "MultiEncoder_4K_1080p",
streams: [
{ id: 0, resolution: 3840x2160, format: NV12, fps: 30 },
{ id: 1, resolution: 1920x1080, format: NV12, fps: 30 },
{ id: 2, resolution: 1920x1080, format: NV12, fps: 30 },
{ id: 3, resolution: 1920x1080, format: NV12, fps: 30 }
],
pipeline: {
// 注意:这里可以配置多个pipeline共享同一个sensor
shared_sensor: true,
ife_output: [ "4K", "1080p_1", "1080p_2", "1080p_3" ]
}
}
这里有个重要的设计决策:是否共享sensor。共享sensor意味着所有stream从同一个sensor取数据,然后通过IFE做多路缩放输出。不共享的话,每个stream独立占用一个sensor。
2.4 架构全景图
说了这么多,咱们用一张图把整个架构串起来。这张图是我做优化时经常参考的,每次调延迟都会先对着它走一遍。
2.5 多路编码场景下的架构要点
搞清楚了架构,咱们回到多路编码延迟优化这个主题。我总结几个关键点:
- Usecase配置是第一关:多路编码的Usecase配置决定了Pipeline的拓扑。配置错了,后面再怎么优化也白搭。我建议在项目初期就确定好Usecase的stream数量和分辨率组合。
- ChiNode越少越好:每个ChiNode都是延迟的累加器。多路编码场景下,尽量用硬件ISP的能力,少用CPU/GPU的ChiNode。如果非用不可,考虑用
ChiBufferManager做zero-copy。 - Pipeline深度要控制:Pipeline每多一级,延迟就多一级。我见过有人把美颜、HDR、EIS、人脸检测全串在一个Pipeline里,延迟直接飙到80ms。多路编码时,建议把非必要的Node拆到另一个Usecase里。
- 资源竞争要提前规划:多路编码意味着多个Pipeline同时运行,它们会竞争ISP、DSP、内存带宽。我建议在ChiSession层面做资源隔离,比如给高优先级的stream分配独立的ISP管线。
嗯,架构这部分就讲到这里。记住一句话:架构决定延迟的上限,优化决定延迟的下限。搞懂了Camera HAL、Chi架构、Usecase和Pipeline,你才有资格去谈优化。