2. Camera HAL1 架构详解

Camera HAL1 是 Android 平台上最早定义的相机硬件抽象层标准,从 Android 1.0 开始引入,直至 Android 8.0 仍被广泛支持。HAL1 的核心设计思想是以 CameraService 为中心,通过同步阻塞模型控制相机硬件。理解 HAL1 是掌握后续 HAL3、HAL4 演进的基础。

学习提示:HAL1 虽然已被 Google 标记为 deprecated(弃用),但大量中低端设备、车载系统、IoT 设备仍在沿用。掌握 HAL1 能帮助你快速定位 legacy 平台上的相机问题。

2.1 HAL1 模块结构

HAL1 在系统层次中位于 CameraService(Java/Native 层)与 Kernel Camera Driver 之间。其模块加载遵循 Android HAL 标准规范,通过 hw_get_module() 动态加载 camera.<platform>.so 共享库。

关键文件路径:
hardware/libhardware/include/hardware/camera.h —— 定义 camera_module_t 和 camera_device_t
hardware/libhardware/modules/camera/ —— 参考实现
device/<vendor>/<platform>/camera/ —— 厂商实际 HAL 源码
HAL1 模块加载与层次结构 Android Camera App / API1 CameraService (Native) camera_module_t (camera.<platform>.so) hw_get_module() → open() → get_number_of_cameras() camera_device_t Camera ID 0 (Back) camera_device_t Camera ID 1 (Front) Kernel V4L2 / Camera Sensor Driver

2.2 CameraHardwareInterface 接口

在 HAL1 架构中,CameraHardwareInterface 是连接 CameraService 与底层硬件实现的核心 C++ 抽象类。它定义了一组纯虚函数,厂商必须实现这些接口才能驱动相机硬件。

接口方法 功能描述 调用时机
setCallbacks() 注册通知/数据回调函数 open() 后立即调用
setPreviewWindow() 绑定 Surface 用于预览显示 startPreview() 之前
startPreview() 启动预览数据流 用户调用 Camera.startPreview()
stopPreview() 停止预览数据流 用户调用 Camera.stopPreview()
takePicture() 触发拍照流程(含 shutter/raw/compressed) 用户调用 Camera.takePicture()
autoFocus() 启动自动对焦 拍照前或用户触发
setParameters() 设置相机参数(分辨率、fps、白平衡等) 随时可调用
getParameters() 获取当前相机参数 随时可调用
接口定义示例(简化):
class CameraHardwareInterface : public virtual RefBase {
public:
    virtual status_t setCallbacks(
        camera_notify_callback notify_cb,
        camera_data_callback data_cb,
        camera_data_timestamp_callback data_cb_timestamp,
        camera_request_memory get_memory,
        void* user) = 0;

    virtual status_t setPreviewWindow(
        preview_stream_ops_t* window) = 0;

    virtual status_t startPreview() = 0;
    virtual void     stopPreview() = 0;

    virtual status_t takePicture() = 0;
    virtual status_t autoFocus() = 0;

    virtual status_t setParameters(const CameraParameters& params) = 0;
    virtual CameraParameters getParameters() const = 0;
};

2.3 预览与拍照流程

2.3.1 预览流程

HAL1 的预览流程采用同步轮询 + 回调通知模式。CameraService 通过 preview_stream_ops_t 接口向 HAL 提供 dequeue_buffer() / enqueue_buffer() 机制,HAL 驱动在完成帧采集后直接填充 buffer 并回调。

HAL1 预览数据流时序 Camera App CameraService HAL1 Kernel Driver ① startPreview() ② setPreviewWindow() ③ 启动 sensor 采集 ④ 帧中断 → DMA ⑤ data_callback() ⑥ enqueue_buffer()

2.3.2 拍照流程

HAL1 的拍照流程比预览复杂,因为它需要依次产生 shutter 回调、raw 数据回调(可选)、jpeg 压缩数据回调。整个过程在 HAL 内部是同步串行的,CameraService 在收到 shutter 回调后才会等待后续数据。

  1. 触发拍照:App 调用 Camera.takePicture() → CameraService → HAL takePicture()
  2. Shutter 回调:HAL 立即调用 notify_callback(SHUTTER),通知上层播放快门音效
  3. Raw 数据(可选):如果 App 注册了 raw 回调,HAL 输出未压缩的 Bayer 数据
  4. JPEG 压缩:HAL 内部完成 ISP 处理 + JPEG 编码,通过 data_callback(COMPRESSED) 返回
  5. 停止预览(可选):部分实现会在拍照期间自动停止预览,拍照完成后再恢复
HAL1 拍照的典型问题:由于 JPEG 压缩在 HAL 内部同步完成,拍照期间整个相机管线被阻塞。如果 JPEG 编码耗时较长(例如 8MP 以上图片),会导致明显的快门延迟(shutter lag),用户体验较差。

2.4 优缺点分析

维度 优点 缺点
架构复杂度 接口简单,厂商实现门槛低 扩展性差,新增功能需修改核心接口
性能 预览延迟较低(直接 buffer 流转) 拍照时阻塞管线;不支持并行流(如同时预览+录像)
内存管理 使用 camera_request_memory 统一分配 buffer 复用策略僵化,高分辨率场景容易 OOM
多相机支持 支持多设备 ID,但各自独立 无法实现双摄同步、深度融合等高级特性
兼容性 所有 Android 版本均支持,生态成熟 Google 已弃用,新特性(如 HDR+、夜景)无法在 HAL1 上高效实现
调试难度 流程线性,日志容易追踪 同步模型导致死锁风险;回调上下文复杂
总结:HAL1 适合功能简单的单摄设备,以及需要快速上市的中低端产品。对于追求计算摄影、多摄协同、低延迟录像的旗舰设备,HAL1 已经成为瓶颈,必须迁移到 HAL3 或更高版本。