3. HAL 接口详解:ICameraProvider、ICameraDevice、ICameraDeviceSession 核心接口分析
在 Android Camera HAL 架构中,ICameraProvider、ICameraDevice 和 ICameraDeviceSession 是三个最核心的接口,它们构成了 HAL 层与 Camera Framework 之间的通信骨架。理解这三个接口的职责、生命周期以及关键方法,是实现自定义美颜与滤镜算法的基础。本章将逐一剖析每个接口的核心方法、调用时序以及典型实现模式。
3.1 ICameraProvider 接口:设备发现与生命周期管理
ICameraProvider 是 HAL 层暴露给 Camera Framework 的入口点。它负责枚举系统中可用的相机设备,并管理这些设备的生命周期。在 Treble 架构下,Provider 运行在独立的 HAL 进程中,通过 HIDL / AIDL 与 Framework 通信。
3.1.1 核心方法
| 方法名 | 返回值 | 描述 |
|---|---|---|
getCameraIdList() |
std::vector<std::string> |
返回所有可用相机设备的 ID 列表,如 ["0", "1", "2"] |
getCameraDeviceInterface() |
ICameraDevice |
根据 cameraId 返回对应的 ICameraDevice 实例 |
setCallback() |
Status |
注册 ICameraProviderCallback,用于通知 Framework 设备状态变化 |
isSetTorchModeSupported() |
bool |
查询是否支持手电筒模式 |
3.1.2 典型实现模式
// ICameraProvider 典型实现片段
Return<Status> CameraProvider::getCameraDeviceInterface(
const std::string& cameraId,
sp<ICameraDevice>* device) {
// 1. 校验 cameraId 是否合法
if (cameraId != "0" && cameraId != "1") {
return Status::ILLEGAL_ARGUMENT;
}
// 2. 创建或返回已有的 ICameraDevice 实例
*device = new CameraDevice(cameraId);
return Status::OK;
}
Return<Status> CameraProvider::setCallback(
const sp<ICameraProviderCallback>& callback) {
// 保存回调,用于设备热插拔通知
mCallback = callback;
return Status::OK;
}
getCameraIdList() 中正确枚举所有物理和逻辑相机 ID。
3.2 ICameraDevice 接口:相机设备配置与流管理
ICameraDevice 代表一个具体的相机设备(物理或逻辑)。它负责提供相机静态信息、配置输出流,并创建用于实际捕获的 ICameraDeviceSession。美颜与滤镜算法所需的图像尺寸、格式配置都在此阶段确定。
3.2.1 核心方法
| 方法名 | 返回值 | 描述 |
|---|---|---|
getResourceCost() |
CameraResourceCost |
返回相机设备的资源消耗信息,用于多摄像头协同 |
getCameraCharacteristics() |
CameraMetadata |
返回相机静态元数据,如传感器尺寸、支持的分辨率、AE/AWB 范围等 |
open() |
Status |
打开相机设备,返回 ICameraDeviceSession 实例 |
dumpState() |
void |
导出调试状态信息 |
3.2.2 流配置与 Session 创建
open() 方法是 Device 层最关键的调用。Framework 在调用 open() 之前,会先通过 getCameraCharacteristics() 获取设备能力,然后配置输出流(如预览流、拍照流、视频流)。open() 的实现需要根据这些流配置创建对应的 Session。
// ICameraDevice::open() 典型实现
Return<Status> CameraDevice::open(
const sp<ICameraDeviceCallback>& callback,
sp<ICameraDeviceSession>* session) {
// 1. 检查设备是否已被占用
if (mIsOpened) {
return Status::CAMERA_IN_USE;
}
// 2. 创建 Session,传入回调用于通知 Framework 捕获结果
*session = new CameraDeviceSession(callback, mCameraId);
mIsOpened = true;
return Status::OK;
}
open() 中不要执行耗时操作(如初始化美颜模型)。Session 创建应轻量快速,真正的资源初始化应延迟到 Session 的 processCaptureRequest 第一次调用时进行。
3.3 ICameraDeviceSession 接口:请求处理与图像捕获核心
ICameraDeviceSession 是美颜与滤镜算法实现的主战场。它负责接收来自 Framework 的捕获请求(CaptureRequest),处理图像数据,并通过回调返回结果。所有像素级的处理逻辑都在此接口的方法中实现。
3.3.1 核心方法
| 方法名 | 返回值 | 描述 |
|---|---|---|
processCaptureRequest() |
Status |
处理单个捕获请求,包含输出缓冲区、元数据、物理相机设置 |
flush() |
Status |
清空所有待处理的请求队列,用于快速关闭或切换模式 |
close() |
Status |
关闭 Session,释放所有资源 |
configureStreams() |
Status |
配置输入/输出流,包括分辨率、格式、使用场景(预览/拍照/录像) |
signalStreamFlush() |
Status |
通知特定流需要刷新缓冲区 |
3.3.2 processCaptureRequest 深度解析
processCaptureRequest 是 HAL 层最核心的方法,也是美颜与滤镜算法的注入点。它的输入参数包含:
- CaptureRequest:包含请求 ID、输出缓冲区列表、输入缓冲区(ZSL 模式)、元数据(AE/AWB/AF 设置、3A 状态等)
- BufferRequest:描述每个输出流的缓冲区句柄、宽度、高度、格式、使用场景
- PhysicalCameraSettings:逻辑相机模式下,每个物理相机的单独设置
// processCaptureRequest 典型实现骨架
Return<Status> CameraDeviceSession::processCaptureRequest(
const std::vector<CaptureRequest>& requests,
const std::vector<BufferRequest>& bufRequests,
/* 其他参数 */) {
for (size_t i = 0; i < requests.size(); i++) {
const auto& request = requests[i];
const auto& bufReq = bufRequests[i];
// 1. 获取输出缓冲区
sp<GraphicBuffer> outBuffer = bufReq.outputBuffers[0].buffer;
// 2. 获取输入图像数据(来自 Sensor)
// 实际项目中需要从 DMA 或 GPU 纹理中读取
// 3. 【美颜/滤镜算法注入点】
// 对图像数据执行美颜处理(磨皮、美白、瘦脸等)
// 或滤镜处理(色彩矩阵变换、LUT 映射等)
applyBeautyFilter(inputData, outputData, request.settings);
// 4. 填充结果元数据
CameraMetadata resultMetadata;
resultMetadata.update(ANDROID_SENSOR_TIMESTAMP, timestamp);
resultMetadata.update(ANDROID_CONTROL_AE_STATE, AE_STATE_CONVERGED);
// 5. 通过回调返回结果
mCallback->processCaptureResult({
.frameNumber = request.frameNumber,
.result = std::move(resultMetadata),
.outputBuffers = { {outBuffer, /* status */ OK} }
});
}
return Status::OK;
}
3.3.3 美颜算法在 Session 中的生命周期
3.4 三个接口的协作时序
理解三个接口的协作时序对于正确实现 HAL 至关重要。以下是一个典型的相机打开 → 预览 → 拍照 → 关闭的完整时序:
- Framework 调用
ICameraProvider::getCameraIdList()获取可用设备列表 - Framework 调用
ICameraProvider::getCameraDeviceInterface("0")获取 Device 实例 - Framework 调用
ICameraDevice::getCameraCharacteristics()获取设备能力 - Framework 配置输出流(预览 1080p、拍照 4K)
- Framework 调用
ICameraDevice::open()创建 Session - Session 调用
configureStreams()确认流配置 - Framework 持续调用
processCaptureRequest()发送预览请求 - Session 在
processCaptureRequest()中执行美颜/滤镜 并返回结果 - Framework 调用
flush()清空请求队列 - Framework 调用
close()关闭 Session 和 Device
processCaptureRequest 的同步路径中完成,避免引入额外的线程切换开销。如果算法耗时较长(如 > 16ms 导致预览掉帧),应考虑使用 HAL 层的 requestStreamBuffers 机制进行异步处理。
3.5 接口实现注意事项
| 接口 | 注意事项 | 美颜/滤镜相关 |
|---|---|---|
ICameraProvider |
必须正确处理设备热插拔;返回的 cameraId 必须与 getCameraCharacteristics 一致 |
多摄像头场景下需正确枚举逻辑相机与物理相机 |
ICameraDevice |
open() 必须幂等;getCameraCharacteristics 返回的元数据必须准确 |
在元数据中声明支持的美颜/滤镜能力(如 ANDROID_REQUEST_AVAILABLE_CAPABILITIES) |
ICameraDeviceSession |
processCaptureRequest 必须线程安全;flush() 必须快速返回 |
美颜参数可通过 CaptureRequest 的元数据传递(如自定义 vendor tag) |
ICameraProvider 和 ICameraDevice 的接口定义。所有算法逻辑应封装在 ICameraDeviceSession 内部,通过标准的 processCaptureRequest 接口与 Framework 交互。这样可以保证 HAL 的兼容性和可维护性。