2. Camera HAL 架构解析:HAL3 vs HAL1 架构对比、Pipeline 模型、Camera Device 与 Camera Module 的职责划分
Camera HAL(硬件抽象层)是 Android 相机系统中连接 Framework 与底层硬件驱动的关键桥梁。理解 HAL 架构的演进、Pipeline 模型以及核心组件的职责划分,是进行 HAL 移植与性能优化的基础。本章将深入剖析 HAL1 与 HAL3 的核心差异,并拆解 Camera Device 与 Camera Module 的工程边界。
2.1 HAL1 与 HAL3 架构对比
Android 相机 HAL 经历了从 HAL1 到 HAL3 的重大演进。HAL1 是早期设计,适用于功能简单的相机设备;HAL3 则引入了更灵活的 Pipeline 模型,支持多帧处理、高速连拍和高级控制。下表从多个维度对比两者的核心差异:
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 设计哲学 | 单线程、阻塞式操作,每次只处理一帧 | 多线程、异步 Pipeline,支持并发请求与多帧流 |
| 数据流模型 | Preview → Snapshot 串行,无法同时处理多路流 | 支持多路独立流(Preview/Video/Snapshot/ZSL)并行处理 |
| 控制能力 | 仅支持基本参数(AE/AWB/AF),无逐帧控制 | 支持逐帧 3A 参数、手动曝光、手动对焦、RAW 输出等高级控制 |
| Buffer 管理 | HAL 内部管理 buffer,Framework 被动接收 | Framework 通过 camera3_stream_buffer 管理 buffer,HAL 按需填充 |
| 多帧处理 | 不支持,每次只输出一帧 | 支持多帧合成(HDR、夜景)、高速连拍(Burst) |
| 适用场景 | 低端功能机、单摄像头、基础拍照 | 中高端智能手机、多摄像头、计算摄影 |
| 接口版本 | camera_module_t + camera_device_t |
camera3_module_t + camera3_device_t |
2.2 Pipeline 模型:从 Request 到 Frame 的完整链路
HAL3 的核心是 Pipeline 模型。Framework 向 HAL 提交 camera3_capture_request_t,HAL 内部经过 ISP Pipeline 处理后,输出 camera3_capture_result_t。每个 Request 可以包含多个 Stream(输出流),HAL 需要保证每个 Stream 的帧同步。
下图展示了 HAL3 Pipeline 的典型数据流:
Pipeline 模型的关键特性包括:
- 异步非阻塞: Framework 提交 Request 后立即返回,HAL 在后台处理,通过回调通知结果。
- 多流并行: 同一 Request 可以同时输出 Preview(YUV)、Video(H.264)、Snapshot(JPEG)等多路流。
- 逐帧控制: 每个 Request 携带独立的 3A 参数、曝光时间、ISO、对焦位置等,实现逐帧精细控制。
- Buffer 所有权转移: Framework 提供
camera3_stream_buffer,HAL 填充数据后归还,避免内存拷贝。
process_capture_request 的线程安全。如果 HAL 内部有多个 Sensor 或 ISP 通道,建议使用线程池 + 队列模型管理 Request,避免阻塞 Framework 的提交线程。
2.3 Camera Device 与 Camera Module 的职责划分
在 HAL 架构中,Camera Module 和 Camera Device 是两个不同层级的抽象。Module 代表整个相机子系统(可能包含多个物理摄像头),Device 代表单个物理摄像头。理解两者的职责边界,是正确实现 HAL 接口的前提。
下表详细列出两者的职责划分:
| 组件 | 接口结构体 | 核心职责 | 典型实现 |
|---|---|---|---|
| Camera Module | camera3_module_t |
|
SoC 厂商提供,如 Qualcomm mm-camera、MTK imem |
| Camera Device | camera3_device_t |
|
Sensor 驱动 + ISP 算法库封装 |
下图展示了 Module 与 Device 在 HAL 架构中的层级关系:
2.4 关键接口与数据结构
在 HAL3 中,Module 和 Device 通过以下核心接口交互:
// Camera Module 接口(camera3_module_t)
typedef struct camera3_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
int (*open)(const struct hw_module_t *mod, const char *id,
struct hw_device_t **dev);
} camera3_module_t;
// Camera Device 接口(camera3_device_t)
typedef struct camera3_device {
hw_device_t common;
int (*initialize)(const struct camera3_device *dev,
const camera3_callback_ops_t *callback_ops);
int (*configure_streams)(const struct camera3_device *dev,
camera3_stream_configuration_t *stream_list);
int (*process_capture_request)(const struct camera3_device *dev,
camera3_capture_request_t *request);
void (*dump)(const struct camera3_device *dev, int fd);
} camera3_device_t;
configure_streams 时,必须检查 Stream 的 usage 和 format 是否被硬件支持。如果返回 -EINVAL,Framework 会认为配置无效并可能导致相机服务重启。建议在移植初期打印所有 Stream 参数到 log,便于调试。
2.5 工程实践:从 HAL1 迁移到 HAL3 的关键步骤
在实际移植项目中,从 HAL1 迁移到 HAL3 通常遵循以下步骤:
- 接口适配: 将
camera_device_t替换为camera3_device_t,实现process_capture_request和configure_streams。 - Pipeline 重构: 将原有的单线程 Preview/Snapshot 流程改为异步 Pipeline,引入 Request 队列和 Result 回调。
- Buffer 管理改造: 从 HAL 内部管理 buffer 改为使用 Framework 提供的
camera3_stream_buffer,实现 buffer 的申请、填充和归还。 - 多流支持: 确保硬件 ISP 可以同时处理 Preview 和 Video 流,必要时增加 MIPI 虚拟通道或 ISP 分时复用。
- 3A 控制升级: 将原有的固定 3A 策略改为逐帧可配置,支持手动曝光、手动对焦等高级功能。
camera3_test 工具验证以下指标:Request 到 Result 延迟 < 33ms(30fps)、多流帧同步误差 < 1 帧、Burst 模式下无丢帧。