上一篇文章《播放器上音频断续问题的原因》提到了最后通过在解码前丢掉一半数量视频帧的方法,保证了音频解码通路有足够的时间片来运转,以实现高码率解码时音频连续。当然最终产品上不可能强制丢弃定量的帧数了,需要做一个动态的丢帧算法,根据播放i当前的状态自动调整丢帧的幅度。由于做丢帧算法的前一晚我玩了会儿极品飞车,最近又在关注上海车展,所以丢帧的算法也就沾了沾灵感,做成类似汽车加速换档和刹车的处理逻辑啦。我觉得看播放器运转情况来决定丢帧到什么程度,与看路况决定汽车开多快,这两点在逻辑上是十分类似的。一共有几个要点:

1、察看播放器当前运转情况,主要判断依据是DECODER之前拿到的FRAME时间戳,与当前播放时间相减,得到的提前量。这个提前量就表示了播放器卡或者不卡。比如我这里放行几帧之后,DECODER解得比较吃力,于是DECODER线程抢占了DEMUX线程的时间片,那么下面几帧到来的提前量会更小了。

1、汽车加速是一个渐变过程,不可能直接从1档换到4档跳变。同样地,播放器的运行状态也应该理解成一个渐变过程,尤其是对于CBR恒定码率的播放。如果做成只根据当前帧的时间提前量来判断的跳变,可以预想到会出现这样的情况;在高码率上,一开始由于解码来不及,我立刻丢帧,连丢若干帧之后,下面几帧到达DECODER的时间大大提前,所以放行,结果DEOCDER连续解这几帧显得非常吃力,并且挤占了其他线程的时间片,播放器进入最恶劣的情况,于是音频就断了;下几个视频帧到达时判断状态不佳,被连续丢弃,由于连续丢弃造成时间空闲,那么再下几帧的到达时间又大大提前……播放器就进入良性-恶性的不断摇摆中,音频还是要断的

2、汽车的刹车应该理解为一个跳变过程。事实上只能说是比较快的渐变,但我们总希望刹车越灵越好,最好直接从140kmh直接跳到0kmh,这样的车才是最安全的。播放器上面一样,一旦播放情况恶化,希望它能立刻作出反应,把当前到达DECODER的帧丢弃,以在最短时间内改善播放性能,否则只要恶化的情况持续片刻,比如几百毫秒,那么脆弱的音频就会断掉了。

3、两档之间应该有个用来确认加速有效的时间段,汽车不可能挂了二档后立刻就挂三档,而是应该在挂二档后确认一下这次提速是安全的,然后看看是否还有提速的空间,再挂三档。

4、车能开多快,应该是看当前路况上还有多少提速空间,而不是当前行驶速度。车速和路况有一个“最佳适合点”。比如我现在开到80kmh,和路况正好适合,那么就没必要提速到90kmh,如果一提速,可能就要撞车了。同样地,比如视频帧到达时间提前了300ms, 这是一个比较合适的提前量区间,如果我认为既然可以提前到300ms,那不妨放行更多帧去解码,那么很可能你会在2秒后看到提前量已经降到了50ms,这时就必须丢弃更多的帧来调整了。

5、越低的档,其加速过程越短;比如从1档加速到2档只需要很短的时间;而从4档换到5档,就需要比较长的加速时间。播放器上面也一样,在放行更多帧之前,需要越来越长的时间用以观察是否符合提档的标准。

说了这么多,我还是贴上代码和注释吧。

  1自创视频解码前丢帧的“挂档算法”bool JudgeDrop(UINT16 FrameSeqNum, s64 FrameTimestamp)  //FrameSeqNum是当前帧在整个视频文件中处于第几帧的序号,FrameTimestamp是当前帧的时间戳
  2


这段代码的运行效果良好,让video decoder腾出更多时间来给audio decoder运作,保证了音频输出的流畅连贯。

相关文章:

  • 2021-08-15
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-15
  • 2021-06-01
  • 2022-12-23
猜你喜欢
  • 2021-10-25
  • 2022-12-23
  • 2021-10-27
  • 2022-12-23
  • 2021-10-05
  • 2022-12-23
相关资源
相似解决方案