4. Camera HIDL 接口定义(ICameraDevice)

ICameraDevice.hal 是 Camera HAL 开发中 最核心 的接口文件,它定义了上层框架(Camera Service)与 HAL 实现之间的通信契约。本章将深入分析该接口中的四个核心方法:open、close、configureStreams 和 processCaptureRequest,理解它们的调用时机、参数含义以及实现要点。

关键认知: ICameraDevice 接口是 Camera HAL 的“业务入口”,所有拍照、预览、录像等上层请求最终都会通过这里下发到 HAL 层。掌握这些方法,就等于掌握了 HAL 开发的“七寸”。

4.1 接口概览与调用链路

在 Android HIDL 架构中,ICameraDevice 继承自 android.hardware.camera.device@3.2::ICameraDevice(或更高版本)。上层通过 ICameraService::connectDevice() 获取到 ICameraDevice 的代理对象,然后依次调用其方法完成相机生命周期管理。

ICameraDevice 接口调用链路 Camera Service ICameraDevice Proxy HAL 实现 HIDL 调用 Binder 传输 核心方法调用顺序: 1. open() —— 打开相机设备,获取会话 2. configureStreams() —— 配置数据流(预览/拍照/录像) 3. processCaptureRequest() —— 提交捕获请求(循环调用) 4. close() —— 关闭相机设备,释放资源

4.2 open() —— 打开相机设备

open() 是 ICameraDevice 的入口方法,上层调用它来获取一个相机设备的操作句柄。其 HIDL 定义如下:

// ICameraDevice.hal (Android 10+)
interface ICameraDevice {
    open(ICameraDeviceCallback callback)
        generates (Status status, ICameraDeviceSession session);
    // ...
};
参数/返回值 类型 说明
callback ICameraDeviceCallback 上层注册的回调接口,用于接收异步事件(如错误、快门、结果元数据)
status Status 操作结果:OK / INTERNAL_ERROR / CAMERA_IN_USE / MAX_CAMERAS_IN_USE 等
session ICameraDeviceSession 返回的会话对象,后续所有操作(configureStreams、processCaptureRequest)都通过此会话进行
实现要点: 在 open() 中,HAL 需要完成硬件初始化(如打开 sensor、初始化 ISP)、分配内部缓冲区池、注册回调代理。注意:open() 可能被多次调用,需要做好重入保护。

4.3 close() —— 关闭相机设备

close() 是资源释放的终点。当上层不再使用相机时(如用户退出相机应用),会调用此方法。其定义通常为:

// ICameraDeviceSession.hal
interface ICameraDeviceSession {
    close()
        generates (Status status);
    // ...
};
行为 说明
停止所有流 关闭所有正在运行的 preview / capture / video 流
释放缓冲区 归还所有从 framework 申请的 gralloc 缓冲区
关闭硬件 关闭 sensor、ISP、MIPI 接口等物理设备
清理线程 停止内部工作线程、销毁同步锁
常见陷阱: close() 调用后,HAL 不能再向 framework 发送任何回调(如 processCaptureResult)。如果此时仍有未完成的请求,必须立即丢弃或返回错误。否则会导致 framework 侧野指针崩溃。

4.4 configureStreams() —— 配置数据流

configureStreams() 是 HAL 开发中最复杂的方法之一。它负责根据上层需求,配置相机输出的数据流组合(如预览流 + 拍照流 + 录像流)。

// ICameraDeviceSession.hal
configureStreams(StreamConfiguration config)
    generates (Status status, StreamConfiguration outConfig);

StreamConfiguration 结构体包含:

  • streams:一个 Stream 数组,每个 Stream 定义了分辨率、格式、用途(PREVIEW / STILL_CAPTURE / VIDEO_RECORD / ZSL 等)
  • operationMode:操作模式,如 NORMAL / CONSTRAINED_HIGH_SPEED(高速连拍)
  • sessionParams:可选的会话级参数(如 HDR 模式、帧率范围)
configureStreams() 内部处理流程 StreamConfiguration 验证流组合 分配硬件资源 返回 outConfig 验证内容: • 分辨率是否在 sensor 能力范围内 • 格式是否支持(YUV_420_888 / JPEG / RAW10 等) • 流组合是否合法(如不能同时有两个 STILL_CAPTURE 流) • 总像素数是否超过 ISP 处理能力
性能关键: configureStreams() 可能会触发 ISP 重新初始化、MIPI 通道重配、时钟频率调整等耗时操作。建议在实现时做“增量配置”优化:如果新配置与当前配置差异很小(如只改变分辨率),尽量复用已有资源,避免全量重建。

4.5 processCaptureRequest() —— 提交捕获请求

processCaptureRequest() 是 HAL 的“工作马”,每次拍照、每一帧预览都通过它提交。其定义如下:

// ICameraDeviceSession.hal
processCaptureRequest(vec<CaptureRequest> requests,
                      vec<BufferCache> cachesToRemove)
    generates (Status status, uint32_t numRequestProcessed);

CaptureRequest 结构体包含:

字段 说明
frameNumber 帧序号,单调递增,用于匹配结果回调
settings 捕获参数(AE/AWB/AF 模式、曝光时间、ISO、3A 状态等)
outputBuffers 输出缓冲区列表,每个缓冲区指定了对应的 stream ID 和 buffer handle
inputBuffer 可选输入缓冲区(用于 reprocessing,如 ZSL 场景)

典型处理流程:

  1. 解析请求:提取 frameNumber、settings、outputBuffers
  2. 参数生效:将 settings 中的 3A 参数写入 sensor 驱动(如通过 V4L2 的 VIDIOC_S_EXT_CTRLS)
  3. 触发捕获:向 sensor 发送 trigger(如 software trigger 或 hardware trigger)
  4. 等待完成:等待 sensor 输出 RAW 数据,经过 ISP 处理后填入 outputBuffers
  5. 回调结果:通过 ICameraDeviceCallback::processCaptureResult() 返回结果元数据和填充好的缓冲区
processCaptureRequest() 时序图 Framework HAL Sensor 驱动 ISP processCaptureRequest 解析参数 设置 3A 参数 触发 capture ISP 处理 processCaptureResult
批量优化: processCaptureRequest() 支持一次传入多个 CaptureRequest(vec<CaptureRequest>)。HAL 可以利用这个特性做批量提交,减少 HIDL 跨进程调用开销。例如,在高速连拍场景下,一次传入 10 个请求,HAL 内部用 DMA 连续触发。

4.6 方法对比总结

方法 调用时机 耗时 是否阻塞 关键约束
open() 应用启动时 中等(10~50ms) 是 必须成功返回 session,否则相机无法使用
close() 应用退出时 短(<10ms) 是 必须幂等,多次调用不崩溃
configureStreams() 配置变更时 长(20~200ms) 是 必须验证流组合合法性,失败返回错误码
processCaptureRequest() 每帧/每次拍照 短(<5ms 提交) 否(异步) 必须保证帧序号连续,结果回调不能丢帧
学习路径建议: 在阅读 ICameraDevice.hal 源码时,建议结合 CameraMetadata(相机元数据)一起理解。因为 processCaptureRequest 中的 settings 和返回的 results 都是通过 CameraMetadata 传递的,它定义了数百个 tag(如 ANDROID_SENSOR_EXPOSURE_TIME、ANDROID_CONTROL_AE_MODE 等)。下一章将专门讲解 CameraMetadata 的结构与使用方法。