1. HAL3 概述:Camera HAL3 架构演进、与 HAL1 的核心区别、在 Android Camera 框架中的位置
1.1 从 HAL1 到 HAL3:架构演进的驱动力
Android Camera HAL(硬件抽象层)是连接 Android 框架与底层摄像头硬件的关键桥梁。早期 Android 版本(4.0 之前)仅提供 HAL1 接口,其设计以“简单可用”为目标,但存在严重的性能瓶颈和功能局限。随着移动摄影对高帧率、零快门延迟、多帧合成、RAW 域处理等需求的爆发,Google 在 Android 4.2 中引入了 HAL3(又称 Camera3 或 Camera HALv3),并在 Android 5.0 后强制要求新设备优先支持 HAL3。
HAL3 的核心设计理念是 “流水线化” 与 “逐帧控制”,将相机传感器从“一次性拍照设备”转变为“可编程的连续数据流处理器”。
演进关键节点:
- Android 4.0 (ICS): 仅 HAL1,同步模型简单,不支持 Burst 和 ZSL。
- Android 4.2 (JB MR1): 引入 HAL3 预览版,支持 Camera 2 API 基础。
- Android 5.0 (Lollipop): HAL3 成为推荐实现,Camera 2 API 全面开放。
- Android 8.0 (Oreo): Treble 架构下 HAL3 接口进一步标准化,引入 HIDL 封装。
- Android 12+: 强制要求所有新设备必须使用 HAL3,HAL1 被彻底废弃。
1.2 HAL3 与 HAL1 的核心区别
下表从设计哲学、数据流模型、控制粒度、性能特征四个维度对比 HAL1 与 HAL3 的本质差异:
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 设计哲学 | 黑盒模式,Framework 下发简单命令(如 startPreview / takePicture),HAL 内部自行调度 | 白盒流水线,Framework 通过 CaptureRequest 逐帧配置,HAL 返回 CaptureResult 元数据 |
| 数据流模型 | 单路同步流,Preview 和 StillCapture 互斥切换 | 多路并发流,支持同时输出 Preview、Video、YUV、RAW、Depth 等多路 Stream |
| 控制粒度 | 粗粒度,仅支持 AE/AWB/AF 三组锁定,无法逐帧修改参数 | 细粒度,每帧可独立设置曝光、增益、白平衡、对焦、裁剪、3A 模式等 200+ 元数据项 |
| 性能特征 | 延迟高(拍照需先停止预览),不支持 ZSL / Burst / HDR+ | 低延迟流水线,支持 ZSL、Burst、多帧合成、RAW 域处理、高帧率(60/120/240fps) |
| Buffer 管理 | Framework 分配 Buffer,HAL 填充后返回,存在额外拷贝 | Gralloc 直接传递,HAL 通过 Dequeue/Enqueue 操作 Buffer,零拷贝路径 |
| Stream 配置 | 固定配置,通常只支持 1 路 Preview + 1 路 Picture | 动态配置,支持同时配置 3~8 路不同格式/分辨率的 Stream |
开发者视角: 在 HAL3 中,Framework 不再“命令”HAL 做什么,而是“请求”HAL 按指定参数生成一帧数据。这种从“命令式”到“请求式”的转变,是理解 HAL3 所有设计细节的起点。
1.3 HAL3 在 Android Camera 框架中的位置
HAL3 位于 Android Camera 软件栈的 中间层,向上对接 Framework 层的 CameraService 和 Camera2 API,向下直接操作 V4L2、Sensor 驱动、ISP 固件等硬件抽象。其核心接口定义在 hardware/libhardware/include/hardware/camera3.h 中。
下图展示了 HAL3 在完整 Camera 框架中的层级关系与数据流向:
1.4 HAL3 接口的核心数据结构
HAL3 接口围绕三个核心数据结构展开,理解它们是实现 HAL3 适配的前提:
camera3_device_t:代表一个物理或逻辑 Camera 设备,包含ops函数指针表(initialize、configure_streams、process_capture_request、flush、dump 等)。camera3_stream_t:描述一路输出流(格式、分辨率、使用场景),由 Framework 在configure_streams时下发,HAL 需填充max_buffers和usage等字段。camera3_capture_request_t:每帧的请求描述,包含frame_number、settings(元数据包)、input_buffer(可选)、output_buffers数组。
常见适配误区: 许多初学开发者将 HAL3 的
process_capture_request 当作 HAL1 的 takePicture 来阻塞实现。实际上,HAL3 要求该函数必须 非阻塞 返回,所有耗时操作(如 ISP 处理、帧同步)应在后台线程异步完成,并通过 process_capture_result 回调返回结果。阻塞实现会导致 CameraService ANR 和 Stream 超时。