3. 性能指标定义:帧率(FPS)、延迟(Latency)、抖动(Jitter)的数学定义与测量方法
在 Camera HAL 工程落地中,性能指标是衡量系统质量的标尺。帧率、延迟与抖动三者共同决定了相机预览、录像及拍照的用户体验。本章给出严格的数学定义、工程测量方法及常见陷阱。
3.1 帧率 (FPS)
数学定义:帧率是单位时间内输出的帧数,通常以每秒帧数 (Frames Per Second, FPS) 表示。对于连续帧序列,帧率定义为:
FPS = N / (t_N - t_1)
其中 t_1 为第一帧的硬件时间戳,t_N 为第 N 帧的硬件时间戳。工程中常使用滑动窗口平均帧率:
FPS_avg = (N - 1) / (t_N - t_1)
测量方法:
- 硬件时间戳法:从 Sensor 或 ISP 驱动获取 VSYNC 时间戳,精度可达微秒级。
- 应用层回调法:在 Camera HAL 的
process_capture_result或buffer_callback中记录时间。 - 示波器/逻辑分析仪法:直接测量 MIPI CSI 时钟或 VSYNC 信号。
工程注意:应用层回调受 CPU 调度和 Binder 传输影响,时间戳可能引入额外抖动。推荐优先使用硬件时间戳。
常见误区:不要用
System.currentTimeMillis() 测量帧间隔,其精度约 1-15ms,远不足以评估 30fps(33.3ms 间隔)的帧率波动。
3.2 延迟 (Latency)
数学定义:延迟是事件从发生到完成所经过的时间。在 Camera HAL 中,延迟分为多个阶段:
| 延迟类型 | 定义 | 典型值 (30fps) |
|---|---|---|
| Sensor 曝光延迟 | 从请求下发到 Sensor 开始曝光的时间 | 1-3 帧 (33-100ms) |
| ISP 管线延迟 | 从 RAW 数据输出到 YUV/JPEG 完成处理 | 2-4 帧 (66-133ms) |
| 端到端延迟 | 从物理光线进入 Sensor 到应用层显示 | 4-8 帧 (133-266ms) |
| 拍照快门延迟 | 从用户按下快门到图像捕获完成 | 100-300ms |
测量方法:
- 打点插桩法:在 HAL 关键路径插入
ktime_get()或clock_gettime(CLOCK_MONOTONIC),记录每个阶段的进入和退出时间戳。 - 光流法:使用 LED 闪烁 + 高速相机拍摄屏幕,测量物理事件到显示的时间差。
- ADB logcat 时间戳:通过
logcat -v time粗略估算,精度约 1ms。
关键陷阱:延迟测量必须区分“软件时间戳”和“硬件时间戳”。软件时间戳包含 CPU 调度延迟,在负载波动时可能引入 5-20ms 的额外误差。硬件时间戳应来自 Sensor 的帧同步信号或 ISP 的 DMA 完成中断。
3.3 抖动 (Jitter)
数学定义:抖动是帧间隔时间相对于理想间隔的偏差。对于理想帧率 FPS_target,理想帧间隔 T_ideal = 1000 / FPS_target (ms)。第 i 帧的抖动定义为:
J_i = (t_i - t_{i-1}) - T_ideal
工程中常用以下统计量描述抖动:
| 统计量 | 公式 | 物理含义 |
|---|---|---|
| 最大抖动 | max(|J_i|) | 最坏情况下的帧间隔偏差 |
| 标准差 (σ) | sqrt( Σ(J_i - μ)² / N ) | 帧间隔的离散程度 |
| 峰峰值 (Pk-Pk) | max(J_i) - min(J_i) | 帧间隔的波动范围 |
| 帧间隔变异系数 (CV) | σ / μ × 100% | 归一化的抖动程度,<5% 为优秀 |
测量方法:
- 帧间隔直方图:采集连续 300-1000 帧的时间戳,计算相邻帧间隔,绘制分布直方图。
- 时间偏差累积图 (Cumulative Jitter):绘制
ΣJ_i随时间的变化,观察是否存在漂移。 - 频谱分析:对帧间隔序列做 FFT,识别周期性抖动的频率成分(如 60Hz 电源干扰、CPU 调频周期)。
工程经验:预览场景下,帧间隔标准差 σ < 1.5ms 为优秀,σ < 3ms 为可接受。录像场景要求更严格,σ 应 < 1ms,否则视频播放会出现明显的卡顿感。
3.4 三者的关系与权衡
帧率、延迟和抖动并非独立指标,它们之间存在内在耦合:
| 场景 | 帧率要求 | 延迟要求 | 抖动要求 | 典型矛盾 |
|---|---|---|---|---|
| 预览 | 30fps 稳定 | <200ms | σ < 3ms | 高帧率增加 ISP 负载,可能增大抖动 |
| 录像 | 30/60fps 恒定 | <100ms | σ < 1ms | 低抖动要求限制 Buffer 复用策略 |
| 拍照 | 单帧/连拍 | <150ms | 不敏感 | 低延迟可能牺牲 HDR 多帧合成质量 |
| 慢动作 | 120/240fps | <50ms | σ < 0.5ms | 极高帧率下 Sensor 读出时间成为瓶颈 |
优化优先级建议:
① 先保证帧率稳定(不丢帧)→ ② 再降低延迟 → ③ 最后优化抖动。
抖动优化往往需要修改驱动层 Buffer 管理策略或调整 CPU/GPU 调频策略,是性能优化的深水区。
① 先保证帧率稳定(不丢帧)→ ② 再降低延迟 → ③ 最后优化抖动。
抖动优化往往需要修改驱动层 Buffer 管理策略或调整 CPU/GPU 调频策略,是性能优化的深水区。
3.5 测量工具与自动化
推荐使用以下工具进行自动化性能采集:
# 1. 使用 perfetto 采集 Camera 管线时间戳
adb shell perfetto -c /data/local/tmp/camera_perfetto.cfg -o /data/local/tmp/camera_trace.pb
# 2. 使用 Python 脚本解析帧间隔
import numpy as np
timestamps = np.loadtxt('frame_timestamps.txt')
intervals = np.diff(timestamps) * 1000 # 转换为 ms
jitter = intervals - 33.33
print(f"Mean: {np.mean(intervals):.2f}ms, Std: {np.std(intervals):.2f}ms, Pk-Pk: {np.ptp(intervals):.2f}ms")
# 3. 使用 chre 工具实时监控帧率
adb shell chre_test_client --monitor_fps 30
自动化 CI 集成:在每日构建中集成帧率/延迟/抖动测试,设置阈值告警。例如:
- FPS < 28 时触发告警
- 端到端延迟 > 250ms 时触发告警
- 抖动 σ > 3ms 时触发告警
- FPS < 28 时触发告警
- 端到端延迟 > 250ms 时触发告警
- 抖动 σ > 3ms 时触发告警