2. Android Camera 整体架构概览

Android Camera 系统采用分层解耦设计,从上层的应用层到底层的硬件驱动,共分为四个主要层级:App 层、Framework 层、HAL 层和Kernel 层。理解每一层的职责以及数据流在层间的传递方式,是进行 Camera HAL 开发的基础。

核心要点:Camera 数据流是一个“请求-响应”模型。App 发起拍照或预览请求,Framework 将其转化为标准化的 CaptureRequest,HAL 负责与硬件交互完成图像采集,最终将结果(CaptureResult)沿原路返回。

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 预览或拍照流程,数据以“请求-响应”的方式在四层之间传递。下图展示了这一完整路径:

Android Camera 完整数据流图 Android Camera 完整数据流(请求-响应模型) App 层 Camera2 API Framework 层 CameraService HAL 层 CameraProvider / HAL Kernel 层 V4L2 / Sensor 驱动 ① CaptureRequest ② HIDL 请求 ③ ioctl / 硬件操作 ④ 原始图像数据 / 中断 ⑤ HIDL 响应 + Buffer ⑥ CaptureResult 关键说明 • 请求路径(蓝色): App → Service → HAL → Driver • 响应路径(绿色): Driver → HAL → Service → App • 核心接口: HIDL (ICameraDevice, IStream, IResult) • 数据载体: GraphicBuffer / HardwareBuffer • 同步机制: Fence (in/out)

2.3 关键组件详解

2.3.1 CameraService

CameraService 是 Android Framework 中负责 Camera 功能的核心系统服务,运行在独立的 cameraserver 进程中。它承担以下职责:

  • 设备管理:枚举并管理所有可用的 Camera 设备(包括物理和逻辑设备)。
  • 权限控制:检查应用是否具有 Camera 权限,以及是否允许访问特定设备。
  • 会话管理:处理多个应用同时请求 Camera 的场景,决定优先级和冲突策略。
  • HIDL 桥接:通过 HIDL 接口与 CameraProvider 通信,下发配置和请求。
开发提示:CameraService 是 HAL 开发者需要关注的上层接口。调试时,可以通过 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 返回。
常见误区:很多初学者认为 HAL 就是直接操作寄存器。实际上,HAL 层更侧重于“策略”和“封装”,真正的寄存器操作由 Kernel 驱动完成。HAL 通过 ioctl 或 V4L2 接口与驱动通信。

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 开发者特别关注:

  1. HIDL 接口调用:CameraService 通过 ICameraDeviceSession::processCaptureRequest() 将请求下发到 HAL。HAL 需要解析请求中的设置(如 AE 模式、输出尺寸)并开始硬件操作。
  2. Buffer 传递:Framework 通过 IStream::allocateBuffers() 或 dequeueBuffer() 与 HAL 交换图像数据。HAL 必须正确处理 Buffer 的引用计数和同步 Fence。
  3. 结果回调:HAL 通过 ICameraDeviceCallback::processCaptureResult() 将采集到的结果(包括元数据和图像 Buffer)异步返回给 Framework。
  4. Kernel 交互:HAL 通过 ioctl() 调用 V4L2 驱动,例如 VIDIOC_S_FMT 设置格式、VIDIOC_QBUF 入队 Buffer、VIDIOC_DQBUF 出队已填充的 Buffer。
实战要点:在调试数据流问题时,建议从两端入手:在 HAL 层打印 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 接口展开。