4. 长时间运行测试:Camera Open/Close循环、Preview持续与录像拍照交替
长时间运行测试是验证 Camera HAL 稳定性的核心手段,旨在暴露资源泄漏、内存碎片、死锁、电源管理异常以及驱动老化等间歇性故障。本章围绕三类典型长时间测试场景展开:Open/Close 循环、Preview 持续与录像拍照交替,分别对应 HAL 层资源管理、流处理持久性以及多模式切换的稳定性。
4.1 测试场景与关键指标
下表汇总了三种长时间测试的典型配置、监控指标与通过标准:
| 测试场景 | 持续时间 / 循环次数 | 核心监控指标 | 通过标准 |
|---|---|---|---|
| Open/Close 循环 | 10000 次 | 内存泄漏、文件描述符泄漏、Camera 服务重启次数 | 0 次服务重启,内存增量 < 5% |
| Preview 持续 | 24 小时 | 帧率稳定性、CPU 占用率、温度、ANR 次数 | 帧率波动 < 10%,无 ANR |
| 录像与拍照交替 | 8 小时 | 录像文件完整性、拍照成功率、音视频同步偏移 | 拍照成功率 100%,音视频偏移 < 33ms |
测试环境要求:所有长时间测试必须在恒温环境下进行(25°C ± 2°C),并保持设备充电状态。建议使用自动化测试框架(如 Google 的 Camera ITS 或自研脚本)驱动,避免人工操作引入的时序偏差。
4.2 Open/Close 循环测试(10000次)
该测试模拟应用频繁打开和关闭 Camera 设备,验证 HAL 层在资源分配与释放过程中的健壮性。常见故障包括:CameraService 崩溃、驱动句柄泄漏以及内存碎片化。
4.2.1 测试流程与关键检查点
- 初始化状态记录:测试前记录 /proc/meminfo、lsof 输出、dmesg 日志。
- 循环执行 Open/Close:每次 Open 后等待 500ms,Close 后等待 200ms,避免背靠背操作。
- 周期性检查:每 1000 次循环检查一次内存增量与文件描述符数量。
- 异常处理:若 Open 返回错误或 CameraService 重启,立即记录上下文并继续测试。
- 后处理分析:对比测试前后的资源快照,计算泄漏量。
常见泄漏模式:HAL 层在 close() 中未释放 gralloc buffer、未关闭 sensor 驱动节点、未销毁 pipeline 线程。建议在 close() 函数末尾添加
LOG_ASSERT 检查内部引用计数是否归零。
4.2.2 资源泄漏检测脚本示例
#!/system/bin/sh
# 资源监控脚本片段,用于 Open/Close 循环测试
LOG_FILE="/data/camera_leak_test.log"
PID=$(pidof cameraserver)
echo "=== Test Start ===" > $LOG_FILE
cat /proc/$PID/status | grep VmRSS >> $LOG_FILE
lsof -p $PID | wc -l >> $LOG_FILE
for i in $(seq 1 10000); do
# 执行 Open/Close 操作(由测试框架触发)
sleep 0.5
# 每 1000 次采样一次
if [ $((i % 1000)) -eq 0 ]; then
echo "Loop $i:" >> $LOG_FILE
cat /proc/$PID/status | grep VmRSS >> $LOG_FILE
lsof -p $PID | wc -l >> $LOG_FILE
dmesg -c | grep -i "camera\|ion\|dma" >> $LOG_FILE
fi
done
echo "=== Test End ===" >> $LOG_FILE
4.2.3 Open/Close 循环故障树
下图展示了 Open/Close 循环测试中可能出现的故障路径与根因分析方向:
4.3 Preview 持续测试(24小时)
Preview 持续测试验证 Camera HAL 在长时间视频流处理中的稳定性。核心风险包括:帧率下降、CPU 过载、热降频导致画面卡顿以及ISP 管线溢出。
4.3.1 测试配置与监控方案
- 分辨率与帧率:使用设备支持的最大分辨率(如 1920x1080 @ 30fps)。
- 帧率监控:通过
adb shell dumpsys media.camera或 HAL 层注入的帧时间戳日志,每 5 分钟统计一次平均帧率。 - 温度监控:读取
/sys/class/thermal/thermal_zone*/temp,记录 SoC 与电池温度。 - ANR 检测:监听
data/anr/目录下是否有新生成的 traces 文件。
注意:Preview 持续测试中,如果帧率在 2 小时内持续下降超过 15%,应立即停止测试并检查 ISP 驱动是否有丢帧或 buffer 堆积现象。常见原因为 HAL 层未及时归还 buffer 给驱动。
4.3.2 Preview 持续测试状态机
下图描述了 Preview 持续测试中 HAL 层的状态流转与关键监控点:
4.4 录像与拍照交替测试(8小时)
该测试模拟用户在实际使用中频繁切换录像与拍照模式,验证 HAL 层在流配置切换、buffer 重分配以及音视频同步方面的稳定性。典型故障包括:拍照黑帧、录像文件损坏以及音视频不同步。
4.4.1 交替测试策略
| 阶段 | 操作 | 持续时间 | 验证点 |
|---|---|---|---|
| 1 | 启动录像(1080p@30fps) | 5 分钟 | 录像文件正常写入,音视频 pts 连续 |
| 2 | 停止录像,立即拍照(连拍 5 张) | 10 秒 | 每张照片 exif 信息完整,无黑帧 |
| 3 | 切换回录像(4K@30fps) | 5 分钟 | 分辨率切换后帧率稳定 |
| 4 | 重复步骤 1-3,共 8 小时 | — | 无 crash,无 ANR,无文件损坏 |
4.4.2 音视频同步偏移检测
在录像过程中,HAL 层需要为每个视频帧和音频帧打上精确的时间戳。检测偏移的方法如下:
# 使用 ffprobe 分析录像文件中的音视频时间戳
ffprobe -v quiet -show_entries frame=pts_time,media_type \
-of csv=p=0 recording.mp4 | awk -F',' '
{
if ($2 == "video") v_pts = $1;
if ($2 == "audio") a_pts = $1;
}
END {
diff = (v_pts - a_pts) * 1000; # 转换为毫秒
if (diff < -33 || diff > 33)
printf "WARNING: AV sync offset = %.2f ms\n", diff;
else
printf "OK: AV sync offset = %.2f ms\n", diff;
}'
偏移根因分析:如果偏移量持续增大,通常是因为 HAL 层在录像/拍照切换时未正确重置音频时间戳基准,或者视频帧在 ISP 管线中排队时间过长。建议在
configure_streams() 中检查 timestamp base 是否被正确更新。
4.4.3 录像拍照交替流程图
下图展示了 8 小时交替测试中 HAL 层的核心操作序列与故障注入点:
4.5 故障排查实战要点
在长时间运行测试中,故障排查应遵循以下优先级顺序:
- 检查 dmesg 与 logcat:搜索 "camera"、"HAL"、"buffer"、"timeout" 等关键词,定位首次异常发生的时间点。
- 分析内存快照:使用
dumpsys meminfo或procrank对比测试前后的内存占用,重点关注 native heap 与 GPU buffer 的增长。 - 复现最小化场景:将 10000 次循环缩减为 100 次,并增加每次操作的延迟,观察是否仍然触发故障。
- 检查驱动层状态:通过
cat /d/ion/heaps或cat /proc/mtk_camera(MTK 平台)查看驱动 buffer 分配情况。 - 验证 HAL 层资源释放:在 close() 函数中添加日志,打印每个子模块的引用计数,确认是否归零。
经验法则:如果 Open/Close 循环在 3000 次左右开始出现内存增长,通常指向某个 buffer 在 close() 中未被释放;如果在 8000 次左右出现,则更可能是内存碎片化问题。根据出现时机可以快速缩小排查范围。