高频卡顿问题分析

news2025/1/10 16:41:38

从监控图中可以看到,3.76k的用户,两分钟内报卡顿次数达到100万次 ,很恐怖,这个是非正常的卡顿

由于没有日志,只能先看代码分析,出现高频卡顿的原因

问题描述

在播放过程,会频繁上报卡顿,2分钟能报几百次,从报卡顿开始到卡顿结束最短时间接近0ms

做的相关实验

模拟测试

1.只有视频、没有音频,不会快进,能正常播放,只是没有声音
2.音频数据播放完之后,再播放一段视频数据,再来音频数据,不会有快进,只是音画不同步,能持续播放音频和视频,会出现一次卡顿
3.在一段音视频数据中,丢弃一段音频数据,会快进丢弃一段视频,音画同步之后正常播放 

--------------------------------------------------------------------------------------------------------------------------

1.丢少量音频帧(未出现音频缓存为空):无卡顿,视频有快进,音画同步后音频和视频均正常
2.丢很多音频帧(出现音频缓存为空):有卡顿(送音频之后卡顿消失),且视频无快进,后续音画一直不同步的持续播放

--------------------------------------------------------------------------------------------------------------------------

1.灌入正常音视频数据至队列的1/2,正常播放
2.快速灌入只有视频的数据,至队列满
3.按正常播放速度灌入正常的音、视频数据
这个现象是:
播放过程没有一次buffer,不过这个过程会有画面快进的现象,整个过程声音保持有,另外从日志看到,播放到一定时间后,音视频数据会同步,播放回归正常

--------------------------------------------------------------------------------------------------------------------------

在视频解码的地方延时50ms

SDL_AMediaCodecJava_dequeueOutputBuffer

 就会出现高频卡顿

数据分析

最近30天的数据分析

出现概率比较高的6个频道如下:

出现概率比较高的用户如下:

Buffer次数

设备数

备注

大于100k

3

最大次数198860

50K~100K之间

9

30K~50K之间

26

20K~30K之间

41

10

代码分析

从播放到buffer

场景

备注

是否可能

开始播放时候,先buffer

播放过程只会出现一次

可能

package拿不到音频的data的时候

本地实验切换声道即可复现

可能

seek的时候

用户拖动进度条,会清除缓冲队列数据

不可能

ffp_toggle_buffering(ffp, 0)buffer状态切换到播放状态

从buffer到播放

场景

备注

是否可能

缓冲满(音频加视频)

本地实验切换声道即可复现

可能

播放结束,从新播放

播放过程只会出现一次

不可能

音频和视频缓冲区两个都达到播放大小

这个是500ms去判断一次

不可能

原因

从代码上分析上看,只有一种情况会导致频繁buffer,即:

解复用视频流的线程,缓冲区里读音频数据,当读不到音频package的时候,就会报buffer;而read线程判断到播放器缓冲区满15m的时候,就会把播放器状态从buffer状态改到播放状态。如此循环,就会导致频繁buffer

解决方案

如果出现频繁buffer原因是由于播放器缓冲达到最大限制,而音频的packat却为0导致的,这个时候播放已经音频不同步,可以通过清除播放器缓冲来解决。当前MFC点播用户也有反馈,播放过程会出现没有声音的情况。

后续

是什么样的情况会导致播放器缓冲已经满,但是音频的packat却为0呢?可能原因

  1. 视频流或者传输过程出现问题
  2. 系统已经出现问题,导致音视频同步出现问题。猜测依据是MFC点播系统,有相当一部分客户反馈播放过程会出现没声音的场景

BUFFER TIMEOUT: remove(4099) from active list on thread 0xa6e03440

D/AudioHardwareTiny: close device但是这个只会出现一次

低内存实验

出现视频队列里的帧数为0,音频满。。。

正常启动播放器

只会出现一次

来回切换HOME键

当低内存的时候,new_packet == 0时竟然会有q->is_buffer_indicator = 0的情况,导致new_packet == 0不报卡顿

为什么q->is_buffer_indicator = 0呢?

   if (is->audio_stream >= 0) {
        is->audioq.is_buffer_indicator = 1;//音频流队列有效
        is->buffer_indicator_queue = &is->audioq;
    } else if (is->video_stream >= 0) {
        is->videoq.is_buffer_indicator = 1;//视频流队列有效
        is->buffer_indicator_queue = &is->videoq;
    } else {
        assert("invalid streams");
    }

原来是以audio为先,所以音频的 is_buffer_indicator为1,视频的is_buffer_indicator为0,所以产生频繁卡顿的条件只有一个,就是audio为0

vd代表video.duration,vp代表video.packat,vb代表video.size

从图中可以看出,当video的缓冲数量为0时,duration并不为0.。。。

AudioTrack Underrun optimization · Issue #7808 · google/ExoPlayer · GitHub

android - AudioTrack restarting even after it is stopped - Stack Overflow

Ok, I think the problem is solved. The error is generated when the buffer is not completely filled with data on time (buffer underrun) . I have no idea what the timeout is but if you experience this make sure that:

1、You don't call the play method until you have some data in the buffer.

2、You can generate the data fast enough to beat the timeout.

3、After you are finished feeding the buffer with data, before you call stop() method, make sure that the "last" buffer was completely filled with data before timeout.

当我实例化名为 audioTrack.play() 的 Audiotrack 时,我收到了该警告,并且 play() 调用和 audioTrack.write() 之间存在轻微延迟。 如果我在 write() 之前调用 play() 警告消失了。

Keep in mind that you must always send the buffer in smaller chunks,
 even if you have the big chunk ready. It still bothers me a bit that
 I'm not 100% sure if that is the right way but the errors are gone so I guess I can live with that :)
您必须始终以较小的块发送缓冲区,即使您已准备好大块。 我仍然有点困扰,我不是 
100% 确定这是否是正确的方法,但错误已经消失,所以我想我可以接受:)
I've solved by this

        if (mAudioTrack.getPlayState()!=AudioTrack.PLAYSTATE_PLAYING)
            mAudioTrack.play();
        mAudioTrack.write(b, 0, sz * 2);
        mAudioTrack.stop();
        mAudioTrack.flush();

android 0.5.1使用硬解码出现ANR · Issue #1388 · bilibili/ijkplayer · GitHub

I find out that it is caused by AudioTrack.write blocked for 5 seconds in ijksdl_aout_android_audiotrack:aout_thread_n
I try force pauce in stream_component_close audio before SDL_AoutCloseAudio(ffp->aout)
 as a workaround Are there any better ways?
我发现它是由 AudioTrack.write 在 ijksdl_aout_android_audiotrack:aout_thread_n 中阻塞 5 秒引起的
我在 SDL_AoutCloseAudio(ffp->aout) 之前尝试在 stream_component_close 音频中强制暂停作为解决方法
有没有更好的方法?

 09-21 12:05:39.843: W/AudioTrack(3956): obtainBuffer() track 0x2bec20 disabled, restarting错误_weixin_34122604的博客-CSDN博客

一般都在一个进程里面使用AudioTrack对象,AudioTrack对象使用完而回收,就会出现以上错误。解决方法是调用AudioTrack对象的release方法。释放AudioTrack对象,解除资源占用。

重要发现,当播放MP4完成后,执行ijkMediaPlayer.reset(),就会百分百出现

点播出现画面卡住,然后没声音,字幕还在稍微的动。出现问题的影片,都是在指定的位置,即特定的block后,画面就卡住

每次都是第90个block开始卡住

这个时候v.size缓冲区已经满,但是audio为0这个即为高频卡顿?

我们自己测试到高频卡顿现象,首先看到的日志是内存溢出,还有出现很多

Binder:2923_7 expire 8 lines

Slow operation: 52ms so far, now at startProcess: returned from zygote!

 

 软解出现高频卡顿了。。。软解才导致?

  硬解也出现高频卡顿。。。。video.size也出现15m。。。。为啥????

1.解决AudioManager可能存在的内存泄漏问题 (639a3a34) · 提交 · andylao62 / DKVideoPlayer · GitCode

解决AudioManager可能存在的内存泄漏问题 

android-(AudioManager)getSystemService(Context.AUDIO_SERVICE)导致内存泄漏-icode9专业技术文章分享

(AudioManager)getSystemService(Context.AUDIO_SERVICE)导致内存泄漏

有盒子出现media.codec进程报错的情况,这个进程出错,会导致画面不动,视频数据满,音频数据为0的情况

从这里可以判断,如果media.codec进程报错,如果没有换台,会一直是硬解码,也会一直报卡顿

 

解码这里加延时后,会有Log

 

 同时出现高频卡顿

 最终解决方案:

1、查内存泄漏

2、ijk切换到软解的时候,通知前端,让前端提示需要重启设备

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/189576.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis详解(二)

文章目录Redis的单线程模型Redis数据过期删除策略内存淘汰机制手写LRU持久化快照持久化(RDB)RDB优缺点AOF持久化AOF优缺点RDB和AOF的选择注意事项Redis修改配置后未生效(windows)Redis的单线程模型 Redis基于Reactor模式来设计开发了自己的一套高效的时间处理模型。 Redis内部…

leetcode-每日一题-1669-合并两个链表(中等,链表操作)

这道题就是考察对链表的理解,但是题目给的链表和我们数据结构学的还是有点不一样的,这里面的头节点是带节点信息的,我们按照课本来说的话头节点,或者叫首元节点如果我记得不错的话就是叫这个,是不提供节点信息的&#…

[数字媒体] PR视频剪辑之自定义音频、视频加速转场和特显停顿

这篇博客是作者数字媒体系列的笔记,仅作为在线笔记供大家学习。在剪辑视频中,我们会遇到自定义音频、视频加速转场、特显停顿、画面调整等技巧,这篇文章将详细介绍。希望对您有所帮助,后续有时间会深入分享视频制作、动画制作等内…

结合淘宝与Twitter详解分布式系统与其架构设计,分布式其实并不难,阿里架构师用实战给讲明白了!

什么是分布式架构 分布式系统(distributed system) 是建立在网络之上的软件系统。 内聚性:是指每一个数据库分布节点高度自治,有本地的数据库管理系统。 透明性:是指每一个数据库分布节点对用户的应用来说都是透明的…

手把手教你如何从0到1开发自动化测试框架,你确定不看?

目录 一、序言 二、自动化测试框架技术选型 三、自动化测试框架的设计思路 四、自动化框架介绍 五、框架技术要点解析 六、后续TODO 一、序言 随着项目版本的快速迭代、APP测试有以下几个特点: 首先,功能点多且细,测试工作量大&#x…

Redis基本通用命令

通用命令 查看使用文档,例如要查看select怎么使用 help select切换数据库 select 1查看符合模板的所有key keys * keys *a keys a*判断key是否存在 exists k1给key设置有效期,给k1设置20秒有效期 expire k1 20查看key剩余有效期,查看k1…

2014年408算法题

文章目录0 结果1 题目2 思路0 结果 1 题目 2 思路 二叉树的带权路径长度(WPL)的计算方法有两种: 1,定义:WPL所有叶结点的权值Wi∗该结点深度Di求和WPL所有叶结点的权值W_i*该结点深度D_i求和WPL所有叶结点的权值Wi​…

linux环境minio安装启动,管理员登录,nginx代理

一.下载minio 官网下载: MinIO | Code and downloads to create high performance object storage 直接点击下载或者用wget https://dl.min.io/server/minio/release/linux-amd64/minio 最后都是得到一个文件minio(大概100M) 二.启动minio 1.创建文件夹,比如 mkdir /data…

mysql的redolog、undolog、binlog介绍,及mysql两阶段提交

https://blog.csdn.net/weixin_45676738/article/details/124770085 https://blog.csdn.net/TABE_/article/details/124935324 三种log REDO LOG 称为 重做日志 ,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。 UNDO LOG 称…

电源管理系统的功能和发展前景分析

电源对于电子设备的重要性不言而喻,电源管理系统是将电源有效分配给系统中的不同组成,在电子设备中起到了电能变换、控制、检测等作用,保证系统的稳定运行,对设备的性能有着直接影响,广泛用在工业、新能源、机器设备、…

一、初识 Spring 框架

文章目录一、Spring 简介二、Spring 框架的优点三、Spring 框架的组成四、Spring 框架 学习路线一、Spring 简介 Spring 框架简介 2004年3月24日发布了Spring 1.0正式版,Spring 框架的诞生给整个软件行业带来了春天。这个框架极大程度上简化了开发,其本…

基于无人机和背负式激光雷达点云的黄河三角洲刺槐林地上生物量估算

论文标题:Estimation of aboveground biomass of Robinia pseudoacacia forest in the Yellow River Delta based on UAV and Backpack LiDAR point clouds ABSTRACT 人工林是陆地碳汇的重要来源。黄河三角洲刺槐林是我国最大的人工生态防护林。然而,自…

“深度学习”学习日记。与学习有关的技巧--超参数的验证

2023.1.31 超参数是指神经网络中,神经元的数量、batch的大小、参数更新时的学习率或权值衰减等,虽然超参数的取值非常重要,但是决定超参数的值时会伴随很多人工的试错,所以我们需要高效地寻找超参数的值的方法 一,验…

【4】【Spring】,【Ioc/DI】,【IoC容器】,【Bean】

1、Ioc/DI,IoC容器,Bean 为了解决不同实现方式耦合度高 Ioc:(Inversion of Control)控制反转 主要思想:使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移…

vite打包静态文件打开显示空白

vite 打包生成静态文件打开显示空白 需求场景 本地调试访问打包的文件看是否有啥问题,方便定位线上问题安卓手机需要去直接访问静态文件,而不是访问域名的情况 vite 打包生成的文件如果直接放在服务器中是可以正常访问的,但是本地直接访问…

三个方面使CRM在360度客户视图中受益

360度客户视图这个词相信您不会陌生,很多关于CRM客户管理系统的文章中都有所提及。所谓的360度客户视图,是帮助企业和业务人员建立客户认知,消除客户生命周期中的信息脱节,让业务人员为客户提供一致性的体验。接下来我们们说&…

Windows10神州网信版的安装

在大约20天里面我完成了Windows10神州网信版72台的安装,有些2009~2014年的计算机完成安装后做一般的办公应用也能流畅运行。买一台新的计算机至少要好几千,通过更换固态硬盘和内存条可以达到旧物新用的目的。 一、安装过程   1、检查硬件  …

Coggle 30 Days of ML(23年1月)打卡

前言 任务链接 这个任务内容比较感兴趣而且和工作内容相关,学习一下打个卡。 编码完成任务1,2,3,5,6,目前手上只有2080,之后在3090上跑。 最近杂事多,笔记、任务4和7之后再补充。 …

vue前端框架课程笔记(五)

目录非文件组件使用步骤定义组件示例(第一部分):使用Vue.extend函数创建三个组件注册组件示例(第二部分):组件的全局和局部注册组件使用示例(第三部分):编写组件标签最终…

软件工程(三)——需求工程、需求开发、需求定义

目录 一、需求定义 二、需求验证 三、需求管理 1.定义需求基线 2.需求跟踪 3.变更控制 四、软件系统建模 一、需求定义 把已经分析好的需求,落成文档,把东西记录下来,成为《需求规格说明书》。需求定义的方法有严格定义法 以及 原型法…