2、Camera HAL架构基础:Android Camera HAL3 整体架构、Pipeline模型、关键数据结构
2.1 Android Camera HAL3 整体架构
Android Camera HAL3 是 Android 系统为相机硬件抽象层定义的第三代接口规范,旨在支持高级拍照功能(如多帧合成、ZSL、高速连拍)和多摄协同。其核心设计思想是将相机子系统从“黑盒”变为“可配置的流水线”,让 Framework 能够精细控制每一帧的捕获参数和输出路径。
整体架构从上到下分为三层:
- Application / Framework 层:通过 Camera2 API 下发 Capture Request,接收 Capture Result。
- Camera Service / Provider 层:管理 Camera 设备生命周期,将 Request 路由到 HAL。
- Camera HAL3 实现层:实现
camera3_device_ops_t接口,驱动 ISP、Sensor、Flash 等硬件。
process_capture_request 接收请求,通过 process_capture_result 异步返回结果,形成全双工流水线。
2.2 Pipeline 模型:从 Request 到 Result 的旅程
HAL3 的核心抽象是 Pipeline 模型。每个 Camera 设备内部维护一个或多个逻辑 Pipeline,每个 Pipeline 由若干 Stage 串联而成。Framework 发送的 Capture Request 进入 Pipeline 后,依次经过各个 Stage 处理,最终输出 Capture Result。
Pipeline 模型的关键特性:
- 异步非阻塞:HAL 可以在处理当前 Request 的同时接收新的 Request,最多可同时处理
request_queue_max_depth个请求。 - 流式输出:一个 Request 可以同时输出到多个 Stream(如预览流、拍照流、分析流),每个 Stream 独立配置分辨率、格式、数据空间。
- 帧同步:多摄场景下,多个 Camera 设备的 Pipeline 需要通过硬件或软件机制对齐帧边界,这是时间戳对齐的基础。
2.3 关键数据结构详解
HAL3 的数据结构围绕“流(Stream)”和“请求(Request)”两个核心概念设计。理解这些结构是排查多摄同步问题的前提。
2.3.1 camera3_stream_t
camera3_stream_t 描述一个逻辑数据流,代表从 Camera 到内存的一条输出路径。每个 Stream 对应一个 BufferQueue,Framework 通过 Dequeue/Enqueue 机制与 HAL 交换数据。
| 字段 | 类型 | 说明 | 多摄同步影响 |
|---|---|---|---|
stream_type |
int | CAMERA3_STREAM_OUTPUT / INPUT / BIDIRECTIONAL | 多摄通常使用 OUTPUT 流 |
width, height |
uint32_t | 图像分辨率 | 不同摄像头分辨率不同,影响同步策略 |
format |
int | 像素格式(HAL_PIXEL_FORMAT_YCbCr_420_888 等) | 格式转换可能引入延迟差异 |
data_space |
android_dataspace_t | 色彩空间(HAL_DATASPACE_STANDARD_BT709 等) | 色彩空间转换影响时间戳归属 |
rotation |
int | 输出旋转角度 | 旋转处理可能改变帧顺序 |
usage |
uint32_t | Buffer 使用标志(GRALLOC_USAGE_HW_TEXTURE 等) | GPU/CPU 访问路径影响时间戳精度 |
max_buffers |
uint32_t | HAL 可同时持有的最大 Buffer 数 | Buffer 不足可能导致帧丢失 |
max_buffers 配置不一致,可能导致 Buffer 分配节奏不同步,进而造成时间戳偏移。建议所有同步流的 max_buffers 保持一致。
2.3.2 camera3_capture_request_t
camera3_capture_request_t 是 Framework 下发给 HAL 的捕获请求,包含一帧所需的所有参数和输出目标。
typedef struct camera3_capture_request {
uint32_t frame_number; // 帧序号,单调递增
const camera3_stream_t **output_buffers; // 输出流数组
uint32_t num_output_buffers; // 输出流数量
const camera3_stream_buffer_t *input_buffer; // 输入流(重处理时使用)
const camera_metadata_t *settings; // 捕获参数(AE/AWB/AF 等)
uint32_t num_physcam_settings; // 多摄物理 camera 设置数量
const char **physcam_id; // 物理 camera ID 数组
const camera_metadata_t **physcam_settings; // 物理 camera 设置数组
} camera3_capture_request_t;
多摄同步场景下,physcam_id 和 physcam_settings 字段尤为关键。Framework 可以在一个 Request 中同时指定主摄和副摄的独立参数,HAL 需要确保两个 Sensor 的曝光时间、增益、帧长度等参数对齐,才能输出时间戳一致的帧。
2.3.3 camera3_stream_buffer_t 与时间戳
每个 Output Buffer 在返回时携带 camera3_stream_buffer_t 结构,其中 acquire_fence 和 release_fence 用于同步 Buffer 访问。时间戳信息则通过 camera3_capture_result_t 中的 result 元数据返回,关键 Tag 为 ANDROID_SENSOR_TIMESTAMP。
ANDROID_SENSOR_TIMESTAMP 必须反映 Sensor 曝光开始时刻的 CLOCK_MONOTONIC 时间。对于多摄,所有摄像头的 ANDROID_SENSOR_TIMESTAMP 必须使用同一个时钟源,且硬件上需要保证 Sensor 的帧同步信号(VSYNC)对齐。
2.4 多摄同步场景下的数据结构适配
在多摄同步场景中,HAL 需要对上述数据结构做特殊处理:
| 数据结构 | 单摄默认行为 | 多摄同步适配要求 |
|---|---|---|
camera3_stream_t |
每个 Stream 独立配置 | 所有同步流的 usage 和 max_buffers 需统一 |
camera3_capture_request_t |
单个 settings | 使用 physcam_settings 为每个物理 Camera 下发独立参数 |
camera3_stream_buffer_t |
Fence 按需等待 | 多摄 Buffer 需使用共享 Fence 或统一信号量保证同时到达 |
camera3_capture_result_t |
单个 result | 每个物理 Camera 返回独立 result,时间戳需跨设备对齐 |
configure_streams 阶段就建立“同步组”概念,将需要对齐的 Stream 绑定到同一个硬件同步域。这样在 process_capture_request 中可以直接下发同步触发信号,减少软件对齐的复杂度。