【安卓】安卓xTS之Media模块 学习笔记(3) VTS测试

1. 背景

接下来进行正式的VTS测试。本章节还是以Media模块相关进行介绍。

VTS主要测的是内核和HAL层,media的hal层是以openMax(即将废弃,今日2023.12) 和 Codec2 (后续主流) 接口为主。

这里我们只看Codec2的要求,CDD里也只要求了这个。

2. 参考文档

3. 测试步骤

3.1 VTS测试包获取

3.1.1 自行编译

谷歌官网没有提供测试包,需要自行编译

复制代码
. build/envsetup.sh
lunch aosp_arm64-userdebug
make vts -j32

生成的文件在: \out\host\linux-x86\vts

把zip包拷贝到 X86宿主机上,解压即可使用。

(如果是windows主机的话,要改下 vts-tradefed 里的环境识别,具体改法参照第2章节)

3.2 VTS测试包文件结构

  • 初次解压的android-vts.zip包中只有testcases 和 tools 两个文件夹,其他文件夹都是后续运行生成的

  • 解压后的android-vts文件夹名称不能修改,但可以放在别的文件夹路径下运行。

    android-vts
    | ---- jdk : 包含一些运行所需要的软件
    | ---- logs :每次测试抓取的日志文件
    | ---- latest : 一个快捷方式,指向最新结果
    | ---- 2023.11.17_22.46.43
    | ---- 2023.11.17_22.10.44
    | ---- ......
    | ---- results : 每次测试生成的结果报告,有时间戳可以分辨
    | ---- latest : 一个快捷方式,指向最新结果
    | ---- 2023.11.17_22.46.43
    | ---- 2023.11.17_22.10.44
    | ---- ......
    | ---- subplans:生成的测试计划
    | ---- testcases:测试用例,每个文件夹对应VTS里的一个module
    | ---- [email protected]
    | ---- arm
    | ---- arm64
    | ---- ApkVerityTest
    | ---- ......
    | ---- VtsHalMediaC2V1_0TargetVideoDecTest
    | ---- VtsHalMediaC2V1_0TargetVideoDecTest.config:功能模块的配置文件
    | ---- arm
    | ---- arm64 : 64位系统的测试进程
    | ---- VtsHalMediaC2V1_0TargetVideoEncTest
    | ---- tools:测试工具,一些jar,以及VTS的测试入口
    | ---- vts-tradefed : 测试入口
    | ---- ......

3.3 测试命令

优先敲 vts-tradefed 进入concoles之后,再执行命令

复制代码
cd tools
./vts-tradefed
XXXXX

如果这样运行有异常(windows HOST 有时候运行有问题),也可以直接1条命令运行,

复制代码
cd tools
./vts-tradefed run commandAndExit vts --abi arm64-v8a --module VtsHalMediaC2V1_0TargetVideoDecTest --disable-reboot --skip-device-info --skip-all-system-status-check --skip-preconditions

3.3.1 常见命令

  • 直接运行, 跑 VtsHalMediaC2V1_0TargetVideoDecTest 模块

    ./vts-tradefed run commandAndExit vts --abi arm64-v8a --module VtsHalMediaC2V1_0TargetVideoDecTest --disable-reboot

  • 建立测试subplan

    ./vts-tradefed l r 查看刚才测试结果的session号,注意是小写字母L不是数字1, l r 意思是 list results
    ./vts-tradefed add subplan --session 158 --name VtsHalMediaC2V1_0TargetVideoDecTest_20230915-10 --result-type not_executed
    ./vts-tradefed run commandAndExit vts --abi arm64-v8a --module VtsHalMediaC2V1_0TargetVideoDecTest --disable-reboot -o --subplan VtsHalMediaC2V1_0TargetVideoDecTest_20230915-10

3.3.2 一些常见的option:

  • --abi arm64-v8a :只测试arm64 的case, FPGA android 固件只支持64位。 如果在参考平台(Inception 平板)
  • --disable-reboot:防止Android系统重启.FPGA 版本Android 不支持reboot 功能,需要在运行XTS 测试时
  • --skip-device-info --skip-all-system-status-check --skip-preconditions :跳过检测 ,FPGA 版本Android 系统检测较慢
    如果运行完整的vts测试,需要加上以下参数 跳过fastboot 测试 **--exclude-filter FastbootGetvarUserspaceTest --exclude-filter FastbootVerifyUserspaceTest

4. 测试结果说明

4.1 结果result

测试结果位于\android-vts\results\对应时间戳子文件夹下。

打开 test_result.html 文件。


整个测试结果显示我分为4个区。

区域1, Summary,整体记录这次测试的一些信息

区域2,测试结果,记录一共跑了哪些模块,通过多少,失败多少,Assumption Failure多少,忽略多少,是否完成了整个测试。

这里介绍下 Assumption Failure, 和 Done。

Assumption Failure 是指这个case,VTS判断就是应该失败的,比如设备不是TV类的,没有TV相关的系统进程,但是VTS跑了TV类的模块测试,这些就都是 Assumption Failure。所以这类case不计入失败率的。

Done 标志 这个模块的测试有没有完成(可能中间检测到一些系统级别的异常,比如设备断开,响应超时等等,导致这个模块里的case没有测试完)。

区域3,失败case,这里会单独把所有的失败用例列出来,并抓取失败时的报错信息进行显示(比区域4的details更详细一点)

区域4,所有case,模块里的所有case测试结果都在这里有显示,包含所有的成功和失败。

4.2 日志log

测试日志位于android-vts\log\对应时间戳子文件夹下。

5. 测试用例说明

5.1 VTS 用例介绍

VTS的case用例类型分为好几种

  • Gtest:绝大多数都是Gtest,C++编写,也是谷歌强烈建议的方式
  • Linux内核测试
  • Junit
  • python3
    具体的区别可以参见谷歌文档

5.2 VTS media 相关模块

media 中 VTS 相关的模块有

VtsHalMediaC2V1_0TargetComponentTest

VtsHalMediaC2V1_0TargetMasterTest

VtsHalMediaC2V1_0TargetVideoDecTest

VtsHalMediaC2V1_0TargetVideoEncTest

VtsHalMediaOmxV1_0TargetComponentTest

VtsHalMediaOmxV1_0TargetStoreTest

VtsHalMediaOmxV1_0TargetVideoDecTest

VtsHalMediaOmxV1_0TargetVideoEncTest

vts_mediaCodecs_validate_test

vts_mediaProfiles_validate_test

看名字能看出来,前面4个都是codec2接口的测试,后面4个是OpenMax接口的测试。

这里我们主要关注codec2接口相关的验证。

5.3 VTS测试流程

先看一下 tools文件夹下的 vts-tradefed,这是整个测试的入口。

VTS也是基于谷歌的 Trade Federation 测试框架进行的。

vts-tradefed文件比较简单,自己丢到文心一言里按行分析一下,就可以得到具体的结果。

前面就是check一些环境变量和行为之类的,没什么好说的。

重点关注最下面的2句话

复制代码
VTS_TESTCASES=${VTS_ROOT}/android-vts/testcases/
VTS_TESTCASES=${VTS_TESTCASES} ${JAVA_BINARY} $RDBG_FLAG -Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -cp ${JAR_PATH} -DVTS_ROOT=${VTS_ROOT} com.android.compatibility.common.tradefed.command.CompatibilityConsole "$@"

就是使用java虚拟机启动 com.android.compatibility.common.tradefed.command.CompatibilityConsole, 把所有入参都传过去。($@)

com.android.compatibility.common.tradefed.command.CompatibilityConsole 进程通常在运行 CTS 测试时启动。它提供了一个控制台界面,用于显示测试结果、日志和其他相关信息。开发者可以使用这个界面来监视和调试 CTS 测试的执行过程,以确保他们的应用程序在各种 Android 设备上都能够正常运行。这个进程通常只在运行 CTS 测试时出现,并且只会在特定情况下启动。在常规使用 Android 设备时,这个进程通常不会运行。

以 VtsHalMediaC2V1_0TargetVideoDecTest 测试为例,

使用的测试资源是 \android-vts\testcases\VtsHalMediaC2V1_0TargetVideoDecTest\

可以看到有2个文件夹,arm 和 arm64 ,分别针对32位和64位系统。

VtsHalMediaC2V1_0TargetVideoDecTest.config 是测试使用的资源,包括媒体资源(码流文件,视频文件),测试进程 vts_media_c2_v1_0_video_dec_test。

可以看出,文件除了 视频文件(.vp9/.vp8/.m2v......)之外,还有 .info 和 .md5 两类。

看了下,info里应该放的是每一帧的时间戳,.md5放的是文件的校验码

代码看一下。

每个case里依赖的文件对应关系。

然后在getFileNames中,根据index可以对应拿到每个case的 inputFile(输入文件),infoFile(时间戳文件),CheckSumFile(校验文件)

然后mChksumFile在DecodeTest中会用到。
if (!mChksumFile.compare(sResourceDir)) mMd5Enable = false; 说明这个case在gCompToFiles数组中没有对应的md5文件,因此不进行Md5检测。

把md5这个文件按二进制读取到mRefMd5这块内存中

然后在这里
void compareMd5Chksm(std::unique_ptr<C2Work>& work)中,分YUV平面去计算独立的md5,然后进行memcpy

原理是啥??

为什么解码结果可以按bit来compare,不同的解码器,参数会不会不一样?

VtsHalMediaC2V1_0TargetVideoDecTest.config 记录的是 需要push的文件,push的位置,测试的用例option。

测试进程会解析这个config文件,进行case配置。

基本可以看出流程是:

先cleanup测试环境,

然后adb push 测试用例 vts_media_c2_v1_0_video_dec_test 到 /data/local/tmp/vts_media_c2_v1_0_video_dec_test

然后把一堆依赖的资源文件 push进去 /data/local/tmp/media/

最后运行
vts_media_c2_v1_0_video_dec_test -P /data/local/tmp/media/

那究竟 VtsHalMediaC2V1_0TargetVideoDecTest 这个进程做了什么呢,

这就需要去framework代码里看一下了。

VtsHalMediaC2V1_0TargetVideoDecTest 位于 frameworks/av/media/codec2/hal/hidl/1.0/vts/functional/video/

打开 frameworks/av/media/codec2/hal/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp 文件,
在线代码链接

可以发现有很多 TEST_P 开头的函数,这都是GTEST框架,

比如

复制代码
TEST_P(Codec2VideoDecHidlTest, validateCompName)
TEST_P(Codec2VideoDecHidlTest, configureTunnel)
TEST_P(Codec2VideoDecDecodeTest, DecodeTest)
TEST_P(Codec2VideoDecHidlTest, AdaptiveDecodeTest)
TEST_P(Codec2VideoDecHidlTest, ThumbnailTest)
TEST_P(Codec2VideoDecHidlTest, EOSTest) 
TEST_P(Codec2VideoDecHidlTest, FlushTest)
TEST_P(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted)
TEST_P(Codec2VideoDecCsdInputTests, CSDFlushTest)

这些对应的就是 测试结果中的一个个部分,

截了个图,能看到,

TEST_P(Codec2VideoDecHidlTest, validateCompName) 对应就有很多 PerInstance/Codec2VideoDecHidlTest#validateCompName/software_c2_XXXX 的 测试用例,

整体来说,

每个TEST_P的入口上都有很多测试。

测试会去遍历所有的解码用的C2 component进行测试。

5.4 VtsHalMediaC2V1_0TargetVideoDecTest

主要模块

Media的codec2在vts这边主要就是Dec和Enc两个模块,其中,

VtsHalMediaC2V1_0TargetVideoDecTest 主要包含了以下几个模块:

  • PerInstance/Codec2VideoDecHidlTest#validateCompName:验证注册的有效解码器名字是否合规(包含软解和硬解)
  • PerInstance/Codec2VideoDecHidlTest#configureTunnel:验证Tunnel配置是否正常,验证bufferQ相关。确保数据能正确传输,对应代码
  • PerInstance/Codec2VideoDecHidlTest.AdaptiveDecodeTest: 自适应测试,不同比特率不同分辨率不同帧率,对应代码
  • PerInstance/Codec2VideoDecHidlTest.ThumbnailTest:多个流发送,对应代码
  • PerInstance/Codec2VideoDecHidlTest.EOSTest:直接发EOS来测试?
  • PerInstance/Codec2VideoDecHidlTest.FlushTest
  • PerInstance/Codec2VideoDecHidlTest.DecodeTestEmptyBuffersInserted: 插入空的一帧,测丢帧等等
  • StreamIndexAndEOS/Codec2VideoDecDecodeTest.DecodeTest:解码测试
  • CsdInputs/Codec2VideoDecCsdInputTests.CSDFlushTest:EOS01,结束符 SPS PPS

我们也可以通过 gtest_list_tests 查支持的测试用例
./vts_media_c2_v1_0_video_dec_test --gtest_list_tests

依赖的资源

不需要单独提供资源包,VTS这两个模块需要的资源包都在VTS的包里了,会自动push到/data/local/tmp下去运行。

5.5 VtsHalMediaC2V1_0TargetVideoEncTest

主要模块

  • PerInstance/Codec2VideoEncHidlTest/validateCompName
  • PerInstance/Codec2VideoEncHidlTest/EOSTest
  • PerInstance/Codec2VideoEncHidlTest/FlushTest
  • InvalidBufferTest
  • AdaptiveBitrateTest
  • EncodeTestwithEOS/Codec2VideoEncEncodeTest/EncodeTest
  • NonStdSizes/Codec2VideoEncResolutionTest/ResolutionTest

Case命名原则

看result的时候,发现大量的case命名为 XXXXX_数字A_数字B_数字C_数字D 的格式

比如

那这些数字是代表什么意思的呢?

VtsHalMediaC2V1_0TargetVideoEncTest.cpp的main。

从0(000)~7(111)进行循环,生成 000, 001,010,011,100,101,110,111 共8种参数配置,连上原有的参数0和参数1,凑成5个参数进行测试。

后面在resolution测试中插入了一些固定的参数测试,

对应结果中的这些测试用例

在模块中每个组件测试中,

会拿到这些参数,进行单独测试使用。

比如EncodeTest,参数2就是代表发不发EOS,参数3代表第一帧是不是空帧,参数4代表有没有B帧等等。

5.6 单用例调试方法

在vts出问题进行程序调试的时候,我们需要运行指定用例。

  • TF测试套件

    如果使用tf测试套件,

  • 手动执行单个case

    从调试方便的角度,还是直接运行GTEST用例更方便。

    如果使用手动运行Gtest,可以使用GTEST支持的filter来指定,如我想跑:

    可以运行
    ./vts_media_c2_v1_0_video_dec_test --gtest_filter=*.validateCompName/default_c2_mtk_av1_decoder_0

    注意的是,如果缺少一些库,

    需要自己export路径,比如
    export LD_LIBRARY_PATH=/apex/com.android.art/lib64/:/vendor/lib64:/system/lib64;等等

5.7 一些常见报错

环境问题

  • Wrong java version.

A:TF框架依赖的安卓版本不对。按照使用的CTS测试包中建议,重新安装对应的JDK模拟器版本即可。我这边,安卓13用的11,安卓14用的17。

  • 外部存储无法mounted

    查看/sdcard路径挂载了没有

  • 运行vts-tradefed 无法进入

有时候windows上运行有问题,可以直接跑命令

复制代码
./vts-tradefed run commandAndExit vts --abi arm64-v8a --module VtsHalGraphicsMapperV4_0TargetTest --disable-reboot --skip-device-info --skip-all-system-status-check --skip-preconditions

运行问题

  • vts程序挂死、卡住,无法打印帮助信息等?

    A:基本上都是因为没有启动c2服务器进程,手动启动c2服务进程后,vts进程可以恢复正常;

  • went over its timeout for outputing a response

怀疑是这里的超时参数设置的太小,因为FPGA上case运行的非常慢,导致获取结果超时。

在线代码:NativeDeviceStateMonitor | Android Open Source Project

相关推荐
AgilityBaby7 分钟前
UE5 2D角色PaperZD插件动画状态机学习笔记
笔记·学习·ue5
AgilityBaby8 分钟前
UE5 创建2D角色帧动画学习笔记
笔记·学习·ue5
xzkyd outpaper32 分钟前
Android动态广播注册收发原理
android·计算机八股
唐墨12337 分钟前
android与Qt类比
android·开发语言·qt
林林要一直努力1 小时前
Android Studio 向模拟器手机添加照片、视频、音乐
android·智能手机·android studio
AD钙奶-lalala1 小时前
Mac版本Android Studio配置LeetCode插件
android·ide·android studio
武昌库里写JAVA2 小时前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
一弓虽2 小时前
git 学习
git·学习
散人10243 小时前
Android Test3 获取的ANDROID_ID值不同
android·unit testing
雨白3 小时前
实现动态加载布局
android