Camera HAL框架:多摄切换与Pipeline资源管理实战 - 第1节

1.1 Android Camera 架构全景

Android Camera 系统采用分层架构,从上至下依次为 Application、Framework、HAL 和 Kernel/Driver。每一层都定义了清晰的接口边界,使得上层应用无需关心底层硬件差异。

核心分层: Application → Camera2 API → Camera Service → Camera HAL → Kernel Driver
Android Camera 分层架构 Android Camera 分层架构 Application (Camera2 API 调用者) Framework (Camera Service / Camera2 Framework) HAL (Camera HAL v1 / v3) Kernel / Driver (V4L2 / CSI / ISP) HAL 层是 Framework 与 Kernel 之间的关键桥梁

1.2 HAL 层在 Camera 系统中的位置与作用

HAL(Hardware Abstraction Layer)是 Android Camera 系统的核心适配层,位于 Framework 与 Kernel 之间。它的主要职责是屏蔽底层硬件差异,向上提供统一的接口。

HAL 层的三大核心作用

  • 硬件抽象: 将不同厂商的 ISP、Sensor、Flash 等硬件差异封装成标准接口。
  • 资源管理: 负责 Camera 设备打开/关闭、Stream 配置、Buffer 分配与流转。
  • 流控制: 处理 Preview、Video Record、Snapshot 等不同数据流的并发与切换。
实战要点: 在多摄场景下,HAL 层还需要管理多个物理 Camera 设备的协同工作,包括主摄、广角、长焦之间的切换逻辑与 Pipeline 资源仲裁。
HAL 层位置与数据流 HAL 层位置与数据流 Camera Framework Camera HAL (HAL v1 / v3) open / configure_streams / process_capture_request Kernel / Sensor / ISP HAL 层向下调用 V4L2 / MIPI CSI 驱动,向上返回 CaptureResult 多摄切换时,HAL 负责 Pipeline 资源重分配

1.3 HAL3 vs HAL1 核心差异

Android 从 API Level 21(Android 5.0)开始引入 Camera HAL3 接口,取代了原有的 HAL1。HAL3 的设计目标是支持更复杂的拍照场景和更高的性能要求。

对比维度 HAL1 HAL3
设计理念 固定 Pipeline,操作简单 可编程 Pipeline,灵活配置
数据流模型 Preview / Record / Snapshot 独立流 统一 Stream 模型,支持多流并发
控制粒度 粗粒度,全局参数 逐帧控制,Per-frame 参数
Buffer 管理 HAL 内部管理 Buffer Framework 与 HAL 共享 Buffer(Gralloc)
多摄支持 有限,需厂商私有扩展 原生支持多物理 Camera 逻辑 Camera
性能开销 较低,但灵活性差 较高,但可优化空间大
适用场景 低端设备、简单拍照 中高端设备、多摄、HDR、夜景
迁移注意: 从 HAL1 迁移到 HAL3 不仅仅是接口替换,还涉及 Pipeline 重构、Buffer 管理策略调整、以及多摄同步逻辑的重新设计。建议在项目早期就确定 HAL 版本选型。

HAL3 核心接口变化

HAL3 引入了三个关键接口,取代了 HAL1 的单一操作模式:

  1. configure_streams: 动态配置数据流,支持多个 Stream 同时存在。
  2. process_capture_request: 逐帧提交 Capture Request,每帧可携带不同的参数。
  3. process_capture_result: 异步返回每帧的处理结果,包含 metadata 和 Buffer。
HAL1 vs HAL3 架构对比 HAL1 vs HAL3 架构对比 HAL1: 固定 Pipeline Preview Stream (固定) Record Stream (固定) Snapshot Stream (固定) Stream 数量与类型在 open 时固定 无法动态增减或修改 HAL3: 可编程 Pipeline Stream #1 (可配置) Stream #2 (可配置) Stream #N (动态增减) 通过 configure_streams 动态配置 支持多流并发与逐帧控制 HAL3 通过 process_capture_request/result 实现逐帧精细控制 多摄切换时,HAL3 可动态重配 Pipeline 资源

HAL3 关键数据结构示例

以下代码展示了 HAL3 中 camera3_stream_t 和 camera3_capture_request_t 的核心字段:

// camera3_stream_t - 描述单个数据流
typedef struct camera3_stream {
    uint32_t      stream_type;   // CAMERA3_STREAM_OUTPUT / INPUT
    uint32_t      width;         // 图像宽度
    uint32_t      height;        // 图像高度
    int32_t       format;        // 像素格式 (HAL_PIXEL_FORMAT_*)
    uint32_t      usage;         // Gralloc usage flags
    uint32_t      max_buffers;   // 最大 Buffer 数量
    void         *priv;          // HAL 私有数据
} camera3_stream_t;

// camera3_capture_request_t - 单帧捕获请求
typedef struct camera3_capture_request {
    uint32_t                frame_number;       // 帧序号
    const camera3_stream_t *input_stream;       // 输入流 (ZSL 等场景)
    uint32_t                num_output_buffers; // 输出 Buffer 数量
    const camera3_stream_buffer_t *output_buffers; // 输出 Buffer 数组
    const camera_metadata_t *settings;          // 帧控制参数 (AE/AWB/AF 等)
} camera3_capture_request_t;
实战建议: 在多摄切换场景中,HAL3 的 configure_streams 调用频率会显著增加。建议在 HAL 实现中预分配 Pipeline 资源池,避免每次切换都重新创建/销毁 Stream,从而降低切换延迟。