第一章:HAL层全景概览

各位同学,咱们今天聊聊Camera HAL。说实话,我刚入行那会儿,HAL这个概念也让我迷糊了好一阵子。你想想看,一个相机系统从APP按下快门到最终出图,中间要经过多少层?HAL就是那个承上启下的关键角色。

1.1 Camera HAL架构演进

Android相机HAL的演进,说白了就是一部「从简单粗暴到精细控制」的历史。我经历过HAL1时代,那时候调试相机就像开手动挡汽车——能跑,但想玩出花来?难。

早期的HAL1架构,设计思路很直接:

  • APP调用一个接口,HAL就做一件事
  • 预览、拍照、录像,各走各的流程
  • 底层硬件控制基本暴露给上层

但问题很快就暴露了。我记得有一次做双摄项目,HAL1下想同时控制两个摄像头,那叫一个痛苦。代码改来改去,最后发现架构本身就不支持这种玩法。

到了HAL3,Google算是彻底想明白了。他们把相机抽象成一个「流水线工厂」:

  • 每个请求(Request)就是一个订单
  • 底层硬件按订单生产结果(Result)
  • 中间可以灵活插入各种处理节点

核心变化:从「函数调用」变成了「请求-响应」模型。这个转变,让多帧合成、HDR、夜景模式这些高级功能有了实现的土壤。

1.2 HAL3 vs HAL1:核心差异

咱们直接上对比表,这样更直观:

对比维度 HAL1 HAL3
控制粒度 粗放,一次只能做一件事 精细,支持多请求并发
数据流模型 同步阻塞 异步流水线
多摄像头支持 基本不支持 原生支持
延迟控制 难以优化 可精细调优
厂商定制空间 有限 灵活

嗯,这里我要特别强调一下「延迟控制」这个点。HAL1时代,你想优化拍照延迟?基本只能靠改驱动。但在HAL3下,你可以通过调整Pipeline的深度、buffer的分配策略、甚至请求的优先级来精细控制。

我的经验:从HAL1迁移到HAL3,最痛苦的不是代码重写,而是思维方式的转变。你不能再想着「我调一个函数就能拿到结果」,而是要习惯「我发一个请求,等回调通知我」。异步编程的坑,我踩过不少。

1.3 HAL在Android相机栈中的位置

咱们把Android相机栈从上到下捋一遍:

  1. APP层:Camera2 API调用者,比如微信、抖音
  2. Framework层:CameraService,负责调度和策略
  3. HAL层:咱们今天的主角,连接Framework和硬件
  4. Kernel层:V4L2驱动、ISP驱动
  5. 硬件层:Sensor、Lens、Flash

HAL的位置很微妙。它既要听懂Framework的「高级指令」,又要指挥硬件干「苦力活」。说白了,HAL就是个翻译官+包工头。

为什么会这样设计?我个人的理解是:Google想把硬件差异都挡在HAL这一层。Framework只关心「我要什么效果」,不关心「你用什么Sensor、怎么调ISP」。这样APP开发者就不用管你是索尼IMX766还是三星GN1了。

避坑指南:我曾经遇到过一个项目,厂商在HAL层里塞了大量业务逻辑,结果Framework升级后接口变了,整个HAL都得重写。记住,HAL只做硬件抽象,别把它当应用层用。

1.4 性能调优的切入点

了解了HAL的架构和位置,咱们才能谈性能调优。我个人习惯把HAL层的性能问题分成三类:

  • 延迟问题:从请求发出到结果返回,时间太长
  • 吞吐问题:单位时间内能处理的请求太少
  • 抖动问题:延迟忽高忽低,不稳定

这三类问题,在HAL3架构下都有对应的优化手段。比如延迟问题,可以调整Pipeline的buffer数量;吞吐问题,可以优化请求的并发策略;抖动问题,往往和内存分配、锁竞争有关。

嗯,这一章咱们先把全景图看清楚。后面几章,我会带着大家深入每个环节,看看具体怎么调、怎么优。你想想看,搞清楚了HAL的来龙去脉,后面再遇到性能问题,是不是心里就有底了?

本章小结:

  • HAL架构从HAL1演进到HAL3,核心是控制粒度的提升
  • HAL3的请求-响应模型,为高级功能提供了基础
  • HAL在相机栈中起承上启下的作用,是性能调优的关键层
  • 性能问题分延迟、吞吐、抖动三类,各有优化方向