第三章 CHI架构详解:从CamX到客制化的桥梁
好,咱们今天聊聊CHI。说实话,这个架构刚出来的时候,我也懵了一阵子。毕竟从传统的HAL架构切过来,思维方式得变一变。但搞懂了之后,你会发现它其实挺优雅的。
3.1 CHI的由来:为什么要有它?
先说说背景。高通在骁龙845之前,用的是旧版HAL。那时候各家OEM要改相机逻辑,得直接改CamX的代码。你想想看,这有多痛苦?
- 耦合太深:OEM的客制化代码和芯片底层代码混在一起
- 升级困难:高通一升级底层,OEM就得重新适配
- 维护成本高:每个项目都要重新解bug,重复劳动
所以,CHI(Camera HAL Interface)就诞生了。它的核心思想很简单:把客制化逻辑从CamX中抽离出来。说白了,就是给OEM留了一个“插件接口”,你只需要写自己的override逻辑,不用动底层。
核心概念:CHI不是一个新的HAL,而是CamX之上的一个抽象层。它定义了OEM如何注入自己的配置和行为。
3.2 CHI与CamX的关系:谁是谁的爸爸?
这个问题我经常被问到。其实它们的关系是这样的:
| 层次 | 角色 | 谁在维护 |
|---|---|---|
| CamX | 底层驱动框架,处理硬件交互 | 高通 |
| CHI | 上层配置层,提供客制化接口 | 高通定义接口,OEM实现 |
| OEM客制化 | 基于CHI的override配置 | OEM自己 |
嗯,这里要注意:CamX是执行者,CHI是配置者。CamX负责调度硬件、处理buffer、管理pipeline。而CHI负责告诉CamX:“嘿,这个场景下,你要用这个参数。”
我在项目中遇到过一种情况:有个同事想直接在CamX里改曝光参数,被我拦住了。我说:“兄弟,你改CHI的override文件就行,别动底层。” 后来他试了试,果然简单多了。
3.3 CHI Override机制:客制化的灵魂
好,重点来了。CHI Override机制,说白了就是一套配置覆盖系统。它允许OEM在不修改CamX源码的情况下,改变相机的行为。
3.4.1 Override的三种方式
根据我的经验,Override主要有三种方式:
- XML配置覆盖:最常用,改配置文件就行
- Usecase覆盖:针对特定场景(如夜景、人像)
- Sensor覆盖:针对特定sensor的调优
举个例子,你想修改夜景模式的曝光时间。传统做法是改CamX的算法代码。但在CHI架构下,你只需要这样:
// 在override XML中配置
<Usecase name="NightMode">
<SensorConfig>
<ExposureTime>200000000</ExposureTime> // 200ms
<Gain>4.0</Gain>
</SensorConfig>
</Usecase>
你看,就这么简单。不需要动一行C++代码。
我的习惯:每次做新项目,我会先建一个override目录,把所有客制化配置放进去。这样升级CamX时,只需要重新编译override部分,省时省力。
3.4.2 Override的加载顺序
这里有个坑,我踩过。Override是有优先级的:
- 最高优先级:运行时动态override(通过属性设置)
- 中等优先级:Usecase级别的override
- 最低优先级:全局默认配置
我曾经遇到过一个bug:明明改了XML,但效果没出来。查了半天,发现是运行时有个属性把配置覆盖了。嗯,从那以后,我每次调试都会先检查属性值。
3.5 实战:如何实现一个简单的Override
咱们来点实际的。假设你要客制化一个“美颜模式”,让它在特定sensor上生效。
第一步,创建override文件:
// vendor/qcom/proprietary/chi-cdk/override/beauty_mode.xml
<?xml version="1.0" encoding="utf-8"?>
<CameraSettings>
<Usecase name="BeautyMode">
<SensorName>imx586</SensorName>
<Pipeline>
<Node name="beauty_node">
<Parameter name="strength">0.8</Parameter>
</Node>
</Pipeline>
</Usecase>
</CameraSettings>
第二步,在CHI配置中注册这个usecase:
// chi-cdk/core/default/chiusecase.cpp
static ChiUsecase g_beautyUsecase = {
.pUsecaseName = "BeautyMode",
.pOverrideXml = "beauty_mode.xml",
.sensorId = SENSOR_IMX586
};
第三步,编译并验证。我个人习惯用adb push到设备上测试:
adb push beauty_mode.xml /vendor/etc/camera/
adb shell setprop persist.camera.override.beauty 1
adb reboot
注意:Override文件的名字和路径必须和CHI配置中一致。我曾经因为文件名大小写问题,浪费了半天时间。记住,Linux是区分大小写的。
3.6 避坑指南:我踩过的那些坑
最后,分享几个实战经验:
- XML格式一定要严格:多一个空格都可能解析失败。我建议用xmllint验证一下。
- 不要覆盖所有配置:只覆盖你需要改的部分。其他保持默认,这样升级时兼容性更好。
- 调试时加日志:在override代码里加CHI_LOG,能帮你快速定位问题。
- 注意版本兼容:不同版本的CHI,override的语法可能有差异。升级前先看release notes。
我曾经接手过一个项目,前任工程师把整个CHI配置都改了一遍。结果高通一升级,全废了。后来我花了三周才把配置重新整理好。所以,尽量少改,改精不改多。
好了,CHI架构的核心内容就这些。下一章咱们聊聊具体的pipeline配置,到时候会用到今天讲的override知识。有什么问题,欢迎随时交流。