1. Camera HAL 层概述
1.1 HAL 层在 Android 相机架构中的位置
Android Camera 架构采用分层设计,自顶向下依次为 Application、Framework、HAL 和 Kernel/硬件。Camera HAL (Hardware Abstraction Layer) 位于 Framework 与底层硬件驱动之间,是连接 Android 相机服务与具体传感器、ISP 等硬件的关键抽象层。
核心作用:HAL 层将硬件差异封装成统一接口,使上层 Framework 无需关心具体芯片厂商的实现细节,从而实现“一次适配,多平台兼容”。
1.2 HAL3 vs HAL1 核心区别
Android 相机 HAL 主要分为两个版本:HAL1(传统接口)和 HAL3(Camera2 API 对应的现代接口)。两者在设计理念、数据流控制、性能特性上存在显著差异。
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 引入版本 | Android 4.0 (API 14) | Android 5.0 (API 21) |
| 数据流模型 | 固定流水线,预览/拍照/录像由 HAL 内部调度 | 灵活 Request/Result 模型,App 可精确控制每一帧 |
| 帧控制粒度 | 粗粒度,无法单独配置每帧参数 | 细粒度,每帧可独立设置 AE/AWB/AF、输出格式、分辨率 |
| 输出流数量 | 通常 1~2 路(预览+拍照) | 支持多路并发输出(预览+拍照+视频+YUV+RAW) |
| RAW/YUV 支持 | 有限,通常只输出 JPEG | 原生支持 RAW、YUV、HEIC 等多种格式 |
| 性能开销 | 较低,适合低端平台 | 较高,需要更强大的 ISP 和内存带宽 |
| 适用场景 | 传统 Camera API、简单拍照/录像 | Camera2 API、专业模式、HDR+、多帧合成、AI 场景 |
选型建议:对于 Android 10+ 的新项目,Google 已强制要求使用 HAL3。HAL1 仅用于兼容老旧平台或极低端设备。若平台 ISP 能力不足,可考虑在 HAL3 中实现“退化模式”以兼容 HAL1 应用。
1.3 HAL 层与 Framework 的交互流程
HAL 层与 Framework 的交互遵循 Provider-Callback 模式。Framework 通过 HIDL / AIDL 接口向 HAL 下发配置和请求,HAL 通过回调机制返回帧数据和事件。以 HAL3 为例,核心交互流程如下:
- 打开相机:Framework 调用
open()打开指定 cameraId 的 HAL 设备,返回camera3_device_t句柄。 - 配置流:Framework 调用
configure_streams()设置输出流集合(预览流、拍照流、视频流等),HAL 返回支持的最大帧率和分辨率。 - 创建 Request:Framework 构造
camera3_capture_request_t,包含输出 buffer、3A 参数、传感器设置等。 - 提交 Request:Framework 调用
process_capture_request()将请求下发到 HAL。 - HAL 处理:HAL 驱动 ISP 和传感器捕获图像,完成 3A 计算、图像处理,将结果填入 buffer。
- 回调通知:HAL 通过
process_capture_result()回调返回帧元数据,通过notify()回调返回事件(如曝光完成、错误等)。 - 关闭相机:Framework 调用
close()释放 HAL 资源。
1.4 关键数据结构与接口
HAL3 的核心数据结构定义在 hardware/libhardware/include/hardware/camera3.h 中,开发者需要重点关注以下结构体:
| 数据结构 | 作用 | 关键字段 |
|---|---|---|
camera3_device_t |
HAL 设备句柄,包含所有操作函数指针 | ops (函数表), priv (私有数据) |
camera3_callback_ops_t |
Framework 注册的回调函数表 | process_capture_result, notify |
camera3_stream_t |
描述一个输出流(预览/拍照/视频等) | stream_type, width, height, format, usage |
camera3_stream_buffer_t |
单个流的 buffer 描述 | stream, buffer, status, acquire_fence, release_fence |
camera3_capture_request_t |
单帧捕获请求 | frame_number, settings, input_buffer, num_output_buffers, output_buffers |
camera3_capture_result_t |
单帧捕获结果 | frame_number, result, num_output_buffers, output_buffers, partial_result |
常见陷阱:HAL3 的
process_capture_request() 是同步调用,HAL 必须在返回前完成 buffer 的填充或提交到硬件队列。若在此函数中执行耗时操作(如长时间 3A 计算),会阻塞 Framework 的请求下发线程,导致预览帧率下降或 ANR。建议将硬件操作放入独立工作线程,函数内仅做请求入队操作。
1.5 HAL 层调试切入点
在实际嵌入式平台开发中,HAL 层问题通常表现为:预览黑屏、拍照卡顿、3A 不收敛、流配置失败等。以下是 HAL 层调试的常用切入点:
- 日志分析:通过
logcat -s CameraHal或logcat -s CameraService过滤 HAL 层日志,关注configure_streams、process_capture_request、notify等关键函数的返回值。 - 流配置验证:检查
camera3_stream_t中的format、width、height是否被 HAL 正确修改(HAL 有权调整流参数)。 - Fence 调试:检查
acquire_fence和release_fence是否超时,fence 超时是黑屏和卡顿的常见原因。 - 3A 状态跟踪:通过
android.control.aeState、android.control.afState等元数据跟踪 3A 收敛过程。 - 性能分析:使用
systrace或perfetto抓取 HAL 线程的 CPU 占用和调度延迟。