Camera 性能优化

MTK Camera性能优化:冷启动全链路八阶段分析与优化实战

用户点开Camera到看到第一帧画面的时间,直接决定用户体验。冷启动(Cold Start)是性能优化中最复杂的场景——没有缓存、没有预热、从零开始。这篇把MTK Camera冷启动的全链路拆成8个阶段,逐个分析时间瓶颈和优化手段,供大家参考。

一、冷启动 vs 热启动

先搞清楚两个概念:

┌────────────┬──────────────────────────────────────────┐
│ Cold Start │ 冷启动                                    │
│ (冷启动)    │ Camera进程首次创建, 无任何缓存             │
│            │ → Sensor上电, 3A初始化, Pipeline构建        │
│            │ → 耗时最长, 是性能优化的重点               │
│            │ → 典型目标: < 1000ms (从点击到首帧显示)   │
├────────────┼──────────────────────────────────────────┤
│ Warm Start │ 热启动                                    │
│ (热启动)    │ Camera进程已存在, 快速重新打开             │
│            │ → Sensor已上电, Pipeline可复用              │
│            │ → 耗时短, 通常 < 300ms                     │
│            │ → 优化空间有限                            │
└────────────┴──────────────────────────────────────────┘

// 用户体验核心指标:
// 点击Camera图标 → 看到第一帧画面的总时间
// 这个时间 = S0 + S1 + S2 + S3 + S4 + S5 + S6 + S7

二、冷启动八阶段总览

MTK Camera冷启动从用户点击图标到首帧显示在屏幕上,共经历8个阶段(S0-S7)。每个阶段都有明确的起止点和时间贡献:

Camera Cold Start 八阶段:

S0 ─── S1 ─── S2 ─── S3 ─── S4 ─── S5 ─── S6 ─── S7
 │       │       │       │       │       │       │       │
点击    App     Open    配置    创建    提交    首帧    首帧
图标    启动    完成    流流    请求    请求    产生    显示

┌──────┬──────────────────────────────────────────────────┐
│ S0   │ User finger leave camera icon                    │
│      │ 点击事件 → InputReader → App启动                   │
│      │ 时间贡献: ~200ms (系统层, Camera无法控制)          │
├──────┼──────────────────────────────────────────────────┤
│ S1   │ App open camera (appstart → connect)              │
│      │ APK Activity init → Camera Service连接             │
│      │ 时间贡献: ~400-450ms (APK层)                      │
├──────┼──────────────────────────────────────────────────┤
│ S2   │ App open done (connect → opendone)                │
│      │ Open Device / Init3A / Power on Sensor             │
│      │ 时间贡献: ~200-300ms (HAL层, 优化重点)            │
├──────┼──────────────────────────────────────────────────┤
│ S3   │ App configure streams (opendone → configure)      │
│      │ APK配置Stream → ConfigureStreams                   │
│      │ 时间贡献: ~400-450ms (APK层)                      │
├──────┼──────────────────────────────────────────────────┤
│ S4   │ ConfigureStreams done → create request             │
│      │ MW ConfigureStreams_3_4 → 创建CaptureRequest      │
│      │ 时间贡献: ~50-100ms (MW层)                        │
├──────┼──────────────────────────────────────────────────┤
│ S5   │ SetRepeating request (configure → submitrequest) │
│      │ App提交request list → Camera Service               │
│      │ 时间贡献: ~50-100ms (APK层)                      │
├──────┼──────────────────────────────────────────────────┤
│ S6   │ First camera frame out (submit → 1st frame)      │
│      │ Pipeline执行: P1 → P2A → P2S → Output             │
│      │ 时间贡献: ~100-200ms (HAL层, 最核心!)             │
├──────┼──────────────────────────────────────────────────┤
│ S7   │ First frame show on panel (1st frame → display)  │
│      │ SurfaceFlinger: queueBuffer → VSYNC → 显示        │
│      │ 时间贡献: ~16-50ms (Display层)                   │
└──────┴──────────────────────────────────────────────────┘

// 总时间: ~1500-2000ms (未优化)
// 优化目标: < 1000ms

// 优化优先级:
// S1/S3 (APK层) → 占比最大, 但Camera团队能力有限
// S2 (HAL层)    → Camera团队可直接优化
// S6 (Pipeline) → Camera团队核心战场
// S7 (显示层)   → 优化空间有限

三、各阶段深度分析

3.1 S0:点击事件传播

S0: User finger leave camera icon

事件链:
  Touch事件 → InputReader → InputDispatcher → App

分析:
  system_server中查找InputReader
  可以获取到点击事件

  这个阶段完全在系统层
  Camera团队无法优化
  典型耗时: ~200ms

3.2 S1:App启动Camera

S1: App open camera (appstart → connect)

事件链:
  APK Activity init → Camera Service connect

分析:
  HIDL层可找到APK发来的cmd
  Activity init等操作占用此阶段时间
  典型耗时: ~400-450ms

优化方向:
  → APK侧优化: 减少Activity init耗时
  → 预加载: Camera相关Class提前加载
  → 但这通常不在Camera团队的优化范围内

3.3 S2:Open Device与初始化(优化重点)

S2: App open done (connect → opendone)

事件链:
  1. Open Device → Camera HAL设备打开
  2. Init3A → AE/AWB/AF算法初始化
  3. Power on Sensor → Sensor上电

分析:
  Power on Sensor通常不直接影响Launch time
  因为它在其他线程执行
  但仍需关注其完成时间

典型耗时: ~200-300ms

优化方向:
  ★ 异步初始化: 3A初始化与其他流程并行
  ★ 延迟加载: 非关键模块延迟初始化
  ★ Sensor上电优化: 减少上电时序等待
  ★ 预分配Buffer: Pipeline Buffer提前分配

3.4 S3-S5:配置与提交

S3: App configure streams (opendone → configurestreams)
  APK配置Stream → 典型耗时: ~400-450ms
  这部分时间主要在APK侧

S4: ConfigureStreams done → create request
  MW ConfigureStreams_3_4 → 创建CaptureRequest
  典型耗时: ~50-100ms

S5: SetRepeating request (configure → submitrequest)
  App提交request list → Camera Service
  典型耗时: ~50-100ms

优化方向:
  → 减少ConfigureStreams的Stream数量
  → 简化Request的Surface配置
  → MW层Pipeline构建优化

四、S6深度分析:首帧Pipeline(核心战场)

S6是从提交Request到首帧产出的时间,是Camera团队最核心的优化战场。它分为4个子阶段:

S6: First camera frame out (submitrequest → 1st frame out)

┌──────────────────────────────────────────────────────────┐
│ S6_1: App Request → Camera HAL process request           │
│                                                          │
│  ① App Request → Cameraservice                           │
│  ② Cameraservice → Camera HAL                            │
│  ③ Camera HAL process request                            │
│                                                          │
│  这三步的总时间是关键, 称为S6_1                            │
│  典型耗时: ~30-50ms                                      │
├──────────────────────────────────────────────────────────┤
│ S6_2: P1 → P2A dispatch                                 │
│                                                          │
│  P1 release → P2 dispatch → P2A Loop In                 │
│                                                          │
│  Pass1 Ring Buffer释放第一帧                              │
│  → 触发Pass2 Dispatch                                    │
│  → P2A(Preview) Loop进入处理                              │
│                                                          │
│  典型耗时: ~20-40ms                                      │
├──────────────────────────────────────────────────────────┤
│ S6_3: P2S process frame                                  │
│                                                          │
│  P2S处理帧 = P2A process + 3rd feature process time      │
│                                                          │
│  Pass2 Streaming处理首帧:                                 │
│  → ISP处理 (BPC/CT/DBS/Color/Gamma等)                   │
│  → 第三方Feature Node处理                                │
│  → 图像后处理                                              │
│                                                          │
│  典型耗时: ~30-60ms                                      │
├──────────────────────────────────────────────────────────┤
│ S6_4: P2S out → image to app                            │
│                                                          │
│  P2S输出 → convertImage → 送给App                        │
│                                                          │
│  convertImage stream 0 = streaming data (Preview)        │
│  → 将处理后的图像转换为App可用的格式                       │
│  → 通过CameraService回调给App                             │
│                                                          │
│  典型耗时: ~10-20ms                                      │
└──────────────────────────────────────────────────────────┘

// S6总典型耗时: ~90-170ms
// 优化目标: < 100ms

S6优化要点

S6 优化 Checklist:

1. P1 Ring Buffer优化
   → 预热Ring Buffer, 避免首次分配
   → 减少Pass1等待Sensor出帧的时间
   → 检查RRZO/IMGO size配置是否合理

2. P2A Pipeline优化
   → 减少不必要的Feature Node
   → 首帧可降级处理 (关闭非关键Feature)
   → 检查P2A Loop是否有不必要的等待

3. P2S处理优化
   → ISP Pipeline串并行优化
   → 第三方Feature Node延迟加载
   → 首帧可跳过部分处理 (如NR/HRD)

4. Output优化
   → convertImage优化, 避免不必要的格式转换
   → 确认Surface配置正确, 无冗余Stream
   → Buffer流转效率优化

五、S7:首帧显示在屏幕

S7是首帧从Camera HAL产出到显示在屏幕上的时间。虽然Camera团队优化空间有限,但理解原理很重要:

S7: First frame show on panel (1st frame out → display)

SurfaceFlinger处理流程:

① queueBuffer
   Camera HAL将处理完的帧放入Buffer Queue

② SurfaceView receive buffer
   SurfaceView接收到buffer, 进入高优先级处理

③ SurfaceView deque finished
   SurfaceView dequeue完成
   等待VSYNC_SF信号

④ 等待VSYNC_SF
   VSYNC_sf edge信号在SurfaceView deque之前到达
   所以需要等待下一个VSYNC周期
   这意味着最多等待16.67ms (60Hz屏幕)

⑤ VSYNC_sf edge signal
   SurfaceFlinger开始工作

⑥ SurfaceFlinger work and release buffer
   SurfaceFlinger处理buffer并释放

⑦ Wait HW_VSYNC (16ms)
   SurfaceFlinger释放buffer后
   还需等待一个HW_VSYNC (~16ms)
   buffer才会刷新到Display

典型耗时: 16-50ms (取决于VSYNC对齐)

// S7优化方向:
// → 减少VSYNC等待: 提前queueBuffer, 对齐VSYNC
// → 减少SurfaceFlinger处理时间
// → 但这通常在Display/系统团队范围内

六、测量工具与方法

6.1 Systrace / Perfetto

// Systrace是分析Camera冷启动的标准工具
// 可以可视化每个阶段的耗时和线程调度

// 抓取命令:
adb shell atrace --async_start
# 打开Camera App
adb shell atrace --async_stop > camera_cold_start.html

// 关注的Trace类别:
# Camera HAL相关的trace:
- camera (CameraService + HAL)
- hal (HIDL调用)
- gfx (SurfaceFlinger)
- sched (CPU调度)
- freq (CPU频率)

# 在Trace中搜索关键字:
- "openCamera" → S1
- "configureStreams" → S3-S4
- "submitRequestList" → S5
- "processCaptureRequest" → S6
- "queueBuffer" → S7

// Perfetto (新平台替代Systrace):
adb shell perfetto -o /data/misc/perfetto-traces/camera.trace \
  -t 10s sched freq idle cam gpu gfx
adb pull /data/misc/perfetto-traces/camera.trace

6.2 MTKLogger

// MTKLogger可以抓取Camera各层的详细日志
// 用于精确分析每个阶段的耗时

// 开启Camera相关日志:
adb shell setprop debug.camera.log 1
adb shell setprop vendor.debug.camera.log 1
adb shell setprop debug.hal3av3.log 1
adb shell setprop debug.aaa_log.enable 1

// 抓取后搜索关键字:
// S1-S2: "openCamera" / "connect" / "openDevice"
// S3-S4: "configureStreams" / "CreateCaptureRequest"
// S5:    "submitRequest" / "setRepeatingRequest"
// S6:    "processCaptureRequest" / "P1" / "P2A" / "P2S"
// S7:    "queueBuffer" / "onFrameAvailable"

// cold_start.html (如果平台支持):
// 直接打开浏览器查看各阶段耗时分析

6.3 测量方法标准化

// 标准测量流程:

1. 重启手机, 等待系统稳定 (至少2分钟)
2. 清理后台进程 (确保Camera进程不存在)
3. 开启Systrace/MTKLogger
4. 点击Camera图标
5. 等待首帧显示
6. 停止抓取
7. 分析各阶段耗时

// 测量注意事项:
// - 每次测量至少3次, 取平均值
// - 测量前关闭省电模式 (避免CPU限频)
// - 注意温度影响 (过热会降频)
// - 区分冷启动和热启动
// - 记录测量时的系统版本和配置

// 快速判断:
// 总时间 > 1500ms → 需要优化
// S2 > 300ms      → HAL初始化有问题
// S6 > 150ms       → Pipeline有瓶颈
// S7 > 50ms        → 显示层有延迟

七、常见瓶颈与优化手段

┌────┬─────────────────────────┬──────────────────────────────┐
│ #  │        瓶颈              │         优化手段               │
├────┼─────────────────────────┼──────────────────────────────┤
│  1 │ Sensor上电慢            │ 异步上电, 与App init并行       │
│    │                         │ 优化I2C通信频率               │
├────┼─────────────────────────┼──────────────────────────────┤
│  2 │ 3A初始化耗时长          │ 延迟非关键3A模块初始化          │
│    │                         │ 预加载默认参数                 │
│    │                         │ 并行初始化AE/AWB/AF            │
├────┼─────────────────────────┼──────────────────────────────┤
│  3 │ P1 Ring Buffer首次分配  │ 预分配Buffer, 避免首次动态分配  │
│    │                         │ 合理设置Buffer Count           │
├────┼─────────────────────────┼──────────────────────────────┤
│  4 │ P2 Pipeline构建慢       │ 简化首帧Pipeline              │
│    │                         │ 首帧降级: 关闭NR/HRD等Feature │
│    │                         │ Feature Node延迟加载           │
├────┼─────────────────────────┼──────────────────────────────┤
│  5 │ ISP处理首帧慢           │ 检查首帧分辨率是否合理         │
│    │                         │ 避免首帧不必要的全分辨率处理   │
│    │                         │ ISP Clock频率是否足够          │
├────┼─────────────────────────┼──────────────────────────────┤
│  6 │ ConfigureStreams重复    │ 减少不必要的Stream配置         │
│    │                         │ 合并Preview和VideoStream       │
├────┼─────────────────────────┼──────────────────────────────┤
│  7 │ SurfaceFlinger VSYNC    │ 提前queueBuffer对齐VSYNC       │
│    │ 等待                    │ 减少Buffer转换延迟             │
├────┼─────────────────────────┼──────────────────────────────┤
│  8 │ CPU频率不足导致         │ Camera场景提升CPU最低频率      │
│    │ Pipeline慢              │ 确保Camera期间不被限频         │
│    │                         │ 检查thermal throttling         │
└────┴─────────────────────────┴──────────────────────────────┘

八、性能优化速查表

Camera Cold Start 性能速查:

┌───────────┬──────────────┬───────────────────────────────┐
│   阶段    │  典型耗时     │         优化重点               │
├───────────┼──────────────┼───────────────────────────────┤
│ S0 点击   │ ~200ms       │ 系统层, 无法优化               │
├───────────┼──────────────┼───────────────────────────────┤
│ S1 启动   │ ~400-450ms   │ APK层, 预加载                  │
├───────────┼──────────────┼───────────────────────────────┤
│ S2 打开   │ ~200-300ms   │ ★ HAL层优化重点               │
│           │              │ 异步初始化, 预分配Buffer       │
├───────────┼──────────────┼───────────────────────────────┤
│ S3 配置   │ ~400-450ms   │ APK层, 减少Stream数量          │
├───────────┼──────────────┼───────────────────────────────┤
│ S4 创建   │ ~50-100ms    │ MW层, Pipeline构建优化         │
├───────────┼──────────────┼───────────────────────────────┤
│ S5 提交   │ ~50-100ms    │ APK层                          │
├───────────┼──────────────┼───────────────────────────────┤
│ S6 首帧   │ ~90-170ms    │ ★★ 核心优化战场               │
│           │              │ P1预热/P2降级/Feature延迟加载  │
├───────────┼──────────────┼───────────────────────────────┤
│ S7 显示   │ ~16-50ms     │ VSYNC对齐                      │
├───────────┼──────────────┼───────────────────────────────┤
│ 总计      │ ~1500-2000ms │ 优化目标: < 1000ms            │
└───────────┴──────────────┴───────────────────────────────┘

工具速查:
Systrace:  atrace --async_start/stop
Perfetto:  adb shell perfetto -t 10s sched freq cam gpu
MTKLogger: setprop debug.camera.log 1

日志关键字:
S1-S2: openCamera / connect / openDevice
S3-S4: configureStreams / CreateCaptureRequest
S5:    submitRequest / setRepeatingRequest
S6:    processCaptureRequest / P1 / P2A / P2S
S7:    queueBuffer / onFrameAvailable

📌 性能优化核心: 阶段拆解 → 定位瓶颈 → S2异步化 → S6降级 → 测量验证

小结:Camera冷启动性能优化是一个系统工程。S0-S7八个阶段中,Camera团队的核心战场在S2(HAL初始化)和S6(Pipeline执行)。S2优化靠异步化和预分配,S6优化靠Pipeline降级和Feature延迟加载。工具上Systrace/Perfetto看全局,MTKLogger看细节。记住优化三步曲:先测量定位瓶颈,再针对性优化,最后复测验证效果。 

更多Camera开发实战内容

欢迎加入知识星球「小驰成长圈」

120+ Camera工程师 · 340+ 实战内容 · 已运营1565天

小驰成长圈 知识星球

微信扫码 · 加入星球

欢迎扫码关注「小驰行动派」公众号 10 年Camera开发 | Camera技术干货 | 行业洞察 | Camera实战分享
小驰行动派公众号 扫一扫关注
分享到: 复制链接
← 上一篇 Camera功耗排查全攻略 | 建议收藏备用 下一篇 → 光子的奇幻漂流:Android Camera 到底该怎么学

相关文章

推荐课程

想系统学习 Camera 开发?看看这些课程

评论 (0)

暂无评论,快来抢沙发吧