2. Android Camera 整体架构概览
Android Camera 系统采用分层解耦设计,从上层的应用层到底层的硬件驱动,共分为四个主要层级:App 层、Framework 层、HAL 层和Kernel 层。理解每一层的职责以及数据流在层间的传递方式,是进行 Camera HAL 开发的基础。
2.1 四层架构与关键组件
下表总结了各层的主要职责和核心组件:
| 层级 | 核心组件 | 主要职责 |
|---|---|---|
| App 层 | Camera2 API (android.hardware.camera2) | 提供 Java/Kotlin 接口给应用开发者;管理 CameraManager、CameraDevice、CaptureSession 等对象。 |
| Framework 层 | CameraService (cameraserver 进程) | 核心服务,管理权限、设备状态、流配置;通过 HIDL 接口与 HAL 通信;协调多个客户端。 |
| HAL 层 | CameraProvider / Camera HAL (so 库) | 实现 HIDL 接口;封装硬件差异;管理 pipeline、3A 算法、ISP 配置;返回元数据和图像数据。 |
| Kernel 层 | V4L2 驱动 / 平台专用驱动 | 提供统一的视频设备接口;控制 sensor、CSI 接收器、ISP 硬件;处理中断和 DMA 传输。 |
2.2 完整数据流:从 App 到 Kernel
一次典型的 Camera 预览或拍照流程,数据以“请求-响应”的方式在四层之间传递。下图展示了这一完整路径:
2.3 关键组件详解
2.3.1 CameraService
CameraService 是 Android Framework 中负责 Camera 功能的核心系统服务,运行在独立的 cameraserver 进程中。它承担以下职责:
- 设备管理:枚举并管理所有可用的 Camera 设备(包括物理和逻辑设备)。
- 权限控制:检查应用是否具有 Camera 权限,以及是否允许访问特定设备。
- 会话管理:处理多个应用同时请求 Camera 的场景,决定优先级和冲突策略。
- HIDL 桥接:通过 HIDL 接口与 CameraProvider 通信,下发配置和请求。
adb shell dumpsys media.camera 查看 CameraService 的内部状态,包括已注册的 HAL、设备特性、活跃会话等。
2.3.2 CameraProvider
CameraProvider 是 HAL 层对外暴露的 HIDL 服务。它负责:
- HAL 注册:在系统启动时向 CameraService 注册自己,并报告支持的 Camera 设备数量。
- 设备生命周期:创建、初始化、关闭 Camera 设备实例。
- 特性上报:返回设备的静态信息(如分辨率、帧率、AE/AWB 范围)和动态能力。
在 Treble 架构下,CameraProvider 运行在独立的 vendor 进程中,与 Framework 进程隔离,保证了 Framework 升级不影响 HAL 实现。
2.3.3 Camera HAL
Camera HAL 是硬件抽象层的核心实现,通常以共享库(.so)的形式存在。它直接与硬件驱动交互,完成以下工作:
- Pipeline 管理:配置 ISP 的输入输出格式、裁剪、缩放等。
- 3A 算法:实现自动曝光(AE)、自动对焦(AF)、自动白平衡(AWB)的控制逻辑。
- Buffer 管理:分配、填充、释放图像缓冲区,并通过 Fence 机制与 Framework 同步。
- 元数据生成:将硬件状态(如当前曝光时间、增益、对焦位置)封装为 CaptureResult 返回。
2.3.4 V4L2 驱动
V4L2(Video for Linux 2)是 Linux 内核中为视频设备提供的标准驱动框架。在 Camera 系统中,V4L2 驱动负责:
- 设备节点:提供
/dev/video*设备文件,供 HAL 层通过open()、ioctl()等系统调用访问。 - 流 I/O:支持多种 I/O 模式,包括
read/write、mmap(内存映射)和userptr(用户指针)。 - 控制接口:通过 V4L2 控制(如
V4L2_CID_EXPOSURE_ABSOLUTE)设置 sensor 参数。 - Buffer 队列:管理硬件 DMA 的 Buffer 入队和出队,实现零拷贝或低拷贝的数据传递。
下表对比了 V4L2 驱动与平台专用驱动(如 Qualcomm 的 Camera Subsystem)的差异:
| 特性 | V4L2 驱动 | 平台专用驱动 |
|---|---|---|
| 标准化程度 | 高,Linux 内核标准框架 | 低,厂商自定义接口 |
| 接口复杂度 | 中等,ioctl 命令集固定 | 高,包含大量私有命令 |
| 可移植性 | 强,跨平台兼容性好 | 弱,绑定特定 SoC |
| 性能优化 | 通用优化,难以极致 | 可深度定制,性能上限高 |
| 典型场景 | USB Camera、通用 Sensor | 手机内置 Camera、高端 ISP |
2.4 数据流中的关键交互点
在数据流中,有几个关键的交互点需要 HAL 开发者特别关注:
- HIDL 接口调用:CameraService 通过
ICameraDeviceSession::processCaptureRequest()将请求下发到 HAL。HAL 需要解析请求中的设置(如 AE 模式、输出尺寸)并开始硬件操作。 - Buffer 传递:Framework 通过
IStream::allocateBuffers()或dequeueBuffer()与 HAL 交换图像数据。HAL 必须正确处理 Buffer 的引用计数和同步 Fence。 - 结果回调:HAL 通过
ICameraDeviceCallback::processCaptureResult()将采集到的结果(包括元数据和图像 Buffer)异步返回给 Framework。 - Kernel 交互:HAL 通过
ioctl()调用 V4L2 驱动,例如VIDIOC_S_FMT设置格式、VIDIOC_QBUF入队 Buffer、VIDIOC_DQBUF出队已填充的 Buffer。
processCaptureRequest 的入参和 processCaptureResult 的出参;在 Kernel 层使用 trace-cmd 或 ftrace 跟踪 ioctl 调用和中断响应。这样可以快速定位问题发生在哪一层。
2.5 架构演进:从 Legacy 到 Treble
Android Camera 架构经历了从 Legacy HAL 到 Treble HAL 的演进,核心变化在于 HAL 与 Framework 的接口标准化和进程隔离:
| 架构版本 | 接口方式 | 进程模型 | 升级影响 |
|---|---|---|---|
| Legacy HAL (Android 7.0 之前) | 直接调用 camera_module_t 结构体函数指针 |
HAL 加载到 cameraserver 进程内 | Framework 升级必须同步更新 HAL |
| Treble HAL (Android 8.0+) | HIDL 接口(.hal 文件生成 C++/Java 代码) | HAL 运行在独立 vendor 进程 | Framework 可独立升级,HAL 保持兼容 |
当前主流开发均基于 Treble 架构,本课程后续内容也将围绕 HIDL 接口展开。