1. HAL3架构概述:Android Camera HAL3整体架构、Pipeline模型、与HAL1的区别
Android Camera HAL3(Hardware Abstraction Layer 3)是Android系统从5.0(Lollipop)开始引入的新一代相机硬件抽象层架构。它彻底改变了HAL1时代“黑盒式”的相机控制方式,将相机子系统重构为显式Pipeline模型,赋予上层应用和框架对图像传感器、ISP(图像信号处理器)以及输出流的精细化控制能力。
理解HAL3架构是进行Stream配置与图像格式转换的基础。本章将从整体架构、Pipeline模型以及HAL1对比三个维度展开。
1.1 HAL3整体架构
HAL3架构位于Android Camera Framework与底层Camera硬件驱动之间,其核心设计目标是支持多流并行、高帧率、低延迟以及高级计算摄影特性(如HDR+、人像模式、夜景模式)。
整体架构自上而下分为三层:
- Application / Framework层:通过
android.hardware.camera2API与Camera Service交互,发送Capture Request,接收Capture Result。 - Camera Service / HAL3 Interface层:Camera Service作为中间人,管理Camera设备生命周期,并通过HAL3接口(
camera3_device_t、camera3_callback_ops_t)与HAL通信。 - Camera HAL3 Implementation层:OEM/芯片厂商实现的HAL库,包含Pipeline Manager、Stream配置器、ISP控制、3A算法(AE/AF/AWB)等核心模块。
关键点: HAL3不再像HAL1那样直接输出固定格式的帧数据,而是通过Request-Result模型,让应用精确指定每一帧的传感器设置、输出流格式、目标缓冲区等参数。
1.2 Pipeline模型详解
HAL3的Pipeline模型是其区别于HAL1的核心特征。它将一次拍照或预览过程抽象为一条可配置的数据处理流水线,每个阶段(Stage)都可以独立控制参数。
Pipeline模型包含以下关键概念:
| 概念 | 说明 | HAL3对应结构 |
|---|---|---|
| Capture Request | 应用发出的单帧捕获请求,包含传感器设置、输出流列表、3A参数等 | camera3_capture_request_t |
| Stream | 定义输出数据的格式、分辨率、用途(预览/拍照/分析) | camera3_stream_t |
| Stream Configuration | 一组Stream的集合,在configure_streams()时提交给HAL | camera3_stream_configuration_t |
| Pipeline Depth | HAL内部流水线深度,决定Request的并发处理能力 | android.request.pipelineDepth |
| Capture Result | HAL返回的捕获结果,包含帧数据、元数据、时间戳 | camera3_capture_result_t |
Pipeline模型的工作流程如下:
- 配置阶段:应用通过
configure_streams()提交Stream配置,HAL根据硬件能力验证并分配内部资源。 - 请求阶段:应用提交Capture Request,指定目标Stream和传感器参数。
- 处理阶段:HAL内部Pipeline按顺序执行:Sensor曝光 → RAW域处理 → ISP处理 → 格式转换 → 输出到目标Stream缓冲区。
- 回调阶段:HAL通过回调函数将填充好的缓冲区返回给Framework,同时附带元数据。
实战提示: Pipeline Depth决定了HAL能同时处理多少个未完成的Request。Depth越大,帧率越稳定,但延迟也会增加。在Stream配置时,需要根据目标帧率和延迟要求合理设置。
1.3 HAL3与HAL1的核心区别
HAL1是Android早期(4.x及之前)使用的相机HAL架构,设计简单但灵活性差。HAL3在架构理念、控制粒度、性能表现上都有质的飞跃。下表从多个维度对比两者的差异:
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 控制模型 | 状态机模型(预览→拍照→录像),操作顺序固定 | Request-Result模型,每帧独立控制,支持乱序提交 |
| 多流支持 | 仅支持单流输出(预览或拍照),切换需重新配置 | 支持多流并行输出(预览+拍照+分析同时进行) |
| 图像格式 | 固定输出格式(通常为NV21或JPEG),格式转换由HAL内部完成 | 支持多种输出格式(YUV、RAW、HEIC、DEPTH等),应用可指定格式 |
| 逐帧控制 | 不支持逐帧参数调整,参数设置全局生效 | 支持逐帧设置曝光、增益、白平衡、对焦等参数 |
| 延迟特性 | Pipeline Depth=1,串行处理,延迟较高 | Pipeline Depth≥2,支持流水线并行,延迟更低 |
| 元数据 | 元数据有限,仅包含基本参数 | 丰富的元数据(android.*),覆盖传感器、ISP、3A、统计信息等 |
| 实现复杂度 | 实现简单,约5-10个接口函数 | 实现复杂,约20+接口函数,需要管理Pipeline状态机 |
迁移注意事项: 从HAL1迁移到HAL3时,最大的挑战在于Stream配置的灵活性与Pipeline状态管理。HAL1的“先预览后拍照”逻辑在HAL3中不再适用,需要重新设计Stream配置策略,特别是多流并行时的缓冲区分配和格式转换路径。
1.4 HAL3关键数据结构速览
在HAL3开发中,以下数据结构是Stream配置和图像格式转换的核心:
// Stream配置结构体
typedef struct camera3_stream {
int stream_type; // CAMERA3_STREAM_OUTPUT / INPUT / BIDIRECTIONAL
uint32_t width; // 图像宽度
uint32_t height; // 图像高度
int format; // 图像格式(HAL_PIXEL_FORMAT_*)
uint32_t usage; // 缓冲区用途标志(GRALLOC_USAGE_*)
uint32_t max_buffers; // HAL请求的最大缓冲区数
void *priv; // HAL私有数据
android_dataspace_t data_space; // 色彩空间
int rotation; // 旋转角度
const char *physical_camera_id; // 物理相机ID(多摄)
} camera3_stream_t;
// Stream配置集合
typedef struct camera3_stream_configuration {
uint32_t num_streams; // Stream数量
camera3_stream_t **streams; // Stream指针数组
uint32_t operation_mode; // 操作模式(NORMAL / CONSTRAINED_HIGH_SPEED等)
const camera3_stream_configuration_t *input_streams; // 输入流(用于ZSL等)
} camera3_stream_configuration_t;
实战要点:
format字段决定了图像格式转换的路径。常见的格式包括HAL_PIXEL_FORMAT_YCbCr_420_888(灵活YUV)、HAL_PIXEL_FORMAT_RAW16(RAW域)、HAL_PIXEL_FORMAT_BLOB(JPEG/HEIC)。在配置Stream时,需要根据目标用途(预览/拍照/分析)选择合适的格式,并确保HAL内部有对应的格式转换管线。
1.5 本章小结
HAL3架构通过Request-Result模型和显式Pipeline设计,为Android相机系统带来了前所未有的灵活性和性能潜力。与HAL1相比,HAL3的核心优势在于:
- 多流并行:支持同时输出预览、拍照、分析等多路Stream,是计算摄影的基础。
- 逐帧控制:每帧可独立配置传感器和ISP参数,实现精确的曝光和色彩控制。
- 灵活格式:应用可指定输出格式,HAL内部负责格式转换,为图像处理提供更多选择。