1. Camera HAL 概述:Android Camera HAL 架构演进

1.1 HAL 在 Android 系统中的位置与作用

Camera HAL(Hardware Abstraction Layer)是 Android 相机子系统中连接 Framework 与底层硬件驱动的关键中间层。它定义了一套标准接口,使得上层相机服务(CameraService)无需关心具体硬件实现细节,从而实现了“一次框架开发,多平台适配”的目标。

核心作用:HAL 将硬件厂商的私有实现封装在标准接口之下,Android 系统通过 HAL 调用相机传感器、ISP、闪光灯、对焦马达等硬件资源,同时向上层提供统一的设备控制能力。
Android Camera 系统分层架构 应用层(Camera App / Camera2 API) Framework 层(CameraService / CameraProvider) Camera HAL 层(HAL1 / HAL2 / HAL3) 内核驱动层(V4L2 / Sensor Driver / ISP Driver) 硬件层(Camera Sensor / ISP / Flash / Actuator) HAL 是承上启下的 关键抽象层

从图中可以看出,HAL 层位于 Framework 与内核驱动之间,承担着“翻译官”的角色:它将上层抽象的请求(如打开相机、配置流、捕获图像)转换为底层硬件可执行的命令,并将硬件返回的原始数据(如 YUV、RAW、JPEG)封装后回传给上层。

1.2 Camera HAL 架构演进:从 HAL1 到 HAL3

Android 相机 HAL 经历了三个主要版本的演进,每个版本都针对性能、灵活性和功能进行了重大改进。下表总结了三个版本的核心差异:

特性 HAL1(Android 2.x - 4.x) HAL2(Android 4.x 过渡) HAL3(Android 5.0+)
设计理念 简单封装,面向传统相机 尝试引入流式处理 面向计算摄影,全控制
接口模型 同步阻塞调用 异步回调 + 流 Pipeline + Request/Result
预览/拍照 独立接口,互斥操作 支持并发流 统一 CaptureRequest
元数据 无标准元数据 部分元数据支持 完整 Metadata(android.*)
多摄像头 不支持 有限支持 原生多摄像头支持
厂商扩展 私有接口泛滥 部分标准化 Vendor Tag 机制
典型平台 QCOM MSM8x60 过渡期平台 MTK / QCOM / Exynos

1.3 HAL1 详解:经典但受限

HAL1 是 Android 早期相机系统的默认接口,设计目标简单直接:提供预览、拍照、录像三个基本功能。其核心接口定义在 camera.h 中,通过 camera_device_t 结构体暴露操作函数指针。

// HAL1 核心接口示例(camera.h)
typedef struct camera_device {
    hw_device_t common;
    int (*set_preview_window)(struct camera_device *, struct preview_stream_ops *);
    void (*set_callbacks)(struct camera_device *, camera_notify_callback,
                          camera_data_callback, camera_data_timestamp_callback,
                          camera_request_memory, void *);
    int (*start_preview)(struct camera_device *);
    void (*stop_preview)(struct camera_device *);
    int (*take_picture)(struct camera_device *);
    int (*start_recording)(struct camera_device *);
    // ... 其他接口
} camera_device_t;
HAL1 的痛点:预览和拍照是互斥的,拍照时必须停止预览流;不支持逐帧参数控制;多摄像头场景下需要多个 HAL 实例,资源管理复杂;元数据缺失导致厂商大量使用私有扩展,平台移植困难。
HAL1 工作流程(预览 → 拍照) Camera App HAL1 Sensor Driver HAL1 状态机(互斥模式) IDLE(空闲) start_preview PREVIEW(预览) take_picture CAPTURE(拍照) ⚠ 拍照时预览自动停止,拍照完成后需重新 start_preview

1.4 HAL2:短暂的过渡方案

HAL2 随 Android 4.2 引入,试图解决 HAL1 的流管理问题。它引入了 camera2.h 接口,支持多个并发流(预览流、拍照流、录像流),并开始使用异步回调模型。但由于设计过于复杂且与 HAL1 不兼容,HAL2 并未得到广泛采用,很快被 HAL3 取代。

实际工程现状:在 QCOM 和 MTK 平台上,HAL2 几乎从未成为主流。大多数厂商直接从 HAL1 跳到了 HAL3。本课程后续章节将重点围绕 HAL3 展开,因为它是当前 Android 相机系统的基石。

1.5 HAL3:现代计算摄影的基石

HAL3 从 Android 5.0(Lollipop)开始成为标准接口,其设计核心是 CaptureRequest / CaptureResult 模型。应用层通过构建包含所有参数(曝光、增益、对焦、白平衡、输出格式等)的 CaptureRequest 提交给 HAL,HAL 异步返回 CaptureResult。这种设计使得逐帧控制、多摄像头协同、高速连拍、RAW 输出等高级功能成为可能。

// HAL3 核心接口示例(camera3.h)
typedef struct camera3_device {
    hw_device_t common;
    int (*initialize)(const struct camera3_device *, const camera3_callback_ops_t *);
    int (*configure_streams)(const struct camera3_device *, camera3_stream_configuration_t *);
    int (*register_stream_buffers)(const struct camera3_device *, const camera3_stream_buffer_set_t *);
    int (*process_capture_request)(const struct camera3_device *, camera3_capture_request_t *);
    void (*dump)(const struct camera3_device *, int fd);
    int (*flush)(const struct camera3_device *);
    // ... 其他接口
} camera3_device_t;
HAL3 Pipeline 模型:CaptureRequest → CaptureResult Camera App (构建 Request) CameraService (分发 Request) HAL3 (处理 Pipeline) Sensor + ISP (执行捕获) HAL3 Pipeline 内部处理流程 Request 解析 参数校验 硬件配置 捕获执行 Result 返回 ✅ 每个 Request 独立处理,支持多帧并发、逐帧参数控制

1.6 HAL 版本选择与平台适配策略

在实际的 QCOM 到 MTK 平台适配工作中,HAL 版本的选择直接影响驱动架构、性能调优和功能开发。以下是不同场景下的推荐策略:

  • 新平台开发(Android 10+): 强制使用 HAL3,充分利用 Camera2 API 和 Treble 架构。
  • 旧平台升级: 如果原平台使用 HAL1,建议直接重写 HAL3 实现,而非在 HAL1 上打补丁。
  • QCOM 平台: 通常使用 QCOM 提供的 mm-camera 或 camx HAL 框架,基于 HAL3 接口。
  • MTK 平台: 使用 MTK 自研的 mtkcam HAL 框架,同样基于 HAL3,但内部 Pipeline 设计与 QCOM 差异较大。