第一章:Camera HAL 概述
什么是 Camera HAL
Camera HAL,全称是 Hardware Abstraction Layer。说白了,它就是一道桥梁。
这道桥梁连接着 Android 框架层和底层的相机硬件。上层应用想拍照,不会直接去操作传感器。它通过 Framework 层,Framework 再通过 HAL,最终才跟硬件打交道。
我习惯把 HAL 理解成一个「翻译官」。上层说「我要拍一张照片」,HAL 就把这个指令翻译成硬件能听懂的「电压信号」和「寄存器配置」。反过来,硬件采集到的原始数据,也要通过 HAL 翻译成上层能处理的格式。
核心要点:Camera HAL 是 Android 相机系统中唯一直接操作硬件的软件层。它屏蔽了不同厂商、不同传感器之间的差异。
你想想看,高通、联发科、海思,每家用的 ISP 都不一样。如果没有 HAL,Google 得为每款芯片写一套 Framework,那工作量简直不敢想。
HAL 在 Android 相机架构中的位置
我们来看一下整个相机架构的层级关系。从上到下,大概是这样的:
| 层级 | 组件 | 说明 |
|---|---|---|
| 应用层 | Camera App | 用户直接交互的界面 |
| Framework 层 | CameraService、CameraManager | 管理相机资源、权限控制 |
| HAL 层 | Camera HAL Module | 硬件抽象,厂商实现 |
| 内核层 | V4L2、Sensor 驱动 | 直接操作寄存器 |
| 硬件层 | Sensor、ISP、Flash | 物理设备 |
HAL 层夹在 Framework 和内核驱动之间。它不直接操作寄存器,而是调用内核提供的接口。比如 V4L2 或者私有的 IOCTL。
我记得刚入行时,有个同事把 HAL 和驱动混为一谈。其实区别很大。驱动负责「怎么让硬件动起来」,HAL 负责「怎么让 Framework 用起来」。一个是面向硬件的,一个是面向框架的。
个人经验:调试相机问题时,我习惯先确认问题出在哪一层。如果是 HAL 层的问题,通常 log 里会有明显的 HAL 相关 tag。如果是驱动层的问题,那就要去翻 kernel log 了。
HAL 的发展历程:HAL1 vs HAL3
Android 相机 HAL 经历了两个主要版本。HAL1 是早期版本,HAL3 是后来重写的。嗯,这里要注意,HAL2 其实存在过,但很快就被废弃了,所以市面上基本看不到。
HAL1 时代
HAL1 的设计思路很简单。它把相机看作一个「黑盒子」。上层调用 open、startPreview、takePicture 这些接口,HAL 内部自己处理一切。
这样做的好处是:实现起来快。厂商只需要实现几个回调函数,就能让相机跑起来。
但缺点也很明显:
- 灵活性差。上层无法控制每一帧的参数。
- 性能瓶颈。所有处理都在 HAL 内部串行执行。
- 扩展困难。想加一个新功能,得改 HAL 接口。
我在项目中遇到过一个问题。用 HAL1 做双摄,简直是一场噩梦。因为 HAL1 的设计根本就没考虑多摄像头协同。最后只能靠厂商私有的扩展接口来勉强实现,维护成本极高。
HAL3 时代
HAL3 是一次彻底的重新设计。它引入了「Pipeline」的概念。每一帧的请求和结果都是独立的。
核心变化有几点:
- 请求-结果模型:上层发送 capture request,HAL 返回 capture result。每一帧都是独立的。
- 元数据传递:所有参数都通过 metadata 传递。不再是固定的函数参数。
- 多流支持:可以同时输出不同分辨率的预览流、拍照流、视频流。
- 硬件级同步:支持多摄像头同时工作,时间戳同步。
说白了,HAL3 把控制权还给了上层。Framework 可以精细控制每一帧的曝光、增益、白平衡。这在 HAL1 时代是做不到的。
避坑指南:我曾经在 HAL3 的 metadata 配置上栽过跟头。有个参数叫 ANDROID_CONTROL_AE_MODE,我忘了设置,结果预览画面一直闪烁。查了两天才发现是自动曝光模式没配对。所以,HAL3 的 metadata 一定要仔细核对,缺一个关键参数都可能出问题。
HAL1 和 HAL3 的对比
| 对比项 | HAL1 | HAL3 |
|---|---|---|
| 架构模型 | 回调驱动 | 请求-结果 |
| 参数控制 | 固定接口 | metadata 灵活配置 |
| 多摄像头 | 不支持原生 | 原生支持 |
| 性能 | 串行处理 | Pipeline 并行 |
| 实现复杂度 | 低 | 高 |
| Google 推荐 | 已废弃 | 当前标准 |
你可能会问:既然 HAL3 这么好,为什么还有厂商用 HAL1?
原因很简单。HAL3 的实现复杂度高。对于一些低端平台,或者功能简单的设备,HAL1 反而更稳定。我见过一些 IoT 设备,摄像头只需要拍个二维码,用 HAL1 完全够用,没必要上 HAL3。
但从 Android 8.0 开始,Google 已经强制要求新设备必须支持 HAL3。HAL1 只作为兼容模式存在。
总结一下:HAL1 是「你告诉我做什么,我来做」。HAL3 是「你告诉我每一帧怎么做,我来执行」。后者给了上层更大的控制权,但也带来了更高的实现门槛。
我个人建议,如果你是刚接触 Camera HAL,先从 HAL3 入手。虽然学习曲线陡一些,但这是未来的方向。HAL1 的知识了解一下就够了,实际项目中用到的地方越来越少。
下一章,我们会深入 HAL3 的架构细节,看看它的 Pipeline 到底是怎么工作的。