Camera HAL开发从入门到精通 - 第1节
1.1 Android Camera 整体架构
Android Camera 系统采用分层架构设计,从上至下依次为 应用层、框架层、HAL 层 和 内核层。每一层都通过明确定义的接口进行通信,实现了应用与硬件的解耦。
核心设计原则:上层应用无需关心底层硬件实现细节,Camera HAL 作为硬件抽象层,向上提供统一接口,向下直接操作硬件驱动。
1.1.1 分层架构详解
| 层级 | 主要组件 | 职责描述 |
|---|---|---|
| 应用层 | Camera App、第三方相机应用 | 提供用户交互界面,调用 Camera2 API 实现拍照、录像、预览等功能 |
| 框架层 | CameraService、CameraProvider、CameraDeviceClient | 管理相机资源、处理权限校验、协调多进程访问、分发 Camera 事件 |
| HAL 层 | Camera HAL(HAL1 / HAL3)、CameraProvider HAL | 抽象硬件差异,实现厂商自定义的图像处理管线,向上提供标准接口 |
| 内核层 | V4L2 驱动、Sensor 驱动、ISP 驱动 | 直接控制硬件寄存器,完成图像数据采集、格式转换、中断处理 |
开发者视角:HAL 层是 Camera 系统中最关键的适配层,OEM 厂商的大部分定制工作都集中在这一层。理解 HAL 接口规范是成为 Camera HAL 开发者的第一步。
1.1.2 Android Camera 架构总览图
1.2 Camera HAL 在系统中的位置
Camera HAL 位于 Android 框架层与内核驱动层之间,是典型的 中间件 角色。它通过 HIDL / AIDL 接口与上层 CameraService 通信,通过 ioctl / mmap 等系统调用与底层驱动交互。
1.2.1 HAL 的边界职责
- 向上提供标准接口:实现
ICameraDevice、ICameraDeviceSession等 HIDL 接口,供 CameraService 调用。 - 向下控制硬件:通过 V4L2 框架或私有驱动接口,完成 Sensor 配置、ISP 参数设置、Buffer 管理。
- 实现图像处理管线:包括 3A(AE/AWB/AF)算法、HDR 合成、多帧降噪、视频稳像等。
- 管理 Buffer 生命周期:负责图像 Buffer 的分配、映射、填充和回收。
常见误区:HAL 层并不负责图像数据的显示或编码,这些工作由 SurfaceFlinger 和 MediaCodec 完成。HAL 只负责将原始图像数据以指定格式输出到 Buffer 中。
1.2.2 HAL 在系统中的交互关系
1.3 Camera HAL 的发展历程:HAL1 vs HAL3
Android Camera HAL 经历了从 HAL1 到 HAL3 的重大演进。HAL1 是早期 Android 版本(Android 4.x 及之前)使用的接口,设计简单但功能受限;HAL3 从 Android 5.0 开始引入,支持更复杂的相机特性和更高的性能要求。
1.3.1 核心差异对比
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 引入版本 | Android 4.x 及之前 | Android 5.0 (API 21) 起 |
| 接口模型 | 同步阻塞模型 | 异步流水线模型 |
| Buffer 管理 | 框架管理 Buffer,HAL 被动接收 | HAL 自主管理 Buffer 池,支持灵活分配 |
| 多流支持 | 仅支持单路输出流 | 支持多路并发输出流(预览+拍照+视频) |
| 3A 控制 | 框架控制 3A,HAL 仅执行 | HAL 可自主控制 3A,支持精细调参 |
| 元数据 | 无标准元数据机制 | 使用 CameraMetadata 标准化元数据 |
| 高帧率 | 受限,通常 ≤ 30fps | 支持 60fps、120fps 甚至更高 |
| 厂商定制空间 | 较小,受限于框架 | 较大,可自定义图像处理管线 |
1.3.2 HAL1 架构特点
HAL1 的设计理念是 简单直接,适用于早期 Android 设备对相机功能要求不高的场景。其核心接口定义在 camera.h 头文件中,主要包含以下关键函数指针:
// HAL1 核心接口示例
typedef struct camera_device_ops {
int (*set_preview_window)(struct camera_device *, struct preview_stream_ops *);
int (*start_preview)(struct camera_device *);
void (*stop_preview)(struct camera_device *);
int (*take_picture)(struct camera_device *);
int (*set_parameters)(struct camera_device *, const char *params);
char* (*get_parameters)(struct camera_device *);
} camera_device_ops_t;
HAL1 的局限性:
- 所有操作都是同步的,拍照时预览会卡顿
- 无法同时输出不同分辨率的流
- 3A 算法完全由框架控制,厂商无法深度优化
- 不支持 RAW 数据输出和手动曝光控制
1.3.3 HAL3 架构特点
HAL3 采用 异步流水线模型,将相机操作抽象为 Capture Request 和 Capture Result 的循环。应用可以同时发送多个 Request,HAL 按需处理并返回 Result,实现了真正的并行处理。
// HAL3 核心接口示例
typedef struct camera3_device_ops {
int (*initialize)(const struct camera3_device *, const camera3_callback_ops_t *);
int (*configure_streams)(const struct camera3_device *, camera3_stream_configuration_t *);
int (*process_capture_request)(const struct camera3_device *, camera3_capture_request_t *);
void (*dump)(const struct camera3_device *, int fd);
} camera3_device_ops_t;
1.3.4 HAL1 与 HAL3 工作流程对比
1.3.5 迁移建议
对于新项目:直接使用 HAL3 进行开发,Android 9 及以上版本已不再支持 HAL1。如果维护旧设备,建议尽快迁移到 HAL3 以获得更好的性能和功能支持。
迁移注意事项:
- HAL3 的接口复杂度远高于 HAL1,需要重新设计图像处理管线
- Buffer 管理方式从框架管理变为 HAL 自主管理,需要实现 Buffer 池
- 3A 算法需要从框架迁移到 HAL 中实现,或集成厂商私有 3A 库
- 需要实现
configure_streams()来支持多流配置