2. Android Camera2 框架核心组件详解
在 ZSL(零延迟快门)模式调优之前,必须透彻理解 Camera2 框架的四大核心组件:CameraManager、CameraDevice、CaptureSession 和 CaptureRequest。它们构成了从设备发现到帧捕获的完整管道,ZSL 的延迟控制、缓冲区管理和同步机制都建立在这些组件的交互之上。
核心认知:Camera2 框架采用管道(Pipeline)架构,每一帧图像从传感器曝光到应用层回调,依次经过 CameraDevice → CaptureSession → CaptureRequest 的编排。ZSL 模式要求这条管道的端到端延迟控制在 1 帧以内(通常 16-33ms)。
2.1 CameraManager —— 相机服务入口与设备发现
CameraManager 是应用层访问相机子系统的唯一入口,负责枚举设备、查询能力、打开相机。在 ZSL 场景中,CameraManager 的关键职责是提供 摄像头特性映射表(CameraCharacteristics),用于判断设备是否支持 ZSL 所需的特性。
| 方法 | 作用 | ZSL 相关要点 |
|---|---|---|
getCameraIdList() |
获取所有可用摄像头 ID | 通常选择后置主摄(ID=0) |
getCameraCharacteristics(id) |
获取指定摄像头的静态特性 | 检查 REQUEST_AVAILABLE_CAPABILITIES 是否包含 PRIVATE_REPROCESSING |
openCamera(id, callback, handler) |
异步打开相机设备 | ZSL 需要快速打开,建议使用专用 HandlerThread |
registerAvailabilityCallback() |
监听相机可用性变化 | 用于热插拔场景下的 ZSL 状态重置 |
ZSL 前置检查:在调用
openCamera 之前,务必通过 CameraCharacteristics 确认 CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES 包含 [30,30] 或更高帧率范围,这是 ZSL 零延迟的基础保障。
2.2 CameraDevice —— 相机硬件抽象与管道控制
CameraDevice 代表物理或逻辑摄像头设备,是帧捕获管道的起点。在 ZSL 模式下,CameraDevice 需要维持一个 循环缓冲区(Ring Buffer),持续从传感器接收帧数据而不中断预览。
- createCaptureRequest(int templateType) —— 创建捕获请求模板。ZSL 通常使用
TEMPLATE_ZERO_SHUTTER_LAG(API 级别 23+),该模板预设了低延迟参数。 - createCaptureSession(SessionConfiguration config) —— 创建捕获会话。ZSL 需要配置 高速输出目标(Surface),通常包括预览 Surface 和 ImageReader Surface。
- close() —— 释放设备。ZSL 场景下关闭时机必须精确,避免缓冲区残留导致下一轮打开失败。
ZSL 陷阱:部分设备在
TEMPLATE_ZERO_SHUTTER_LAG 下会强制启用电子防抖(EIS),导致视场角裁切。如果应用需要全视场,应使用 TEMPLATE_PREVIEW 并手动配置 ZSL 参数。
2.3 CaptureSession —— 捕获会话与会话配置
CaptureSession 是帧捕获的执行上下文,负责将 CaptureRequest 提交到 CameraDevice 管道。ZSL 模式对 CaptureSession 的配置有特殊要求:
| 配置项 | 普通模式 | ZSL 模式 |
|---|---|---|
| 输出 Surface 数量 | 1~2 个 | 至少 2 个(预览 + ImageReader) |
| Session 类型 | SESSION_REGULAR |
SESSION_HIGH_SPEED 或带高速配置 |
| 缓冲区大小 | 默认 | 需显式设置 setInputSize() 匹配传感器输出 |
| 重处理支持 | 可选 | 必须启用 PRIVATE_REPROCESSING 能力 |
ZSL 会话创建最佳实践:使用
SessionConfiguration 的 setSessionType(SessionConfiguration.SESSION_HIGH_SPEED) 并配合 OutputConfiguration 的 setSurfaceSize() 显式指定缓冲区尺寸,避免默认分配导致的内存碎片。
2.4 CaptureRequest —— 帧捕获参数与 ZSL 控制
CaptureRequest 是每一帧捕获的参数集合,ZSL 调优的核心就是精确控制 CaptureRequest 中的各项参数。以下是与 ZSL 最相关的关键参数:
- CONTROL_AE_MODE —— 自动曝光模式。ZSL 推荐
CONTROL_AE_MODE_ON(持续测光),避免ON_AUTO_FLASH引入额外延迟。 - CONTROL_AE_TARGET_FPS_RANGE —— 目标帧率范围。ZSL 必须设置为 [30,30] 或更高,保证缓冲区持续填充。
- CONTROL_CAPTURE_INTENT —— 捕获意图。ZSL 拍照时应设置为
CONTROL_CAPTURE_INTENT_STILL_CAPTURE,但预览帧保持CONTROL_CAPTURE_INTENT_PREVIEW。 - STATISTICS_FACE_DETECT_MODE —— 人脸检测模式。ZSL 下建议关闭或使用
SIMPLE模式,减少 ISP 处理延迟。
2.5 四大组件协作流程(ZSL 拍照时序)
理解组件间的协作时序是 ZSL 调优的基础。以下是一个完整的 ZSL 拍照流程,从应用启动到帧回调:
- 初始化阶段:CameraManager 查询设备列表 → 获取 CameraCharacteristics → 确认 ZSL 能力 → 打开 CameraDevice。
- 会话创建阶段:CameraDevice.createCaptureSession() → 配置预览 Surface + ImageReader Surface → 设置高速会话类型。
- 预览阶段:创建预览 CaptureRequest(CONTROL_CAPTURE_INTENT=PREVIEW)→ 重复提交到 CaptureSession → 帧数据持续填充循环缓冲区。
- 拍照阶段:用户触发快门 → 创建拍照 CaptureRequest(CONTROL_CAPTURE_INTENT=STILL_CAPTURE)→ 从循环缓冲区取出最新帧 → 提交重处理请求(若支持)→ 回调 ImageReader.onImageAvailable()。
- 清理阶段:关闭 CaptureSession → 关闭 CameraDevice → 释放 ImageReader Surface。
性能关键点:步骤 3→4 的切换必须在 1 帧时间内完成(16ms@60fps)。建议将拍照 CaptureRequest 预先创建并缓存,避免在快门瞬间分配对象导致 GC 卡顿。
2.6 组件间数据流与缓冲区管理
ZSL 的性能瓶颈往往出现在组件间的数据传递和缓冲区管理上。以下是各组件间的数据流关系:
| 数据流方向 | 数据内容 | 缓冲区类型 | ZSL 优化要点 |
|---|---|---|---|
| Sensor → ISP | RAW 数据 | 硬件 FIFO | 帧率由传感器 PLL 控制,ZSL 要求锁定帧率 |
| ISP → 循环缓冲区 | YUV/RAW | GraphicBuffer | 使用 ImageReader 的 getSurface() 直接绑定 |
| 循环缓冲区 → 应用 | YUV/JPEG | ImageReader 内部队列 | 设置 maxImages 为 3~5,避免队列满阻塞 |
| 应用 → 重处理 | YUV | InputConfiguration | 重处理请求需单独创建 CaptureRequest |
缓冲区泄漏风险:ZSL 模式下 ImageReader 的
maxImages 设置过小(如 1)会导致帧丢失;设置过大(如 10)会增加内存压力。建议根据帧率和预期延迟计算:maxImages = 帧率 × 预期延迟(秒) + 2。