Camera HAL 架构基础:HAL3 vs HAL1 架构对比与核心接口解析
在 Android Camera 系统中,HAL(Hardware Abstraction Layer)是连接 Framework 与底层 Camera 硬件的关键桥梁。理解 HAL 架构的演进与核心接口,是掌握 Preview 流程与性能优化的前提。本章将系统对比 HAL1 与 HAL3 的架构差异,解析核心数据结构,并介绍 Pipeline 模型。
2.1 HAL1 与 HAL3 架构对比
Android 从 Lollipop(API 21)开始引入 HAL3 架构,以替代原有的 HAL1。两者在设计理念、数据流模型和性能特性上存在本质区别。
| 对比维度 | HAL1(传统架构) | HAL3(现代架构) |
|---|---|---|
| 设计理念 | 固定功能管线,操作模式单一 | 灵活可配置的 Pipeline,支持多流并发 |
| 数据流模型 | 同步阻塞式,一次只能处理一个请求 | 异步非阻塞式,支持多请求流水线 |
| Preview 实现 | 通过 startPreview() 启动固定流 |
通过 process_capture_request() 提交请求 |
| Buffer 管理 | 由 HAL 内部管理,Framework 被动接收 | Framework 与 HAL 共享 Buffer,支持 dequeue/queue |
| 元数据传递 | 通过 setParameters() 传递 |
通过 camera3_capture_request_t 携带完整 metadata |
| 多流支持 | 不支持,同一时间只能有一个输出流 | 支持 Preview、Video、Snapshot 等多流并发 |
| 性能特性 | 延迟较高,CPU 占用大,难以优化 | 低延迟,高吞吐,支持硬件加速 |
| 适用场景 | 低端设备、兼容模式 | 中高端设备、专业相机应用 |
架构演进核心驱动力: HAL3 的引入是为了解决 HAL1 在双摄、高帧率、多流并发等场景下的性能瓶颈。HAL3 将控制权从 HAL 转移到 Framework,使得应用层可以更精细地控制每一帧的采集参数和 Buffer 分配。
2.2 核心接口解析
HAL3 架构的核心接口定义在 hardware/libhardware/include/hardware/camera3.h 中。以下两个结构体是理解 HAL3 工作的关键。
2.2.1 camera3_device_t
camera3_device_t 是 HAL3 设备层的核心结构体,它定义了 Framework 与 HAL 交互的操作函数指针表。每个 Camera 设备对应一个 camera3_device_t 实例。
typedef struct camera3_device {
hw_device_t common;
camera3_device_ops_t *ops;
void *priv;
} camera3_device_t;
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 (*register_stream_buffers)(const struct camera3_device *, const camera3_stream_buffer_set_t *);
const camera_metadata_t *(*construct_default_request_settings)(const struct camera3_device *, int type);
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 *);
void (*signal_stream_flush)(const struct camera3_device *, uint32_t num_streams, const camera3_stream_t *const *streams);
int (*is_reconfiguration_required)(const struct camera3_device *, const camera_metadata_t *old_session, const camera_metadata_t *new_session);
} camera3_device_ops_t;
关键函数说明:
initialize():初始化 HAL 设备,注册回调函数。configure_streams():配置输出流(Preview、Video、Snapshot 等),是 Pipeline 建立的起点。process_capture_request():提交捕获请求,HAL 异步处理并返回结果。construct_default_request_settings():构造默认的请求设置(metadata)。flush():刷新所有未完成的请求,用于快速停止。
2.2.2 camera3_stream_t
camera3_stream_t 描述一个输出流,它定义了流的格式、尺寸、使用方式以及 Buffer 管理策略。
typedef struct camera3_stream {
int stream_type; // CAMERA3_STREAM_OUTPUT / CAMERA3_STREAM_INPUT
uint32_t width;
uint32_t height;
int format; // HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 等
uint32_t usage; // GRALLOC_USAGE_* 标志
uint32_t max_buffers; // HAL 建议的最大 Buffer 数
void *priv; // HAL 私有数据
android_dataspace_t data_space;
int rotation;
int id;
camera3_stream_configuration_mode_t configuration_mode;
camera3_stream_t *physical_camera_id;
} camera3_stream_t;
关键字段解析:
stream_type:输出流(OUTPUT)或输入流(INPUT,用于 reprocessing)。format:推荐使用HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,让 HAL 选择最优格式。usage:Gralloc 使用标志,如GRALLOC_USAGE_HW_TEXTURE(GPU 纹理)或GRALLOC_USAGE_HW_VIDEO_ENCODER(视频编码)。max_buffers:HAL 通过此字段告知 Framework 需要多少个 Buffer 才能达到最佳性能。
实战建议: 在 configure_streams() 中,HAL 应合理设置 max_buffers。设置过少会导致 Buffer 饥饿,增加等待延迟;设置过多会浪费内存,并可能增加 Cache 抖动。通常 Preview 流建议 3~4 个 Buffer,Video 流建议 4~6 个。
2.3 Pipeline 模型介绍
HAL3 的核心是一个异步 Pipeline 模型。Framework 提交请求(Capture Request),HAL 内部按流水线方式处理,最终返回结果(Capture Result)。这种模型使得多个请求可以同时处于不同处理阶段,极大提升了吞吐量。
Pipeline 模型的核心优势在于:
- 异步非阻塞:Framework 提交请求后立即返回,无需等待处理完成。
- 流水线并行:不同请求可以同时处于 Sensor 曝光、ISP 处理、Post-processing 等不同阶段。
- Buffer 复用:通过
dequeue/queue机制,Buffer 在 Framework 和 HAL 之间高效流转。
2.4 HAL1 与 HAL3 数据流对比
为了更直观地理解两者差异,下面通过数据流图对比 HAL1 的同步模型与 HAL3 的异步 Pipeline 模型。
迁移注意事项: 从 HAL1 迁移到 HAL3 时,需要特别注意以下几点:
- HAL3 要求 HAL 实现异步回调,不能阻塞
process_capture_request()。 - Buffer 管理权从 HAL 转移到 Framework,HAL 需要正确处理
dequeue_buffer/queue_buffer回调。 - Metadata 传递方式从
setParameters()改为 Request 携带,HAL 需要解析camera_metadata_t。 - 多流并发时,HAL 需要确保不同流的 Buffer 之间没有数据竞争。