1. Camera HAL 概述:Android Camera HAL 架构演进
1.1 HAL 在 Android 系统中的位置与作用
Camera HAL(Hardware Abstraction Layer)是 Android 相机子系统中连接 Framework 与底层硬件驱动的关键中间层。它定义了一套标准接口,使得上层相机服务(CameraService)无需关心具体硬件实现细节,从而实现了“一次框架开发,多平台适配”的目标。
从图中可以看出,HAL 层位于 Framework 与内核驱动之间,承担着“翻译官”的角色:它将上层抽象的请求(如打开相机、配置流、捕获图像)转换为底层硬件可执行的命令,并将硬件返回的原始数据(如 YUV、RAW、JPEG)封装后回传给上层。
1.2 Camera HAL 架构演进:从 HAL1 到 HAL3
Android 相机 HAL 经历了三个主要版本的演进,每个版本都针对性能、灵活性和功能进行了重大改进。下表总结了三个版本的核心差异:
| 特性 | HAL1(Android 2.x - 4.x) | HAL2(Android 4.x 过渡) | HAL3(Android 5.0+) |
|---|---|---|---|
| 设计理念 | 简单封装,面向传统相机 | 尝试引入流式处理 | 面向计算摄影,全控制 |
| 接口模型 | 同步阻塞调用 | 异步回调 + 流 | Pipeline + Request/Result |
| 预览/拍照 | 独立接口,互斥操作 | 支持并发流 | 统一 CaptureRequest |
| 元数据 | 无标准元数据 | 部分元数据支持 | 完整 Metadata(android.*) |
| 多摄像头 | 不支持 | 有限支持 | 原生多摄像头支持 |
| 厂商扩展 | 私有接口泛滥 | 部分标准化 | Vendor Tag 机制 |
| 典型平台 | QCOM MSM8x60 | 过渡期平台 | MTK / QCOM / Exynos |
1.3 HAL1 详解:经典但受限
HAL1 是 Android 早期相机系统的默认接口,设计目标简单直接:提供预览、拍照、录像三个基本功能。其核心接口定义在 camera.h 中,通过 camera_device_t 结构体暴露操作函数指针。
// HAL1 核心接口示例(camera.h)
typedef struct camera_device {
hw_device_t common;
int (*set_preview_window)(struct camera_device *, struct preview_stream_ops *);
void (*set_callbacks)(struct camera_device *, camera_notify_callback,
camera_data_callback, camera_data_timestamp_callback,
camera_request_memory, void *);
int (*start_preview)(struct camera_device *);
void (*stop_preview)(struct camera_device *);
int (*take_picture)(struct camera_device *);
int (*start_recording)(struct camera_device *);
// ... 其他接口
} camera_device_t;
1.4 HAL2:短暂的过渡方案
HAL2 随 Android 4.2 引入,试图解决 HAL1 的流管理问题。它引入了 camera2.h 接口,支持多个并发流(预览流、拍照流、录像流),并开始使用异步回调模型。但由于设计过于复杂且与 HAL1 不兼容,HAL2 并未得到广泛采用,很快被 HAL3 取代。
1.5 HAL3:现代计算摄影的基石
HAL3 从 Android 5.0(Lollipop)开始成为标准接口,其设计核心是 CaptureRequest / CaptureResult 模型。应用层通过构建包含所有参数(曝光、增益、对焦、白平衡、输出格式等)的 CaptureRequest 提交给 HAL,HAL 异步返回 CaptureResult。这种设计使得逐帧控制、多摄像头协同、高速连拍、RAW 输出等高级功能成为可能。
// HAL3 核心接口示例(camera3.h)
typedef struct camera3_device {
hw_device_t common;
int (*initialize)(const struct camera3_device *, const camera3_callback_ops_t *);
int (*configure_streams)(const struct camera3_device *, camera3_stream_configuration_t *);
int (*register_stream_buffers)(const struct camera3_device *, const camera3_stream_buffer_set_t *);
int (*process_capture_request)(const struct camera3_device *, camera3_capture_request_t *);
void (*dump)(const struct camera3_device *, int fd);
int (*flush)(const struct camera3_device *);
// ... 其他接口
} camera3_device_t;
1.6 HAL 版本选择与平台适配策略
在实际的 QCOM 到 MTK 平台适配工作中,HAL 版本的选择直接影响驱动架构、性能调优和功能开发。以下是不同场景下的推荐策略:
- 新平台开发(Android 10+): 强制使用 HAL3,充分利用 Camera2 API 和 Treble 架构。
- 旧平台升级: 如果原平台使用 HAL1,建议直接重写 HAL3 实现,而非在 HAL1 上打补丁。
- QCOM 平台: 通常使用 QCOM 提供的
mm-camera或camxHAL 框架,基于 HAL3 接口。 - MTK 平台: 使用 MTK 自研的
mtkcamHAL 框架,同样基于 HAL3,但内部 Pipeline 设计与 QCOM 差异较大。