Camera HAL硬件抽象层完全掌握 - 第1节
1.1 Camera 子系统在 Android 中的位置
Android Camera 子系统是连接应用层与底层硬件成像设备的核心桥梁。从系统架构的视角看,Camera 子系统横跨应用框架(Application Framework)、系统服务(System Services)、硬件抽象层(HAL)以及内核驱动(Kernel Driver)四个层级。
下图展示了 Camera 子系统在 Android 整体架构中的层级关系与数据流路径:
从图中可以清晰看到,Camera HAL 处于承上启下的关键位置。应用层通过 Camera2 API 发起拍照或预览请求,Framework 层的 CameraService 将请求序列化并下发至 HAL,HAL 再与内核驱动交互完成图像数据的采集与处理。
1.2 HAL 的作用与设计哲学
1.2.1 HAL 的核心作用
Camera HAL 在 Android 系统中承担以下四个核心职责:
| 职责 | 说明 | 关键价值 |
|---|---|---|
| 接口标准化 | 定义统一的 HAL 接口(camera_module_t、camera3_device_t 等),供 Framework 层调用 | 应用开发者无需关心底层硬件差异 |
| 硬件抽象 | 封装不同 SoC 平台(Qualcomm、MTK、Exynos、Tensor)的 ISP 和 Sensor 控制逻辑 | OEM 厂商可快速移植 Camera 功能 |
| 数据管道管理 | 管理从 Sensor 原始数据到最终输出图像(YUV、JPEG、RAW)的完整处理流水线 | 保证图像质量与实时性 |
| 资源生命周期 | 控制 Camera 设备的打开/关闭、Stream 的创建/销毁、Buffer 的分配/回收 | 避免内存泄漏与资源冲突 |
1.2.2 设计哲学:接口与实现分离
Android Camera HAL 的设计哲学可以概括为 "接口与实现分离"。Framework 层只依赖 HAL 层暴露的 hw_module_t 和 hw_device_t 结构体,而不关心底层是 Qualcomm 的 CamX、MTK 的 P1/P2 还是 Google 的 PixelCore。
hw_module_methods_t 和 hw_device_methods_t 两个函数指针表来定义行为契约。厂商只需实现这些函数指针,即可完成 Camera 功能的适配。这种设计模式类似于面向对象编程中的"接口(Interface)"概念。
以下是一个典型的 HAL 模块定义示例,展示了接口与实现分离的设计模式:
// hardware/libhardware/include/hardware/camera_common.h
typedef struct camera_module {
hw_module_t common;
// HAL 版本信息
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
// HAL3 特有的回调注册
int (*set_callbacks)(const camera_module_callbacks_t *callbacks);
// 厂商扩展接口
void *(*get_vendor_tag_ops)(vendor_tag_ops_t *ops);
} camera_module_t;
这种设计带来的直接好处是:Framework 层代码可以跨平台复用,而厂商只需在 HAL 层实现自己的硬件适配逻辑。Google 在 AOSP 中提供了 camera_hal3_default 参考实现,厂商可以基于此进行二次开发。
1.3 HAL 版本演进:HAL1 vs HAL3
1.3.1 版本演进背景
Android Camera HAL 经历了从 HAL1 到 HAL3 的重大演进。HAL1 诞生于 Android 4.0(API 14)时代,设计上较为简单;HAL3 随 Android 5.0(API 21)引入,是一次彻底的架构重构。下表从多个维度对比两个版本的核心差异:
| 对比维度 | HAL1(传统模式) | HAL3(现代模式) |
|---|---|---|
| 引入版本 | Android 4.0 (API 14) | Android 5.0 (API 21) |
| 操作模型 | 同步/阻塞式调用 | 异步请求-结果模型 |
| 数据流 | 单路输出(Preview/Record/Still 互斥) | 多路并发输出(同时支持 Preview+Record+Still) |
| 控制粒度 | 粗粒度(setParameter 字符串) | 细粒度(CaptureRequest 元数据包) |
| Buffer 管理 | HAL 内部管理,Framework 被动接收 | Framework 统一管理,HAL 通过 Dequeue/Enqueue 交互 |
| 3A 控制 | HAL 内部自动处理,应用无法干预 | 应用可指定 AE/AWB/AF 策略,HAL 按需执行 |
| 元数据 | 无标准化元数据 | 标准化的 android.* 元数据体系(200+ 个 tag) |
| 多 Camera 支持 | 有限(需厂商自定义扩展) | 原生支持逻辑 Camera 与物理 Camera 映射 |
1.3.2 架构对比图
下面的 SVG 图直观展示了 HAL1 与 HAL3 在数据流和控制流上的本质区别:
1.3.3 关键演进:从 HAL1 到 HAL3 的驱动力
HAL3 的诞生并非简单的版本升级,而是为了满足以下三个核心需求:
- 多摄像头并发需求:随着双摄、三摄乃至多摄系统的普及,HAL1 的单路输出模型无法满足同时预览、拍照、录像的需求。HAL3 的 Stream 模型天然支持多路并发。
- 计算摄影的兴起:Google 的 HDR+、夜景模式等计算摄影算法需要应用层能够精细控制曝光参数、帧间隔和 RAW 数据输出。HAL1 的粗粒度控制无法满足这些需求。
- 性能与延迟优化:HAL3 的异步模型允许 Framework 提前下发多个 CaptureRequest,HAL 可以流水线式处理,显著降低拍照延迟(从 HAL1 的 200-300ms 降低到 HAL3 的 30-50ms)。
camera_module_t 的 get_number_of_cameras 和 get_camera_info 接口来区分 HAL 版本。
1.3.4 版本选择决策树
在实际项目开发中,选择 HAL1 还是 HAL3 通常遵循以下决策逻辑:
| 场景 | 推荐版本 | 原因 |
|---|---|---|
| Android 9+ 新设备开发 | HAL3 | CDD 强制要求,且支持多摄、计算摄影等新特性 |
| 低端功能机或 IoT 设备 | HAL1 | 实现简单,资源占用低,满足基本拍照需求 |
| 需要 RAW 或 YUV 输出的专业应用 | HAL3 | HAL1 不支持 RAW 输出,且 YUV 输出受限 |
| 多摄像头同时工作(双摄虚化、变焦) | HAL3 | HAL1 无法原生支持多路并发 Stream |
| 遗留系统升级(Android 4.x → 7.x) | HAL1(过渡) | 减少驱动移植工作量,后续再迁移到 HAL3 |
1.4 本章小结
本章作为《Camera HAL 硬件抽象层完全掌握》的开篇,建立了以下知识基础:
- 架构定位:Camera HAL 位于 Android 系统中间层,是连接 Framework 与硬件驱动的关键桥梁。
- 设计哲学:接口与实现分离,通过标准化的
hw_module_t和hw_device_t结构体定义行为契约。 - 版本演进:从 HAL1 的同步单路模型演进到 HAL3 的异步多路模型,核心驱动力是多摄需求、计算摄影和性能优化。