Camera2 API 如何与 HAL3 自动适配
关键词:
Camera2、HAL3、自动适配、StreamConfigurationMap、CaptureRequest、CameraMetadata、SessionConfiguration、DeviceCallback、动态协商
摘要:
Android Camera 架构中,Camera2 API 是应用层与底层 HAL3 驱动间的中介抽象,其核心机制是将高层标准化请求(如 Preview、ImageCapture)自动转化为兼容各厂商 HAL3 的调用组合,并基于设备能力动态构建流配置与 Metadata 协议。本文基于实际项目调试经验,系统解析 Camera2 如何完成与 HAL3 的自动适配,包括请求构建、能力协商、Buffer 流配置、Metadata 回传与错误处理等关键流程,帮助开发者在面对多平台相机适配与兼容性问题时具备工程实操能力。
目录
- Camera 架构回顾:Camera2 × HAL3 的职责分层与交互路径
- HAL3 自动适配的触发时机与关键机制总览
- 能力查询:如何通过 CameraCharacteristics 动态获取 HAL3 能力
- StreamConfigurationMap 与 UseCase 配置的适配逻辑
- CaptureRequest 构建过程与参数标准化封装策略
- 请求发送与 HAL3 接口映射路径详解
- Metadata 回传链路解析:Result → App Callback 的闭环
- 工程实战建议:跨平台稳定性优化 × 错误容错策略 × Trace 调试入口
一、Camera 架构回顾:Camera2 × HAL3 的职责分层与交互路径
Android Camera 系统采用典型的层次式架构,Camera2 API 与 HAL3 驱动之间通过 HIDL
或 AIDL
接口桥接,以实现跨厂商平台的图像能力抽象与请求传递。理解这一分层结构是掌握 HAL3 自动适配机制的基础。
1.1 系统分层结构与功能职责
[App 层]
└── Camera2 API(CameraManager / CameraDevice / CaptureRequest)
↓
[Framework 层]
└── CameraService
↓
[HAL 层(Vendor Implementation)]
└── Camera HAL3(ICameraDeviceSession, ICameraDeviceCallback)
↓
[驱动 & ISP 层]
└── Sensor, ISP, DMA, JPEG Codec, AE/AF/AWB Unit
-
Camera2 API:
- 对外提供标准请求接口(Preview、拍照、变焦、控制参数)
- 管理生命周期与会话绑定逻辑(
CameraDevice
、CaptureSession
) - 提供设备能力查询接口(
CameraCharacteristics
)
-
CameraService:
- 统一管理多摄设备、资源调度、权限控制
- 建立 Camera2 到 HAL3 的会话桥接(ICameraDeviceSession)
-
Camera HAL3:
- 实现
processCaptureRequest()
、configureStreams()
等 HAL 接口 - 执行具体的 Sensor 控制、流配置、Buffer 处理
- 通过回调返回
CaptureResult
与ShutterNotify
等状态
- 实现
1.2 Camera2 到 HAL3 的交互路径简述
以一次 Preview 请求为例:
- App 调用
CameraDevice.createCaptureSession()
绑定 Surface → 生成SessionConfiguration
- CameraService 通过 Binder 将请求转为 HAL3 的
configureStreams()
- App 创建
CaptureRequest
,调用capture()
触发图像采集 - Framework 封装请求为
HALRequest
,传递给processCaptureRequest()
接口 - HAL3 驱动执行图像采集,填充 buffer,回调
processCaptureResult()
给 CameraService - Framework 封装为
TotalCaptureResult
,上报给 App 的CameraCaptureCallback
1.3 HAL3 架构设计初衷:标准化 × 可拓展 × 高性能
- 不再由厂商提供 Java SDK,转为提供标准 HAL 接口,降低集成复杂度
- 支持并发流配置、动态请求组合、Metadata 管理能力
- 提供
InputStream
,Reprocessing
,ZSL
等高阶场景支持
因此 Camera2 的所有能力都需通过 CameraCharacteristics
与动态请求协商方式,自动适配 HAL3 提供的能力边界。
二、HAL3 自动适配的触发时机与关键机制总览
Camera2 并不会假设所有设备行为一致,而是通过 设备能力协商 + 请求封装策略 + Metadata 透传 的机制,在运行时动态适配 HAL3 的具体实现差异。这个过程完全由 Framework 自动完成,开发者无需感知 HAL 细节。
2.1 适配的核心触发时机
时机 | 对应动作 | 适配内容 |
---|---|---|
CameraManager.openCamera() |
获取设备能力 | 读取 CameraCharacteristics |
CameraDevice.createCaptureSession() |
配置图像流 | 调用 configureStreams() ,传入 Surface 配置 |
CameraCaptureSession.capture() / setRepeatingRequest() |
请求提交 | 将 CaptureRequest 组装为 HAL Request |
HAL 回调 processCaptureResult() |
结果接收 | 将 HAL metadata 封装为 TotalCaptureResult 上报 App |
2.2 自动适配的关键能力模块
-
流能力协商(StreamConfigurationMap)
Camera2 查询
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP
,动态识别:- 支持的输出格式(YUV、JPEG、RAW、DEPTH 等)
- 各格式下支持的分辨率
- 是否支持
InputStream
、ZSL、私有格式
-
请求参数支持范围(Request Keys)
Camera2 读取:
REQUEST_AVAILABLE_CAPABILITIES
:如 MANUAL_SENSOR、RAW、READ_SENSOR_SETTINGSCONTROL_AE_AVAILABLE_MODES
、LENS_INFO_AVAILABLE_FOCAL_LENGTHS
等 key/value 范围- 自动决定是否启用手动模式、HDR、对焦模式等
-
Metadata key 协议转换
所有请求与回调参数都通过
CameraMetadata
(key/value)管理:- App → Request.set(key, value)
- Framework → HAL3Request → Metadata 构建
- HAL → processCaptureResult → Metadata 返回
- Framework → Result → key 解包后分发给 App
Camera2 会根据
availableKeys
列表限制 App 可用参数,防止传入不支持的配置。 -
请求节奏与流优化策略
Camera2 会依据流配置特征、Surface 类型、Usage Flags 等信息:
- 判断是否开启单一流优化(如 PREVIEW + YUV 复用)
- 自动设置
TEMPLATE_PREVIEW
,TEMPLATE_STILL_CAPTURE
模板以匹配 HAL 预设参数组合 - 结合
SessionConfiguration
配置流优先级、组合顺序等
2.3 动态请求封装逻辑路径
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(surface);
builder.set(CONTROL_AF_MODE, CONTROL_AF_MODE_CONTINUOUS_PICTURE);
...
cameraCaptureSession.setRepeatingRequest(builder.build(), callback, handler);
框架在构建 Request 时,自动校验:
- 所使用 key 是否包含在
CameraCharacteristics.getAvailableCaptureRequestKeys()
中 - 若不支持则抛出异常或自动 fallback 为默认值
最终打包为 camera_metadata_t
结构,传入 HAL 层。
三、能力查询:如何通过 CameraCharacteristics 动态获取 HAL3 能力
在 Camera2 架构下,系统在打开相机设备时会自动从 HAL3 层拉取该设备的能力描述,通过 CameraCharacteristics
暴露给上层,开发者或 Framework 可依据这些能力信息进行自动适配与策略决策。
3.1 CameraCharacteristics 的获取路径
使用 Camera2 API 打开相机时,系统通过 CameraManager
查询设备列表及其能力:
val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraIdList = manager.cameraIdList
val