高通Camera HAL层开发项目实战 - 第2节

2.1 HAL1 与 HAL3 架构对比

Camera HAL(硬件抽象层)是 Android 相机框架中连接上层 Camera Service 与底层硬件驱动的关键中间层。高通平台从 Android 5.0 开始全面转向 HAL3 架构,但理解 HAL1 与 HAL3 的差异仍然是开发者的基本功。

2.1.1 架构演进背景

HAL1 是 Android 早期(4.x 及之前)的相机抽象层设计,采用“单线程、单会话”模型,每次只能打开一个 Camera Device,且预览、拍照、录像等操作串行执行。HAL3 从 Android 5.0 引入,基于“请求-结果”管道模型,支持多会话、多流并发、逐帧控制,是高通平台现代相机 HAL 开发的基础。

关键认知: 高通平台从 MSM8996(骁龙820)开始,Camera HAL 强制使用 HAL3 架构。HAL1 仅在 legacy 模式或部分低端平台保留兼容层。

2.1.2 核心差异对比表

对比维度 HAL1 HAL3
架构模型 函数调用 + 回调 异步请求-结果管道
并发能力 单设备、单流 多设备、多流并发
控制粒度 粗粒度(打开/关闭/参数设置) 逐帧控制(per-frame settings)
数据通路 预览/拍照/录像分离 统一 Stream 抽象
Buffer 管理 Gralloc 直接分配 BufferQueue + 生产者-消费者
高通适配 mm-camera 框架 CamX + ChiAPI 框架
延迟特性 高延迟(~100ms) 低延迟(~30ms)

2.1.3 HAL1 vs HAL3 架构对比图

HAL1 vs HAL3 架构对比 HAL1 架构(传统) CameraService HAL1 Module (单一设备) mm-camera / 硬件驱动 单线程 · 串行 · 高延迟 HAL3 架构(现代) CameraService Camera Device (多设备) CamX + ChiAPI 多线程 · 并发流 · 低延迟
开发建议: 在高通平台新项目中,始终以 HAL3 为开发目标。HAL1 仅用于兼容旧平台或快速原型验证,生产环境不建议使用。

2.2 Camera Device 详解

Camera Device 是 HAL3 架构中代表物理或逻辑相机的核心对象。每个 Camera Device 对应一个 camera_id,通过 open() 调用创建,负责管理该相机的所有操作。

2.2.1 Camera Device 生命周期

  • 初始化: HAL 加载 camera_module_t,调用 get_camera_info() 获取设备信息,然后 open() 创建 Device 实例。
  • 配置: 通过 configure_streams() 设置输出流集合,建立 Session。
  • 运行: 接收 Capture Request,处理并返回 Capture Result。
  • 销毁: close() 释放资源,Device 实例失效。

2.2.2 Camera Device 核心接口

// HAL3 Camera Device 核心接口定义(简化)
typedef struct camera3_device_ops {
    // 配置输出流
    int (*configure_streams)(const struct camera3_device *device,
                             camera3_stream_configuration_t *stream_list);

    // 提交捕获请求
    int (*process_capture_request)(const struct camera3_device *device,
                                   camera3_capture_request_t *request);

    // 获取元数据
    int (*get_metadata)(const struct camera3_device *device,
                        uint32_t frame_number,
                        camera3_capture_result_t *result);

    // 通知错误/事件
    void (*notify)(const struct camera3_device *device,
                   const camera3_notify_msg_t *message);

    // 刷新待处理请求
    int (*flush)(const struct camera3_device *device);

    // 销毁设备
    void (*close)(struct camera3_device *device);
} camera3_device_ops_t;

2.2.3 Camera Device 状态机

Camera Device 状态机 CLOSED open() OPENED configure_streams() CONFIGURED process_capture_request() ACTIVE close() close() ERROR close()
常见陷阱: 在 ACTIVE 状态下直接调用 close() 而不先 flush(),会导致未完成的 Capture Request 丢失,可能引发 Buffer 泄漏或 ISP 挂起。高通平台建议先 flush() 再 close()。

2.3 Camera Session 机制

Camera Session 是 HAL3 中管理 Capture Request 生命周期的逻辑单元。一个 Session 对应一次 configure_streams() 调用,包含一组配置好的 Stream 集合。Session 负责协调 Request 的提交、处理和结果返回。

2.3.1 Session 与 Device 的关系

  • 一对一: 一个 Camera Device 在同一时刻只能有一个活跃的 Session。
  • 生命周期: Session 从 configure_streams() 开始,到下一次 configure_streams() 或 close() 结束。
  • 重配置: 切换分辨率或帧率时,需要销毁旧 Session 并创建新 Session。

2.3.2 Session 工作流程

  1. 配置阶段: 应用层通过 configure_streams() 指定输出 Stream 列表(预览、拍照、录像等)。
  2. 请求阶段: 应用层提交 camera3_capture_request_t,包含目标 Stream、元数据设置、Buffer 句柄。
  3. 处理阶段: HAL 将 Request 分发给 ISP 管线,逐帧处理。
  4. 结果阶段: HAL 通过回调返回 camera3_capture_result_t,包含输出 Buffer 和元数据。

2.3.3 Session 状态转换图

Camera Session 状态转换 IDLE(空闲) submit request PENDING(待处理) ISP processing PROCESSING(处理中) result callback DONE error ERROR flush() / reconfigure
性能要点: 高通平台建议在 Session 中保持至少 3~5 个 Request 的流水线深度(pipeline depth),以充分利用 ISP 并行处理能力,避免 CPU 等待造成帧率下降。

2.4 Camera Stream 详解

Camera Stream 是 HAL3 中定义输出数据通路的抽象概念。每个 Stream 代表一路独立的图像输出,具有特定的分辨率、格式、用途和 Buffer 管理方式。

2.4.1 Stream 类型

Stream 类型 用途 典型格式 Buffer 方向
CAMERA3_STREAM_OUTPUT 预览、录像、拍照输出 NV12, YUV420, JPEG HAL → 应用
CAMERA3_STREAM_INPUT 输入流(如重处理) NV12, YUV420 应用 → HAL
CAMERA3_STREAM_BIDIRECTIONAL 双向流(少见) NV12 双向

2.4.2 Stream 配置参数

// Stream 配置结构体(关键字段)
typedef struct camera3_stream {
    // 流类型:OUTPUT / INPUT / BIDIRECTIONAL
    int stream_type;

    // 图像宽度(像素)
    uint32_t width;

    // 图像高度(像素)
    uint32_t height;

    // 像素格式:HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 等
    int format;

    // 使用位掩码:GRALLOC_USAGE_HW_TEXTURE 等
    uint32_t usage;

    // 最大缓冲数(HAL 可修改)
    uint32_t max_buffers;

    // 私有数据(高通扩展字段)
    void *priv;

    // 数据空间(颜色空间)
    android_dataspace_t data_space;

    // 旋转角度
    int rotation;

    // 物理相机 ID(多摄场景)
    const char *physical_camera_id;
} camera3_stream_t;

2.4.3 多 Stream 并发架构图

Camera Stream 并发架构 Camera Device camera_id = 0 Session Stream 0: 预览 1920x1080 NV12 max_buffers=4 Stream 1: 拍照 4000x3000 JPEG max_buffers=2 Stream 2: 录像 3840x2160 NV12 max_buffers=6 SurfaceView ImageReader MediaCodec

2.4.4 Stream 配置最佳实践

高通平台 Stream 配置要点:
  • 格式选择: 预览和录像优先使用 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,让 HAL 选择最优格式;拍照使用 HAL_PIXEL_FORMAT_BLOB(JPEG)。
  • Buffer 数量: 预览流建议 4~6 个 Buffer,录像流建议 6~8 个 Buffer,拍照流 2~3 个 Buffer。
  • 分辨率对齐: 高通 ISP 对宽度和高度有对齐要求(通常 16 或 32 像素对齐),非对齐尺寸会导致性能下降。
  • 多流限制: 同一 Session 中 Stream 数量受 ISP 管线资源限制,骁龙 8 系列通常支持 3~5 路并发输出。

2.5 三者的协作关系

Camera Device、Camera Session、Camera Stream 三者构成 HAL3 架构的核心三角:

  • Device 是硬件抽象实体,负责生命周期管理。
  • Session 是逻辑会话单元,负责请求调度和结果分发。
  • Stream 是数据通路定义,负责 Buffer 管理和格式转换。

2.5.1 协作流程图

Device · Session · Stream 协作流程 应用层 (Camera App) Camera Device Camera Session Stream 0 (预览) Stream 1 (拍照) Stream 2 (录像)
开发口诀: “Device 管生管死,Session 管调度,Stream 管数据”。理解这三者的职责边界,是写出稳定 HAL 代码的第一步。