婚恋系统源码开发,解决直播视频的丢帧问题

本文将以婚恋系统源码视频播放的丢帧问题为例,介绍在解决这一性能问题时的思路、所使用的工具、尝试的优化方案和一些测试的结果,具有较强的综合性。当然,我本人在性能优化方面也只是新手,欢迎大家一起讨论交流。

问题

ExoPlayer 是google推出的一款开源java播放器,包括youtube在内的很多视频服务商都在使用它,但是我们发现,在一些性能比较低的硬件平台上,使用exoplayer播放视频时会出现大片的丢帧,视频画面也随之变得“一卡一卡的”。

假设

和其他应用不同的是,婚恋系统源码直播视频的音视频解码会消耗大量的CPU资源,同时这一工作对解码的速度是有硬要求的,如果达不到的话就会产生播放流畅度的问题。所以丢帧的原因很可能是CPU满负载,使得音视频没有足够的资源保持流畅播放。

验证工具

为了验证上面提出的假设, 这里主要使用了三个工具 :

  1. DS5 & Streamline

arm平台常用的性能分析工具, 基本的介绍和安装流程在网上都能搜到

  1. Systrace & TraceView

这两个是可以直接在android studio配套的device monitor中使用的性能分析工具, 前面的ds5 & streamline虽然强大, 却不能用于分析java代码的性能, 这里就是主要利用systrace和traceview来分析java代码的性能, 关于这两个工具的使用方法, 可以参考下面的链接Analyzing UI Performance with SystraceProfiling with Traceview and dmtracedump

  1. Bento4工具集

利用bento4工具集, 可以自制一些hls或者dash测试流, 同时bento4还支持最新的hls-fmp4

验证结果

利用streamline在播放婚恋系统源码视频的同时抓取系统信息, 可以发现播放器进程中的loader:hls线程存在burst现象, 具体来说, cpu占比(其中两个核)可以达到60%~80%, 如下图所示

这里写图片描述

同时, 通过对比实时抓取的log, 也可以看到发生burst的时候一定伴随着大量的丢帧. 由此, 可以确定, loader:hls对cpu资源的大量占用是播放视频卡顿的一个很重要的原因.

调查与分析


一,
首先阅读exoplayer的代码, 可以看到loader:hls线程就是在播放器后台进行m3u8和ts切片下载的线程, 既然如此, 就很容易联想到是下载中的IO操作占用了cpu资源, 分析一下播放过程中几个关键的io操作, 或者说涉及到buffer的操作, 可以简单表示为: cdn --> buffer --> player --> 播放器缓存buffer --> 解码器buffer --> decoder 从这个流程来说婚恋系统源码没什么可以优化的点,看来要从别的地方优化。


二, 详细来看loader:hls部分的代码,发现了一个很可疑的循环

in TsChunk.java@load()
while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
    result = extractorWrapper.read(input);
    ...
}

这里的read方法会调用 TsExtractor.java@read, 如下

public int read(ExtractorInput input, PositionHolder seekPosition)
throws IOException, InterruptedException {
if (!input.readFully(tsPacketBuffer.data, 0, TS_PACKET_SIZE, true)) {
return RESULT_END_OF_INPUT;
  }
  // parse a packet
  .....
  return RESULT_CONTINUE;
}

上面的readfully方法负责下载工作, 可以看到每次以TS_PACKET_SIZE=188为单位进行下载, 在read方法中接下来再对下载得到的packet进行解封装操作, 由此可以确认, 当有burst时,一定也有ts的下载和parser的频繁循环调用, 循环次数可以用 bitrate*segDuration / (188 * 8) 来计算, 当婚恋系统源码的码率约为8Mbps, 分片时长10s的时候, 循环次数可以达到50000次, 而实际中视频的码率并非固定, 低的时候可以仅有7Mbps, 高的时候可以达到16Mbps,这样一来循环次数就非常可观了。

由此可以做出初步的推断:因为在loader线程里面还同时进行了解封装操作,而TS格式的解封装相对fmp4等其他格式来说更加复杂,再加上每次只处理188字节,在播放高码率片源时就更加占用资源. 有的朋友可能要问了,那为啥一定要把婚恋系统源码的下载和解封装一起做呢?拆开不行吗?这里有两个考虑:一是如果先下载完毕再解封装的话,势必会影响起播速度;二是很多ts码流的音视频交织做的非常差,为了更好地音视频同步,很有必要提前做解封装。

下面使用traceview来判断到底是download还是parse消耗了更高的cpu, 从traceview得到的结果如下图所示

这里写图片描述

图中DefaultExtractorInput.read代表了download操作, PesReader.consume代表了parse操作, 可以看到还是download操作占用了更高的cpu.


三, 作为对比, 使用bento4工具制作了相同码率, 相同分片时长的hls-ts片源和hls-fmp4片源 使用streamline抓取系统信息, 播放ts流时结果如下图所示

这里写图片描述

而播放fmp4流时的结果如下图所示

这里写图片描述

对比download和parse的循环调用次数, ts流是fmp4流的1000倍 结论: loader:hls线程中伴随频繁download的io操作是cpu占用高的主要原因.

优化方案与结果

本节将介绍所尝试的婚恋系统源码几种优化方案和相应的结果,测试时考虑了限速和不限速的场景,主要观察的指标有起播时间,卡顿比,丢帧数,CPU占用


一, 降低loader:hls线程的优先级 简单粗暴,直接降低loader线程优先级,相当于提高了解码优先级,保证婚恋系统源码解码可以流畅完成工作,从而减少丢帧。修改起来也很简单,在loader线程里面加上一句

Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);

经过测试,发现可以减少一半的丢帧,经过长时间压测,也没发现对婚恋系统源码起播时间或卡顿比有影响。 再来看看cpu占用方面的变化,修改后

这里写图片描述

可以看到,loader仍然会有burst,峰值CPU占比仍然可达80%以上,但是有一部分被"打散",峰值持续时间减少,测试发现大约能减少1/3的burst 结论: 通过降低loader线程优先级, 可以将cpu占用的burst打散, 减少丢帧数目,未发现对起播时间和loading圈的影响。


二,在loader:hls线程的频繁调用中间强行sleep 与方案一降低线程优先级的思路类似,通过在前面提到的while loop中强行sleep,来空出CPU资源,但是这样很有可能会导致下载ts分片的时间变长,并引发loading圈或增加起播时间,为此,可以设计基于bufferedDuration的动态sleep机制 而具体的sleep逻辑,如下面代码所示

int i = 0;
try {
    int result = Extractor.RESULT_CONTINUE;
    while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
    i++;
    if (i > DEFAULT_EXTRACTOR_READ_INTERVAL && isHighBuffer) {
        i = 0;
        Thread.sleep(DEFAULT_SLEEP_TIME_MS);
    }
    result = extractorWrapper.read(input);
    ...
}

代码中DEFAULT_EXTRACTOR_READ_INTERVAL表示while loop循环多少次之后进行sleep,DEFAULT_SLEEP_TIME_MS表示每次sleep的时长,设置为10ms, isHighBuffer根据设定的阈值判断现在的缓冲区余量是否充足。 经过测试,同样能降低一半以上的丢帧,但是因为是强行sleep,会增加loading圈出现的次数,通过合理设置buffer阈值可以改善。 CPU占用方面倒没有方案一改善明显,依然存在burst。 其实对于方案一的降低线程优先级,也可以改成根据bufferedDuration来动态修改的逻辑。


三,一次下载多个ts packet 可以一次下载多个ts packet,让io操作不那么频繁,当然,解封装的时候还是只能以单个ts packet为单位进行。做一个极端的测试,婚恋系统源码使用自制hls流测试,每次下载500个ts packet,使用streamline查看系统信息,如下图

这里写图片描述

婚恋系统源码在一定时间段内能降低cpu占用,但是loading圈出现次数明显变多,可以通过更合理的设置一次性的下载数来改善。

以上就是对婚恋系统源码丢帧这一性能问题从假设验证到提出方案并测试的全过程了。
声明:本文由云豹科技转发自zhanghui_cuc博客,如有侵权请联系作者删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值