1. Camera 系统概述:Android Camera 整体架构、Camera HAL 层、Camera Service、应用层调用链路

Android Camera 系统采用分层解耦的架构设计,从上至下依次为 应用层、Framework 层、HAL 层 和 Kernel 层。每一层都定义了清晰的接口边界,使得应用开发者、系统集成商和硬件厂商可以独立演进。理解这一调用链路是进行 CameraDevice 接口调用与 Pipeline 性能调优的基础。

1.1 整体架构分层

Android Camera 架构共分为四个主要层级,各层职责明确,通过标准化接口进行通信:

层级 主要组件 职责描述 关键接口/协议
应用层 Camera App、第三方应用 调用 Camera API 实现拍照、录像、预览等功能 android.hardware.camera2 API
Framework 层 Camera Service、Camera Provider 管理 Camera 设备生命周期、权限控制、流配置协调 AIDL / HIDL
HAL 层 Camera HAL (v3/v4) 抽象硬件差异,实现 ISP 控制、3A 算法、流处理 HIDL / AIDL HAL 接口
Kernel 层 V4L2 驱动、ISP 驱动、Sensor 驱动 提供底层硬件访问、中断处理、DMA 传输 V4L2、Platform Device
架构要点: Android 从 Camera API 1 演进到 Camera API 2(即 camera2),核心变化在于将同步阻塞模型改为异步流水线模型。API 2 通过 CameraCaptureSession 和 CaptureRequest 实现了 Pipeline 化的请求-响应机制,这是性能调优的起点。

1.2 应用层调用链路

一个典型的 Camera 打开与预览流程,从应用层到 HAL 层的完整调用链路如下:

  1. 获取 CameraManager: 应用通过 Context.getSystemService(Context.CAMERA_SERVICE) 获取 CameraManager 实例。
  2. 枚举 Camera ID: 调用 cameraManager.getCameraIdList() 获取设备支持的 Camera 列表。
  3. 打开 Camera: 调用 cameraManager.openCamera(cameraId, stateCallback, handler),该调用通过 Binder 跨进程到达 Camera Service。
  4. Camera Service 处理: Camera Service 检查权限、创建 CameraDeviceImpl 实例,并通过 HIDL/AIDL 调用 Camera Provider 进程中的 HAL 接口。
  5. HAL 层响应: Camera Provider 加载 HAL 实现(如 android.hardware.camera.provider@2.4),调用 HAL 的 open() 方法初始化硬件。
  6. 创建 Capture Session: 应用通过 cameraDevice.createCaptureSession(sessionConfig, callback, handler) 配置输出 Surface 并启动 Pipeline。
  7. 发送 Capture Request: 应用构建 CaptureRequest 并提交到 CameraCaptureSession,请求沿 Pipeline 下发至 HAL 进行 ISP 处理。
性能关键路径: 步骤 3-5 是 Camera 打开延迟的主要来源,涉及 Binder 跨进程通信、HAL 库加载、Sensor 初始化。步骤 7 的 Request 提交频率直接影响预览帧率和拍照响应速度。

1.3 Camera HAL 层详解

HAL 层是连接 Android Framework 与硬件驱动的桥梁。Android 目前主要使用 Camera HAL v3(部分新设备已迁移至 HAL v4),其核心设计理念是 Pipeline 化:

  • ICameraDevice: HAL 层 Camera 设备抽象,提供 open()、close()、constructDefaultRequestSettings() 等接口。
  • ICameraDeviceSession: 会话抽象,负责处理 processCaptureRequest()、flush() 等核心 Pipeline 操作。
  • Stream 配置: 通过 configureStreams() 配置输入/输出流,包括 YUV、JPEG、RAW 等格式。
  • 3A 控制: HAL 内部实现自动曝光(AE)、自动对焦(AF)、自动白平衡(AWB)算法。
// HAL v3 核心接口示例(简化)
// 位于 hardware/interfaces/camera/device/3.4/ICameraDeviceSession.hal

interface ICameraDeviceSession {
    // 配置数据流管道
    configureStreams_3_4(StreamConfiguration configuration)
        generates (Status status, StreamConfigurationOut output);

    // 处理捕获请求(Pipeline 核心入口)
    processCaptureRequest_3_4(vec<CaptureRequest> requests,
                              vec<BufferCache> cachesToRemove)
        generates (Status status, uint32_t numRequestProcessed);

    // 刷新所有待处理请求
    flush() generates (Status status);
};

1.4 Camera Service 角色

Camera Service 运行在 cameraserver 进程中,是应用层与 HAL 层之间的 核心调度器:

功能模块 说明 性能影响
设备管理 维护 Camera 设备列表、状态机、连接计数 设备打开/关闭的延迟
权限检查 验证调用方是否具有 Camera 权限 每次 open 时的额外 IPC
流配置协调 校验 Stream 组合是否合法,协调多个 Client Session 创建耗时
Buffer 管理 通过 BufferQueue 管理 Surface 的 Buffer 分配与流转 Buffer 分配延迟、帧率稳定性
Request 分发 将应用提交的 Request 序列化后发送给 HAL Request 排队深度、Pipeline 吞吐

1.5 调用链路全景 SVG 图

下图展示了从应用层到 HAL 层的完整调用链路与核心组件交互关系:

Android Camera 调用链路全景图 应用层 (Application Layer) Camera App CameraManager CameraDevice CaptureRequest/Session Framework 层 (Camera Service) CameraService CameraProviderManager CameraDeviceImpl Binder IPC HAL 层 (Camera HAL v3/v4) ICameraDevice ICameraDeviceSession processCaptureRequest configureStreams Kernel 层 (Driver) V4L2 Driver ISP Driver Sensor Driver DMA / ION 关键路径:openCamera() → CameraService → HAL open() → Sensor Init → createCaptureSession() → processCaptureRequest()

1.6 关键性能指标与调优方向

在 Camera 调用链路中,以下指标直接影响用户体验,也是 Pipeline 性能调优的核心关注点:

  • Open Latency(打开延迟): 从应用调用 openCamera() 到收到 onOpened() 回调的时间。通常应 < 200ms,受 HAL 初始化、Sensor 启动、权限检查影响。
  • Session Creation Latency(会话创建延迟): 从 createCaptureSession() 到 onConfigured() 的时间。受 Stream 配置复杂度、Buffer 分配策略影响。
  • Frame Duration(帧间隔): 连续 Capture Request 之间的时间间隔,决定预览帧率。Pipeline 深度、ISP 处理时间、Buffer 流转效率是关键。
  • Request Pipeline Depth(请求流水线深度): HAL 内部同时处理的 Request 数量。深度过大会增加延迟,过小会降低吞吐。
常见陷阱: 应用层频繁创建和销毁 CameraCaptureSession 会导致严重的性能抖动。每次 Session 切换都会触发 configureStreams() 调用,该操作在 HAL 层通常需要停止 ISP 流水线并重新配置,耗时可达 100-300ms。建议复用 Session 并通过 setRepeatingRequest() 切换预览参数。

1.7 本章小结