2. Camera HAL层基础架构:HAL3 vs HAL1,Pipeline模型与Stream配置
在深入夜拍与HDR联合调优之前,必须理解Camera HAL层的基础架构。Android Camera系统经历了从HAL1到HAL3的重大演进,两者在架构设计、数据流模型和灵活性上存在本质差异。本章将系统对比HAL1与HAL3的核心区别,解析Pipeline模型与Stream配置机制,为后续的联合调优奠定架构基础。
2.1 HAL1 vs HAL3:架构演进与核心差异
HAL1是Android早期版本采用的相机抽象层,设计简单但功能受限;HAL3(Camera3)从Android 5.0引入,基于流水线模型设计,支持每帧精细控制,是夜拍与HDR等高级功能的基础。
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 架构模型 | 单线程阻塞式模型 | 异步流水线模型(Pipeline) |
| 数据流 | 预览→拍照→回放,串行执行 | 多Stream并行,每帧独立配置 |
| 控制粒度 | 全局参数,无法逐帧调整 | 逐帧控制(per-frame controls) |
| 输出能力 | 单路输出(预览或拍照) | 多路输出(预览+拍照+分析+RAW) |
| YUV/RAW支持 | 通常仅JPEG/YUV | 原生支持YUV、RAW、HEIC、Depth |
| HDR/夜拍支持 | 依赖ISP硬集成,灵活性差 | 支持多帧合成、逐帧曝光控制 |
| 适用场景 | 低端设备、简单拍照 | 高端设备、计算摄影、AI增强 |
调优启示: 夜拍模式与HDR模式的核心依赖——多帧合成、逐帧曝光参数调整、多路Stream并行输出——在HAL1架构下几乎无法实现。因此,所有现代计算摄影功能都必须基于HAL3架构开发。
2.2 HAL3 Pipeline模型:核心架构与数据流
HAL3的核心是Pipeline(流水线)模型,它将相机处理过程分解为多个可独立配置的阶段。每个阶段接收输入缓冲区,处理后输出到下一阶段,最终输出到多个目标Stream。
2.3 Stream配置:多路输出与分辨率管理
Stream是HAL3中定义输出数据通道的核心概念。每个Stream对应一个输出目标(如预览Surface、拍照ImageReader、RAW缓冲区),具有独立的格式、分辨率和使用场景。夜拍与HDR模式通常需要同时配置多个Stream。
2.3.1 Stream配置核心参数
| 参数 | 说明 | 夜拍/HDR典型值 |
|---|---|---|
| format | 像素格式(YUV_420_888 / JPEG / RAW10 / HEIC) | YUV_420_888(多帧合成)、RAW10(HDR合成) |
| width / height | 输出分辨率 | 预览:1920x1080;拍照:4032x3024;RAW:同Sensor |
| usage | 使用场景标志(GPU / CPU / Camera) | CPU(多帧合成)、Camera(直出) |
| dataSpace | 色彩空间(sRGB / Display P3 / BT2020) | sRGB(标准)、BT2020(HDR显示) |
| rotation | 输出旋转角度(0 / 90 / 180 / 270) | 0(由应用层处理旋转) |
2.3.2 夜拍模式典型Stream配置示例
夜拍模式通常需要3路Stream并行工作:预览流、多帧合成流、缩略图分析流。以下是一个典型的Stream配置代码片段:
// 夜拍模式 Stream 配置示例(C++ HAL3 接口)
std::vector<camera3_stream_t*> streams;
// Stream 1: 预览流(YUV,1080p)
camera3_stream_t previewStream;
previewStream.stream_type = CAMERA3_STREAM_OUTPUT;
previewStream.width = 1920;
previewStream.height = 1080;
previewStream.format = HAL_PIXEL_FORMAT_YCbCr_420_888;
previewStream.usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_SW_READ_OFTEN;
previewStream.data_space = HAL_DATASPACE_STANDARD_BT709;
streams.push_back(&previewStream);
// Stream 2: 多帧合成流(YUV,全分辨率)
camera3_stream_t hdrStream;
hdrStream.stream_type = CAMERA3_STREAM_OUTPUT;
hdrStream.width = 4032;
hdrStream.height = 3024;
hdrStream.format = HAL_PIXEL_FORMAT_YCbCr_420_888;
hdrStream.usage = GRALLOC_USAGE_SW_READ_OFTEN; // CPU 读取做多帧合成
hdrStream.data_space = HAL_DATASPACE_STANDARD_BT709;
streams.push_back(&hdrStream);
// Stream 3: 缩略图分析流(YUV,小分辨率)
camera3_stream_t analysisStream;
analysisStream.stream_type = CAMERA3_STREAM_OUTPUT;
analysisStream.width = 640;
analysisStream.height = 480;
analysisStream.format = HAL_PIXEL_FORMAT_YCbCr_420_888;
analysisStream.usage = GRALLOC_USAGE_SW_READ_OFTEN;
analysisStream.data_space = HAL_DATASPACE_STANDARD_BT709;
streams.push_back(&analysisStream);
调优要点: 夜拍模式的多帧合成流必须使用
GRALLOC_USAGE_SW_READ_OFTEN 标志,确保CPU可以高效读取帧数据进行合成。预览流则建议使用 GRALLOC_USAGE_HW_COMPOSER 以利用硬件合成器降低延迟。
2.4 HAL3 Pipeline与Stream配置的联合工作流程
理解Pipeline与Stream如何协同工作,是进行夜拍/HDR调优的前提。以下流程图展示了从应用层下发Request到HAL层处理并返回Result的完整链路:
2.5 HAL1到HAL3迁移的关键注意事项
- Stream数量限制: HAL3支持最多4~8路Stream(取决于硬件平台),夜拍+HDR联合模式通常需要3~4路,需提前规划Stream资源。
- 逐帧控制开销: 每帧下发CaptureRequest会带来CPU/IPC开销,夜拍多帧合成时建议使用Burst模式(连续Request)减少调度延迟。
- Buffer管理: HAL3要求HAL层自行管理Buffer队列,夜拍多帧合成时需注意Buffer生命周期,避免内存泄漏或死锁。
- 兼容性: 部分低端SoC的HAL3实现可能不支持RAW输出或多路YUV Stream,需在配置时通过
camera3_stream_configuration_t的num_streams做运行时检测。
常见陷阱: 在HAL3中,如果同时配置了预览Stream和拍照Stream,且两者分辨率差异过大(如预览1080p、拍照4K),部分ISP可能无法同时支持,导致Stream配置失败(返回 -EINVAL)。建议在Stream配置阶段先查询
camera3_stream_configuration_t 的 operation_mode 是否支持 CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE 或 CONSTRAINED_HIGH_SPEED_MODE。