兼容性与碎片化处理:不同SoC平台差异

做Camera HAL这么多年,我最大的感触就是——Android的碎片化,是每个底层工程师的必修课。你想想看,同一套Camera HAL代码,要在高通、联发科、三星Exynos、谷歌Tensor上跑通,还要兼容从Android 10到14的API差异,再加上各家OEM的定制魔改……嗯,这活儿真不是谁都能干的。

我个人习惯把碎片化问题分成三个维度来拆解:SoC平台差异、Android版本API差异、OEM定制化问题。咱们一个一个说。

1. 不同SoC平台的底层差异

先说高通。高通平台在Camera HAL这块做得最成熟,文档也最全。它的camx架构从Android 9开始就稳定了,CHI(Camera HAL Interface)这套东西,说白了就是帮你把ISP、传感器、算法模块串起来。我在项目中遇到过最典型的问题——高通平台的UVC Camera兼容性。有些第三方USB摄像头在高通上跑得好好的,换到MTK上就黑屏。为什么?因为MTK的UVC驱动实现跟高通不一样,它要求特定的帧间隔配置。

核心差异点:

  • 高通:camx + CHI架构,ISP管线可编程性强,支持多Camera并发
  • MTK:自研ISP + 私有HAL实现,对第三方Sensor兼容性较差
  • Exynos:三星自研,ISP集成度高,但文档封闭,调试困难
  • Tensor:基于Exynos魔改,加入了Google自己的ML加速单元

MTK平台我踩过的坑最多。有一次客户要求在MTK平台上实现HDR+拍照,结果发现MTK的ISP不支持多帧合成的硬件加速。没办法,只能走CPU后处理,帧率直接掉到2fps。后来我学乖了——做MTK平台,一定要先确认ISP的硬件能力

Exynos平台呢?说实话,它的ISP性能其实不差,但问题在于文档和工具链。三星的Camera HAL代码里经常有未公开的私有API,你只能靠反编译和抓log来猜。我记得有一次调试Exynos的AE(自动曝光)算法,发现它的曝光收敛速度比高通慢一倍,最后查出来是三星的ISP驱动里有个默认的防抖参数没关。

Tensor平台比较新,我接触得不多。但有一点可以肯定——它的ML加速单元对Camera pipeline有直接影响。比如Google的Real Tone算法,就是靠Tensor的TPU来做肤色还原。如果你要在Tensor上做第三方Camera App,得注意它的HAL层可能已经绑定了Google自己的算法模块。

2. Android版本API差异

Android版本升级,对Camera HAL来说就是一场噩梦。我列个表,你感受一下:

Android版本 关键API变化 对HAL的影响
Android 10 引入CameraX,HAL3成为强制 老设备必须升级HAL3,否则无法使用
Android 11 新增CAMERA_SERVICE_PRIORITY 多Camera场景下优先级调度变化
Android 12 强制CONFIGURATION_SUCCESS回调 HAL必须正确返回配置状态
Android 13 引入SESSION_CONFIGURATION新接口 老HAL代码需要适配新接口
Android 14 Ultra HDR支持,RAW16格式变化 ISP管线需要支持新的HDR元数据

我个人觉得,Android 12到13的过渡是最痛苦的。为什么?因为Google在Android 13里改了CameraMetadata的序列化方式。以前你写HAL代码,直接往metadata里塞key-value就行。现在不行了,必须走VendorTag注册流程。我有个项目,就因为没及时适配这个变化,导致第三方Camera App在Android 13上无法获取到自定义的AE参数。

避坑指南:我曾经在Android 11升级到12时,忽略了CAMERA_SERVICE_PRIORITY的变化。结果多Camera场景下,主摄和广角同时打开时,广角经常被系统杀掉。后来发现是优先级没配好。解决办法很简单——在HAL的open()函数里,根据Camera ID设置不同的优先级。

3. OEM定制化问题处理

OEM定制化,说白了就是各家手机厂商在Android原生基础上加自己的私货。小米的MiuiCamera、OPPO的ColorOS Camera、华为的EMUI Camera……每个都有自己的HAL扩展。

我遇到过最离谱的一次——某厂商在HAL层加了一个vendor.qti.hardware.camera.postproc的私有服务,用来做美颜。结果这个服务跟高通的camx有冲突,导致拍照时ISP管线卡死。查了三天log,最后发现是私有服务的线程优先级比camx的ISP线程高,抢占了CPU资源。

处理OEM定制化问题,我有三个原则:

  1. 先看Vendor目录:OEM的定制代码通常放在vendor/目录下,别去动hardware/里的原生代码
  2. 抓取Vendor log:用logcat -b vendor抓取OEM私有服务的日志
  3. 对比原生HAL:把OEM的HAL代码跟AOSP原生代码做diff,找出差异点

警告:千万不要直接修改OEM的HAL代码!我曾经手贱改了一行小米的MiuiCamera代码,结果OTA升级时被覆盖了,导致线上用户拍照闪退。正确的做法是——在HAL层之上加一个适配层,用VendorTag来桥接OEM的私有接口。

4. 知识体系总览

下面这张图,是我自己整理的Camera碎片化处理知识体系。你看一眼,心里就有数了:

Camera碎片化处理 SoC平台差异 高通:camx + CHI架构 MTK:自研ISP + 私有HAL Exynos:文档封闭,调试困难 Tensor:ML加速单元影响 Android版本API差异 Android 10:HAL3强制 Android 11:优先级调度 Android 12:CONFIGURATION回调 Android 13-14:新接口+HDR OEM定制化问题 小米:MiuiCamera私有服务 OPPO:ColorOS HAL扩展 华为:EMUI私有接口 适配层 + VendorTag桥接 核心思路:分层处理 + 适配层桥接 + 日志对比 不直接修改OEM代码,通过VendorTag和适配层兼容

5. 实战建议

最后,给你几个实战建议:

  • 建立平台兼容性矩阵:把每个SoC平台支持的Camera特性列出来,比如HDR、多帧合成、RAW格式等。我习惯用Excel维护这个矩阵,每次新项目先查一遍。
  • 使用抽象层隔离差异:在HAL之上加一个CameraPlatformAdapter,把平台相关的代码封装起来。这样换平台时,只需要改适配层。
  • 自动化测试覆盖:写一个脚本,自动在多个Android版本上跑Camera CTS测试。我吃过亏——Android 13上有个testCameraMetadata用例没过,结果导致Google认证卡了两周。

小技巧:如果你要在新平台上快速验证Camera HAL,可以用adb shell dumpsys media.camera来查看当前设备的Camera能力。这个命令会输出所有Camera ID、支持的分辨率、帧率范围等信息。我每次拿到新设备,第一件事就是跑这个命令。

嗯,碎片化处理这事儿,说白了就是经验积累 + 工具链完善。你踩过的坑越多,后面的路就越顺。别怕,慢慢来。