2. Android Camera 架构概览:从 App 到 HAL 再到 Kernel 的完整数据流

Android Camera 子系统是一个典型的 分层解耦 架构,从上至下依次为:应用层 (App)、框架层 (Framework)、硬件抽象层 (HAL) 与 内核层 (Kernel)。理解每一层的职责与层间接口,是进行 HAL 与 Kernel 对齐策略设计的前提。

核心要点: 数据流本质是“控制流 + 数据流”的双通道。控制流负责配置参数与下发命令,数据流负责图像帧的搬运与处理。HAL 是承上启下的关键枢纽,Kernel 是硬件交互的最终执行者。

2.1 四层架构与核心组件

下表总结了各层的主要模块与职责:

层级 核心模块/进程 主要职责 关键接口/协议
App 层 Camera App (Java/Kotlin) 调用 Camera API2,发起预览/拍照/录像请求 android.hardware.camera2
Framework 层 CameraService, CameraProvider 权限管理、流配置、会话创建、数据分发 AIDL / HIDL
HAL 层 Camera HAL (CameraProvider HAL) 实现 CameraDevice、CaptureSession、Result 回调 HIDL / AIDL (Camera HAL 接口)
Kernel 层 V4L2 驱动、ISP 驱动、Sensor 驱动 硬件寄存器操作、帧采集、MIPI CSI 接收、DMA 搬运 V4L2 ioctl / mmap / dma-buf
架构演进提示: Android 从 Treble 项目开始强制使用 HIDL 隔离 HAL,到近期逐步迁移至 AIDL 实现更轻量的 IPC。无论哪种形式,HAL 与 Kernel 之间的 V4L2 接口始终是底层事实标准。

2.2 完整数据流:一次拍照请求的生命周期

以一次 单帧拍照 为例,数据流可拆解为 6 个关键步骤:

  1. App 发起请求: App 通过 CameraCaptureSession.capture() 提交 CaptureRequest,包含输出目标 Surface、3A 参数、帧率等。
  2. Framework 序列化: CameraService 将请求封装为 HIDL/AIDL 消息,通过 Binder 发送至 HAL 进程。
  3. HAL 配置与下发: HAL 解析请求,通过 V4L2 ioctl 设置 sensor 模式、曝光时间、增益,并调用 VIDIOC_QBUF 将空 buffer 入队。
  4. Kernel 硬件采集: Sensor 曝光输出 RAW 数据,ISP 处理为 YUV/JPEG,DMA 将数据写入 dma-buf,驱动通过中断通知帧完成。
  5. Kernel 上报完成: 驱动调用 VIDIOC_DQBUF 将 filled buffer 出队,并通过 V4L2_EVENT 或 poll 机制通知 HAL。
  6. HAL 回调至 App: HAL 将 filled buffer 与 metadata 打包为 CaptureResult,通过回调返回 Framework,最终送达 App 的 ImageReader。
常见瓶颈: 步骤 3 与步骤 5 之间的 buffer 周转效率,以及 HAL 与 Kernel 之间的 ioctl 调用延迟,是影响帧率与拍照延迟的核心因素。对齐策略主要针对这两个环节。

2.3 数据流架构 SVG 图

下图展示了从 App 到 Kernel 的完整数据流与关键接口:

Android Camera 完整数据流架构图 Android Camera 完整数据流架构图 App 层 (Camera App) CameraCaptureSession.capture() Binder (AIDL/HIDL) Framework 层 CameraService / CameraProvider HIDL/AIDL IPC HAL 层 (Camera HAL) processCaptureRequest() / notify() V4L2 ioctl / dma-buf Kernel 层 (V4L2 驱动) VIDIOC_QBUF / VIDIOC_DQBUF MIPI CSI / I2C / SPI 硬件 (Sensor / ISP) 数据流方向 控制流:App → Kernel 数据流:Kernel → App Buffer 通过 dma-buf 共享 对齐策略关注点 1. Buffer 格式协商 2. 元数据同步

2.4 关键接口对比:HAL 与 Kernel 的交互契约

HAL 与 Kernel 之间通过 V4L2 框架交互,核心接口包括:

接口类型 V4L2 调用 HAL 侧行为 Kernel 侧行为
设备打开 open() / VIDIOC_QUERYCAP 获取驱动能力,确认支持格式 初始化硬件,返回 capabilities
格式协商 VIDIOC_S_FMT / VIDIOC_TRY_FMT 设置输出分辨率、像素格式、fps 配置 ISP 与 sensor 输出模式
Buffer 管理 VIDIOC_REQBUFS / VIDIOC_QBUF / VIDIOC_DQBUF 申请 buffer 并入队/出队 管理 DMA 缓冲区,处理帧完成中断
流控制 VIDIOC_STREAMON / VIDIOC_STREAMOFF 启动/停止数据流 控制 sensor 与 ISP 时钟门控
控制参数 VIDIOC_S_CTRL / VIDIOC_G_CTRL 设置曝光、增益、白平衡等 通过 I2C/SPI 写入 sensor 寄存器
事件通知 VIDIOC_SUBSCRIBE_EVENT / poll() 监听帧同步、错误事件 上报帧完成、丢帧、硬件错误
对齐策略切入点: 上表中的“格式协商”与“Buffer 管理”是 HAL 与 Kernel 对齐最频繁、最容易出问题的两个区域。例如,HAL 要求输出 NV12 格式,但 Kernel 驱动只支持 NV21,就需要在 HAL 侧增加格式转换或协商 fallback 逻辑。

2.5 数据流中的 Buffer 生命周期

Buffer 在 App、HAL、Kernel 之间的流转是数据流的核心。下图展示了 Buffer 的完整生命周期:

Buffer 生命周期流转图 Buffer 生命周期流转图 App 申请 Buffer dequeue HAL 入队 (QBUF) VIDIOC_QBUF Kernel 填充数据 DMA done HAL 出队 (DQBUF) 返回 App 消费 Buffer 生命周期关键点 • 整个周期中,Buffer 物理内存不拷贝,仅通过 dma-buf 传递 fd • HAL 与 Kernel 必须对齐 buffer 的 stride、plane offset、color space 等元数据

2.6 对齐策略的三大核心矛盾

从架构概览中,我们可以提炼出 HAL 与 Kernel 对齐时必须解决的三个核心矛盾:

  • 格式与分辨率协商: HAL 期望的格式(如 YUV420_888)与 Kernel 驱动实际支持的格式(如 NV12 或 NV21)不一致。需要建立格式优先级列表与 fallback 机制。
  • Buffer 元数据同步: HAL 与 Kernel 对 buffer 的 stride、plane offset、timestamp、metadata 的理解必须一致。否则会导致花屏、绿屏或帧率异常。
  • 控制参数映射: HAL 的 3A 参数(曝光、增益、白平衡)需要精确映射到 Kernel 驱动的 V4L2 controls 或私有 ioctl。映射错误会导致图像过曝、偏色或无法对焦。
实战建议: 在项目初期,建议使用 v4l2-ctl --list-formats 和 v4l2-ctl --list-ctrls 导出 Kernel 驱动的能力,与 HAL 的 CameraCharacteristics 进行逐项比对,形成对齐检查清单。