第一章:Camera HAL 概述

1.1 Android Camera 架构简介

做 Camera HAL 开发,首先得搞清楚整个架构长什么样。我习惯把 Android Camera 系统想象成一条流水线:

  • 最上层:各种相机 App,比如系统相机、美颜相机
  • 中间层:Framework 层的 Camera Service,负责调度
  • 最底层:就是我们 HAL 层,直接跟硬件打交道

说白了,App 拍一张照片,请求要经过 Framework 层层传递,最终落到 HAL 手里。HAL 再去操作传感器、ISP、闪光灯这些硬件。嗯,这里要注意:HAL 是 Android 系统与硬件之间的契约,谁都不能越界。

核心要点:Camera HAL 是 Android 相机系统的"翻译官"。它把 Framework 的标准请求,翻译成硬件能理解的指令。

1.2 HAL 层的作用与定位

HAL 层到底干些什么活?我总结了三件事:

  1. 抽象硬件差异:不同厂商的 sensor、ISP 千差万别,HAL 把它们统一成 Android 标准接口
  2. 控制硬件行为:比如设置曝光时间、增益、帧率,这些都得 HAL 来下发
  3. 处理数据流:从 sensor 拿到原始数据,经过 ISP 处理,再送回 Framework

我在项目中遇到过一个问题:某款 sensor 的驱动接口跟标准 HAL 对不上,折腾了两天才发现是寄存器映射搞错了。你想想看,如果 HAL 层没做好适配,上层再怎么优化也是白搭。

个人经验:我建议刚入行的朋友,先把 HAL 的定位搞清楚。它不是一个"万能胶",而是一个"适配器"。它的职责是让 Android 系统能正常使用你的摄像头,而不是去实现什么花哨功能。

1.3 HAL 接口版本演进:HAL1 vs HAL3

Android Camera HAL 有两个主要版本,我分别说说它们的区别。

对比项 HAL1 HAL3
设计理念 简单、固定流程 灵活、可配置
数据流控制 Framework 主导 HAL 自主控制
支持特性 基础拍照、录像 HDR、多帧合成、RAW 输出
性能开销 较低 较高,但更灵活

HAL1 是早期版本,流程固定。Framework 说"拍照",HAL 就乖乖拍照。说白了就是个"工具人"。我刚开始做 HAL 时用的就是 HAL1,那时候觉得挺简单,但后来发现很多高级功能根本实现不了。

HAL3 就完全不一样了。它引入了 Capture RequestCapture Result 的概念。HAL 可以自主决定怎么处理每一帧数据。比如你想做多帧 HDR,HAL3 可以让你控制每一帧的曝光参数,然后自己合成。这在 HAL1 时代想都不敢想。

避坑指南:我曾经在 HAL1 上强行实现 HDR,结果性能惨不忍睹。后来切到 HAL3,同样的硬件,效果天差地别。所以,如果你的平台支持 HAL3,千万别再用 HAL1 了。

1.4 HAL 在系统启动时的加载流程

系统启动时,HAL 是怎么被加载的?我一步步拆解给你看:

  1. init 进程启动:系统启动后,init 进程读取 init.rc 文件,启动 cameraserver 服务
  2. cameraserver 启动:cameraserver 会去加载 HAL 库,路径通常是 /vendor/lib/hw/camera.xxx.so
  3. HAL 初始化:调用 HAL_module_info 中的 open() 函数,打开摄像头设备
  4. 设备枚举:HAL 返回支持的摄像头列表,比如后置、前置、深度摄像头
  5. 建立通信:Framework 通过 HAL 接口下发请求,HAL 开始工作

这里有个细节:HAL 库的命名规则camera.<platform>.so。比如高通平台就是 camera.qcom.so。我记得有一次客户把库名写错了,结果系统死活找不到 HAL,折腾了半天才发现是文件名不对。

关键点:HAL 加载失败,整个相机系统就废了。所以调试时,第一步就是确认 HAL 库有没有被正确加载。用 logcat | grep camera 看看有没有报错信息。

嗯,第一章的内容就这些。说白了,Camera HAL 就是 Android 相机系统的"地基"。地基没打好,上面盖再高的楼也是危房。我建议你先把这些基础概念吃透,后面章节我们会深入每个细节。

我的建议:如果你手头有开发板,建议亲自跑一遍 HAL 加载流程。看看 log,看看 dumpsys,比看十遍文档都管用。