一、相机系统全景概览

做Android相机优化这么多年,我最大的感受是——你得先看清全局,才能动手调优。很多人一上来就盯着某个模块猛改,结果往往是按下葫芦浮起瓢。今天这一章,我们就从架构、指标、思路三个维度,把相机系统的底牌翻个底朝天。

1.1 Android相机架构:三层模型

Android相机系统说白了就三层:App层、Camera Service层、Camera HAL层。每一层都有自己的职责,也都有自己的坑。

核心架构图:Android相机三层模型

App层(应用层) Camera2 API / CameraX 预览、拍照、录像、滤镜、美颜 Camera Service层(框架层) CameraService / CameraProvider 权限管理、流配置、会话管理、3A策略 Camera HAL层(硬件抽象层) HAL3 / HIDL / AIDL Sensor驱动、ISP处理、3A算法、Buffer管理 数据流方向:App → Service → HAL(请求下发) | HAL → Service → App(帧数据回传)

嗯,这张图我画了很多遍。每次给团队新人讲架构,我都会指着它说:你看到的每一帧画面,都是这三层协作的结果。哪一层出了问题,最终都会反映到用户体验上。

App层

这是离用户最近的一层。说白了,就是各种相机App——系统相机、微信扫码、抖音直播。它们通过Camera2 API或CameraX向底层发请求。我个人习惯把这一层叫做"需求发起方"。

  • 预览流:要求低延迟、高帧率
  • 拍照流:要求高画质、低噪声
  • 录像流:要求稳定帧率、编码效率

我的经验:很多App开发者抱怨相机启动慢,其实问题往往不在App层,而是底层流配置太复杂。我曾经在一个项目里,App层每次启动都要重新配置3个流,结果光配置时间就占了500ms。后来改成复用Session,直接砍掉300ms。

Camera Service层

这一层是"调度中心"。它负责把App的请求翻译成HAL能理解的指令,同时管理权限、流配置、会话生命周期。你想想看,如果Service层处理不当,App发一个请求它卡一下,那延迟就上去了。

我记得有一次排查帧率抖动问题,发现是Service层在每次帧回调时都做了一次权限检查。嗯,权限检查本身没问题,但放在主路径上就不对了。后来我们把它移到初始化阶段,帧率立刻稳定了。

Camera HAL层

这是真正的"干活"层。Sensor曝光、ISP处理、3A算法、Buffer管理,全在这里。HAL层的性能直接决定了相机的天花板。

做HAL优化,我个人最看重三点:

  1. Buffer流转效率——别让Buffer在内存里"旅游"
  2. 3A收敛速度——曝光、对焦、白平衡要快速稳定
  3. ISP管线延迟——每一级处理都要"快进快出"

1.2 相机性能指标:三个核心维度

做性能优化,你得先知道"好"的标准是什么。我一般只看三个指标:延迟、帧率、功耗。这三者互相制约,说白了就是"不可能三角"。

指标 定义 典型目标值 优化难点
延迟 从触发到画面显示的时间 预览启动 < 200ms
拍照 < 100ms
HAL管线长、Buffer分配慢
帧率 每秒输出的帧数 预览 30fps / 60fps
录像 30fps / 60fps
ISP处理能力、带宽瓶颈
功耗 相机模组+ISP+CPU的功耗 预览 < 400mW
录像 < 600mW
Sensor功耗、ISP频率、CPU负载

注意:这三个指标是互相拉扯的。你想降低延迟,可能就得提高ISP频率,功耗就上去了。你想省电,降帧率,用户又说卡。所以优化不是单点突破,而是全局权衡。

1.3 性能优化的核心思路

做了这么多年相机优化,我总结了一套思路,分享给你:

思路一:先测量,再优化

没有数据就没有发言权。我习惯在项目一开始就埋好性能打点:

// 关键路径打点示例
Trace.beginSection("CameraOpen");
int ret = camera_device->open();
Trace.endSection();

Trace.beginSection("ConfigureStreams");
int ret = stream_manager->configure(streams);
Trace.endSection();

Trace.beginSection("ProcessCaptureRequest");
hal_result_t result = hal->process(request);
Trace.endSection();

我曾经接手过一个项目,团队说"相机启动慢",但谁也说不出具体慢在哪。我加了打点后发现,光HAL层的Sensor初始化就占了800ms。嗯,找到根因就好办了——后来我们做了Sensor预初始化,启动时间直接砍半。

思路二:分层优化,各司其职

每一层都有自己该做的事:

  • App层:减少不必要的流配置、复用Session、异步处理
  • Service层:精简权限检查、优化Binder通信、减少主路径阻塞
  • HAL层:优化ISP管线、减少Buffer拷贝、加速3A收敛

思路三:抓大放小,先解决主要矛盾

别一上来就纠结那1ms的优化。先看看整体流程里,哪一段最耗时。我一般用Systrace抓一次完整流程,然后找"长条"——就是那些占用时间最长的模块。先把这些大头砍掉,再去抠细节。

核心优化流程图:从问题到方案

1. 性能打点 Systrace / Perfetto 2. 定位瓶颈 找最长耗时模块 3. 分层优化 App/Service/HAL 4. 验证效果 对比数据 迭代循环,直到达标

思路四:别忘了功耗

很多工程师只盯着延迟和帧率,把功耗抛在脑后。结果呢?相机是快了,但手机烫得能煎鸡蛋。我见过一个项目,为了把预览帧率从30fps提到60fps,直接把ISP频率拉满,功耗飙到800mW。用户反馈说"拍照5分钟,手机烫手"——这优化还不如不做。

所以我的原则是:在功耗预算内做性能优化。先定好功耗红线,再在这个范围内去压榨性能。

避坑指南:我曾经在一个项目里,花了整整两周优化HAL层的Buffer流转,把延迟从120ms降到了80ms。结果一测功耗,涨了150mW。后来发现是Buffer复用策略改得太激进,导致DDR带宽飙升。嗯,有时候"快"不一定是好事,得看代价。

小结

这一章我们聊了Android相机的三层架构、三个核心指标、以及优化的基本思路。说白了,相机优化不是闷头改代码,而是先看清全局,再动手。下一章我们会深入HAL层,看看具体的延迟优化怎么做。


公众号:蓝海资料掘金营,微信deep3321