第24章:CTS/VTS 测试:多媒体测试套件、兼容性测试、常见失败修复
说到 CTS 和 VTS,很多做多媒体开发的兄弟第一反应就是「头疼」。说实话,我也一样。刚入行那会儿,每次跑 CTS 都像在开盲盒——你永远不知道哪个测试用例会挂掉。尤其是多媒体相关的测试,音频、视频、相机、编解码器……随便一个环节出问题,就是几十上百个 failure。
但话说回来,CTS/VTS 其实是 Google 给我们铺的一条「安全绳」。它不是为了折腾你,而是帮你提前发现兼容性问题。你想想看,如果连 CTS 都过不了,那设备上市后用户随便装个 App 就闪退,那才叫灾难。
这一章,我就把多媒体测试套件这块掰开揉碎了讲。包括测试框架怎么搭、常见失败怎么修、以及我这些年踩过的坑。
24.1 多媒体测试套件概览
CTS(Compatibility Test Suite)和 VTS(Vendor Test Suite)是 Android 兼容性认证的两大支柱。CTS 主要测框架层和 HAL 接口,VTS 则更关注 Treble 架构下的 vendor 实现。
多媒体相关的测试,主要集中在以下几个模块:
- MediaPlayer:播放器功能、格式支持、seek、循环等
- MediaRecorder:录制功能、音视频同步、码率控制
- Camera:预览、拍照、录像、HDR、连拍
- Codec:硬件编解码器、AVC/HEVC/VP9 等
- Audio:音频路由、低延迟、回声消除
我个人习惯把多媒体测试套件分成三层来看:
第一层:基础功能测试 —— 保证最核心的播放、录制、拍照能跑通。
第二层:性能与压力测试 —— 长时间运行、多实例并发、资源竞争。
第三层:兼容性边界测试 —— 特殊分辨率、异常码流、低内存场景。
这三层层层递进。基础功能都过不了,就别谈后面的了。
24.2 兼容性测试的核心逻辑
CTS 的测试用例,说白了就是 Google 定义的一套「最低标准」。你达不到,就不能说自己兼容 Android。多媒体这块尤其严格,因为涉及到硬件差异太大了。
我记得有一次,某款芯片的硬件解码器在解码 4K 60fps 的 H.265 码流时,偶尔会丢一帧。CTS 的测试用例正好抓到了这个丢帧,直接判定失败。你说冤不冤?其实用户根本感觉不到。但 Google 的标准就是:你承诺了支持,就必须做到。
常见的多媒体 CTS 测试项包括:
| 测试模块 | 测试项 | 常见失败原因 |
|---|---|---|
| MediaPlayer | android.media.cts.MediaPlayerTest | 解码器不支持、seek 精度不够 |
| MediaRecorder | android.media.cts.MediaRecorderTest | 音视频不同步、码率偏差大 |
| Camera | android.hardware.camera2.cts | HAL 实现不完整、参数校验失败 |
| Codec | android.media.cts.CodecTest | 硬件编解码器不支持某些 profile |
| Audio | android.media.cts.AudioTrackTest | 低延迟路径未实现、采样率不匹配 |
小技巧: 跑 CTS 之前,先看看 test_result.xml 里的 failure 列表。很多失败其实是环境问题,比如存储空间不足、权限没给够。别一上来就改代码。
24.3 常见失败修复实战
好,接下来我们聊点实在的。我这些年修过的 CTS 失败,少说也有上百个。挑几个典型的说说。
24.3.1 解码器不支持特定 Profile
这个太常见了。CTS 会要求设备支持 AVC Baseline、Main、High 三个 profile。但有些芯片只实现了 Baseline,或者 High profile 只支持到 Level 4.0 而不是 4.1。
修复方法:
- 检查
media_codecs.xml中的 profile/level 声明 - 确认硬件解码器实际支持的能力
- 如果硬件不支持,可以考虑用软件解码兜底
<!-- media_codecs.xml 示例 -->
<MediaCodec name="OMX.google.h264.decoder" type="video/avc">
<Limit name="profile" value="baseline|main|high" />
<Limit name="level" value="type" />
<!-- 注意:level 要写对,否则 CTS 会报错 -->
</MediaCodec>
注意: 我曾经遇到过一家厂商,把 media_codecs.xml 里的 profile 写得很全,但实际硬件只支持 Baseline。结果 CTS 一跑就挂。这种「虚假声明」是 Google 重点打击的,千万别干。
24.3.2 音视频不同步
MediaRecorder 的 CTS 测试里,有一个用例会录制一段音视频,然后检查 PTS 的偏差。如果偏差超过 33ms(一帧的时间),就算失败。
我遇到过一个案例:某款芯片的音频编码器启动延迟特别大,导致前几百毫秒的音频 PTS 都偏大。修复方案是在音频编码器初始化时,预填充一段静音数据,让 PTS 对齐。
// 伪代码:预填充静音帧
AudioRecord record = new AudioRecord(...);
record.startRecording();
// 先读 200ms 的静音数据,丢弃
byte[] dummy = new byte[16000];
record.read(dummy, 0, dummy.length);
// 然后再开始真正的录制
// 这样 PTS 就能对齐了
24.3.3 Camera HAL 参数校验失败
Camera2 CTS 测试里,有一个用例会遍历所有支持的 StreamConfigurationMap,检查每个输出尺寸是否合法。如果 HAL 返回了一个不支持的尺寸组合,直接挂。
修复方法:
- 检查 HAL 的
getSupportedOutputSizes()实现 - 确保每个尺寸都能正常打开流
- 有些厂商会「虚报」尺寸,比如声称支持 4K,但实际预览会卡顿
我的经验: 修 Camera CTS 失败,最有效的方法是「最小化声明」。只声明你真正测试过的尺寸和格式。少声明几个尺寸不会影响认证,但声明了却跑不过,那才是大问题。
24.4 VTS 多媒体测试要点
VTS 是 Android 8.0 引入的,专门针对 Treble 架构下的 vendor 实现。多媒体相关的 VTS 测试,主要集中在 android.hardware.media.omx 和 android.hardware.camera.provider 这两个模块。
VTS 的测试逻辑和 CTS 不太一样。CTS 是从 App 层往下测,VTS 是从 HAL 层往上测。说白了,VTS 更关注接口的完整性和稳定性。
常见的 VTS 失败:
- OMX 组件未注册:
treble_test会检查所有 OMX 组件是否在 manifest 中声明 - HIDL 接口版本不匹配:vendor 实现的接口版本必须和 framework 要求的版本一致
- 内存泄漏:VTS 会反复创建销毁组件,检查是否有内存泄漏
// VTS 测试示例:检查 OMX 组件
// 运行命令:
adb shell vts-tradefed run vts -m VtsHalMediaOmxV1_0TargetTest
// 如果失败,检查 manifest.xml
<hal format="hidl">
<name>android.hardware.media.omx</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>IOmx</name>
<instance>default</instance>
</interface>
</hal>
避坑指南: 我曾经在 VTS 上栽过一个跟头。某个 OMX 组件在 CTS 里跑得好好的,但 VTS 就是报「接口未实现」。查了两天才发现,是 manifest.xml 里少写了一个 <instance> 标签。这种低级错误,真的让人哭笑不得。
24.5 自动化测试与持续集成
手动跑 CTS/VTS 太累了。我建议你把测试集成到 CI 流水线里。每次提交代码后自动触发测试,失败了就发邮件通知。
常用的做法:
- 使用
tradefed命令行工具批量跑测试 - 解析
test_result.xml提取失败用例 - 将失败用例自动归类(环境问题 / 代码问题 / 硬件问题)
# 自动化脚本示例
#!/bin/bash
# 跑 CTS 多媒体测试
cts-tradefed run cts -m CtsMediaTestCases --abi arm64-v8a
# 检查结果
if grep -q "FAIL" test_result.xml; then
echo "CTS 测试失败,请检查日志"
# 发送邮件通知
fi
嗯,自动化这块其实还有很多可以聊的,比如怎么并行跑测试、怎么管理测试设备池。但篇幅有限,咱们先到这。
最后说一句:CTS/VTS 不是敌人,它是你的朋友。每次失败都是一次学习机会。修得多了,你对 Android 多媒体框架的理解就会越来越深。
公众号:蓝海资料掘金营,微信deep3321