第一章:Android Camera 系统架构全景
从 App 到 HAL 的完整数据流,HAL 在其中的位置与作用。
大家好,我是你们的讲师。今天咱们聊聊 Android Camera 的整体架构。
很多新人一上来就扎进 HAL 代码里,结果越看越懵。为什么?
因为你不知道数据从哪来,到哪去。说白了,你只看到了一个点,没看到整条线。
我个人习惯,学任何子系统,先看全景图。就像去一个陌生城市,先看地图,再走街串巷。
1.1 一张图看懂 Camera 数据流
先别急着看代码。咱们把 Camera 系统想象成一条流水线。
- App 层:用户点一下拍照按钮。这是起点。
- Framework 层:接收指令,调度资源。这是大脑。
- HAL 层:真正操作硬件。这是双手。
- Kernel 层:驱动传感器、ISP。这是肌肉。
数据流是这样的:
App → Framework → CameraService → HAL → Kernel → 硬件
反过来,图像数据从硬件上来,经过 HAL 处理,再一路送回 App 显示。
嗯,这里要注意:HAL 是承上启下的关键节点。它把上层抽象的请求,翻译成底层具体的硬件操作。
1.2 HAL 到底在哪个位置?
我经常跟团队里的新人说:HAL 就是一道墙。
墙的左边,是 Android 通用的 Framework 代码。墙的右边,是各家芯片厂商的私有实现。
为什么要有这道墙?
你想想看,高通、MTK、展锐,每家 ISP 都不一样。如果 Google 直接跟硬件打交道,那代码得写成什么样?
所以 Google 定义了 HAL 接口。你只要实现这个接口,你的 Camera 就能跑在 Android 上。
核心要点:
HAL 是硬件抽象层。它隐藏了硬件差异,向上提供统一接口。
说白了,Framework 不关心你用的是 OV 还是 Sony 的 sensor。它只调用 HAL 的 open、close、processCaptureRequest 这些函数。
1.3 数据流中的关键角色
咱们把每个角色拆开看看。
| 层级 | 组件 | 职责 |
|---|---|---|
| App | Camera2 API | 发起请求,接收结果 |
| Framework | CameraService | 管理权限、协调多个 App 访问 |
| HAL | Camera HAL 模块 | 处理请求,控制硬件 |
| Kernel | V4L2 / 私有驱动 | 操作寄存器,传输数据 |
我在项目中遇到过一个问题:App 打开相机特别慢。查了半天,发现是 HAL 层的初始化里,有个 I2C 通信超时了。
你看,问题出在 HAL,但表象在 App。不懂架构,你根本不知道从哪下手。
1.4 一次拍照请求的完整旅程
咱们走一遍流程。假设用户按下了拍照键。
- App 调用 capture():构造一个 CaptureRequest,里面包含各种参数(曝光、白平衡、对焦区域等)。
- CameraService 收到请求:检查权限,然后转发给 HAL。
- HAL 的 processCaptureRequest() 被调用:这是咱们开发者最熟悉的入口。
- HAL 下发命令到 Kernel:通过 ioctl 或者 DMA 方式,告诉 sensor 开始曝光。
- 硬件返回 RAW 数据:Kernel 把数据送到 HAL 的 buffer 里。
- HAL 做后处理:比如 3A 统计、YUV 转换、JPEG 编码。
- HAL 回调通知 Framework:数据准备好了,你拿走吧。
- Framework 把结果送回 App:App 拿到图片,显示在屏幕上。
个人经验:
我曾经调试过一个 bug,预览画面卡顿。从 App 一路查到 HAL,最后发现是 HAL 里 buffer 申请太慢。
嗯,这种问题,如果你不懂整条链路,光看 HAL 代码是找不到根因的。
1.5 HAL 的核心价值
说了这么多,HAL 到底有什么用?我总结三点:
- 解耦:Framework 和硬件不直接依赖。换 sensor 只需要改 HAL,Framework 不用动。
- 复用:同一套 Framework 代码,可以跑在不同芯片上。Google 的 CTS 测试也是基于 HAL 接口。
- 性能:HAL 可以做一些底层优化。比如我习惯在 HAL 里做 buffer 复用,减少内存拷贝。
避坑指南:
千万不要在 HAL 里做耗时操作!
我曾经见过有人把 JPEG 编码放在 HAL 的 processCaptureRequest 里同步执行。结果拍照卡死,ANR 了。
记住:HAL 的接口调用是有超时限制的。耗时的操作要放到单独线程里。
1.6 小结
这一章咱们把 Camera 架构的全景看了一遍。
你知道了数据从 App 到硬件的完整路径。也明白了 HAL 就是那个翻译官,把上层需求变成硬件指令。
下一章,咱们会深入 HAL 的代码结构。看看那些 open、close、processCaptureRequest 到底是怎么实现的。
嗯,先消化这些。有问题随时问我。