Android 计算视频的fps

监控 游戏 fps 调研

adb shell dumpsys gfxinfo

这种方式反回的数据太大,还监控不到游戏的pfs.,是必须是 Android M 版本以上才支持,而且需要拖动屏幕产生的数据才比较准确

dumpsys是一款运行在设备上的Android工具,将 gfxinfo命令传递给dumpsys可在logcat中提供输出,其中包含各阶段发生的动画以及帧相关的性能信息。但是gfxinfo不统计SurfaceView。


dumpsys SurfaceFlinger --latency【这个只支持安卓6以下】(https://wizzie.top/Blog/2020/03/31/2020/200330_android_getFPS/)
命令主要用于获取游戏/视频应用的fps数据。
返回的是安卓当前activity的fps,清楚数据之后,不滑动屏幕是没有数据的,
计算方式   https://www.jianshu.com/p/280ec5c566ea
计算方法比较简单,一般打印出来的数据是129行(部分机型打印两次257行,但是第一部分是无效数据,取后半部分),取len-2的第一列数据为end_time,取len-128的第一列数据为start_time
fps = 127/((end_time - start_time) / 1000000.0)
自己在手机上测试之后发现数据有点出入,每次第一列和第三列数据都是一样得,没法计算
还有一个问题就是怎么把执行完adb 得数据拿出来,只取用到得数据,怎么计算
怎么实时显示数据,计算,延迟怎么处理,

在Android 6系统直接就是SurfaceView
在Android 7系统中可以通过 dumpsys window windows | grep mSurface | grep SurfaceView 然后通过数据截取到
在Android 8系统中可以通过 dumpsys SurfaceFlinger | grep android包名获取到
在这个命令下,执行完得数据不对,没有提示所需要得数据, 正常数据应该是128行数据

版本不同执行得命令也不同,grep 是Linux grep 命令(这个有点不懂)


目前只能使用这个办法,但是获取得数据只有一行,使用java实现得没有,大部分都是C++ ,python

fpsviewer—实时显示fps    https://www.jianshu.com/p/ba1cd424901d     计算出来好像不对,正常设置30帧得话,他一秒就是渲染30帧,但是现在算出来还是60,有点问题(是根据屏幕得刷)
fpsviewer 特点无损FPS实时显示,一段时间的平均帧率和帧率占比
利用Choreographer.FrameCallback的fun doFrame(frameTimeNanos: Long)方法回调里获取数据计算每帧消耗的时长,实时性高且不需要额外的数据获取无其他性能消耗,开启和关闭fpsviewer对帧率的影响远小于1帧。支持一段时间的平均帧率和帧率占比显示,可用于性能优化前后的对比。


使用腾讯的wetest助手
腾讯云测平台提供的客户端FPS方法较上面两种简单,可以直接生成测试报告,缺点是必须要在手机上安装wetest助手的客户端并且手机要root后才能获取到。

FrameLayout
前面几种方式都不合适,需要在调研其他的方法,

大部分方法都是测试app性能得测试,在抓取视频得fps得暂时没有合适得


其他得方式就是通过脚本来抓取数据分析

perfdog   获取fps是通过   adb shell dumpsys SurfaceFlinger --latency 图层名  得到数据里面得第一列  【desiredPresentTime:应用期望提交的时间】 来计算得

 处理128行数据   这个用到得主要是第二列数据

目前找到一种合适得方法,需要先执行adb shell 进入到shell  里面
以综合测试apk为例,执行   dumpsys SurfaceFlinger | grep 包名+activity  得到 SurfaceView命令

在执行   dumpsys SurfaceFlinger --latency "SurfaceView[包名+activity](BLAST)#0"
得到所有得数据128行  其中第一行为  刷新周期   剩下得127行为帧数据

用T2中的数据 每次都是下一行减去上一行得值,最后总和。  转换成秒  用127/转换出来的数据  = fps

多次计算之后,这个公式是可以计算出帧数的,因为计算器算的是整数,精度可能差一点
把小数保留两位之后,得到的数据跟系统,so返回的数据,在截图看来大致是一样的

先把数据保存到本地文件里(因为adb现在执行不了,只能先用死数据),在用的时候取出来,再取的时候,只取中间一列的数据。在遍历计算的时候要考虑他的无效数据,和最后一行不计算的问题,有几行无效数据,在那个坐标下面,把算到的值都加一起除以1000000000,保留两位小数,拿有效数据的总个数除以刚计算出的数据,就是fps.
在计算fps的时候,因为现在会有一个无效数据,需要处理,在循环遍历的时候需要判断是否有无效数据
目前测试的时候,发现每次无效数据只会有一个,在最后一行,不排除有其他的,可能算法还需要在完善


现在又发现一个问题,在小米8se手机上,上面这套adb执行完的结果是跟小米10手机上不一样的,他只有一行,如果按照第一个命令行执行完的结果来执行最后一个adb的时候,他只有127行数据,第一列跟第三列 都为零,在红米K40手机上,执行完最后一个adb 他出来的结果有129行,第一行为刷新率,第二行 是执行的命令,后面127才是帧数据   在vivo手机上出现的是,在刚进入游戏的时候。抓取的是数据是128行数据,但是他前边有好多条数据都是零,在启动游戏过一会后,才能都抓到数据,在其前面刚开始的时候计算会有问题。
在vivo手机上确认是数据再有0  0  0 的时候,数据都是一样的,都当无效数据处理,但是在计算的时候他不需要跟其他手机一样,使用有效数据的行数/计算得出的数据 ,这样得出的结果不对,还需在找其他计算方式 。和其他手机发生冲突,需要解决

jank  计算   
t3-t1>16.7ms,则认为发生一次卡顿

FrameTime  两帧画面间隔耗时

1秒内的卡顿次数
 
PerfDog Jank计算方法:
 
同时满足两条件,则认为是一次卡顿Jank.
 
    ①Display FrameTime>前三帧平均耗时2倍。
    
    ②Display FrameTime>两帧电影帧耗时 (1000ms/24*2=84ms)。
    
 
同时满足两条件,则认为是一次严重卡顿BigJank.
 
    ①Display FrameTime >前三帧平均耗时2倍。
    
    ②Display FrameTime >三帧电影帧耗时(1000ms/24*3=125ms)。

因为这个我是使用的终端进行操作的,每次复制出来在进行计算的,可能需要用python来计算

猜你喜欢

转载自blog.csdn.net/weixin_50330149/article/details/126977477
FPS