WebRTC音频QoS方法一(NetEQ之音频网络延时DelayManager计算)
一、整体思路不像视频一帧数据那么大,音频一帧数据包都比较小,UDP的1500个字节完全可以装满一帧。所以音频在发送端的发送时间间隔是按照固定的打包时长节奏发送的。如上图以30ms打包时长为例,ABCD四个报文的发送时间间隔都是30ms。若没有网络影响,接收端的包间间隔也是30ms,音频播放清晰流畅。1)延时定义:二、实现原理三、参考...
一、整体思路

| 时间点 | A | B | C | D |
| 发送 | 30 | 60 | 90 | 120 |
| 接收 | 40 | 90 | 100 | 130 |
| 延时 | null | 50 | 10 | 30 |
不像视频一帧数据那么大,音频一帧数据包都比较小,UDP的1500个字节完全可以装满一帧。所以音频在发送端的发送时间间隔是按照固定的打包时长节奏发送的。
以上图30ms打包时长为例,ABCD四个报文的发送时间间隔都是30ms。若没有网络影响,接收端的包间间隔也是30ms,音频播放清晰流畅。
但网络传输各种不可控因素会导致音频报文到达接收端存在丢包、乱序、抖动等异常。接收端若不特殊处理,用户体验会很差。
对于丢包异常传输层可以使用FEC/NACK修复。编解码层可以使用变速算法进行平滑。
对于乱序、抖动异常,需要使用JitterBuffer做平滑。JitterBuffer实现机制有静态JB和动态JB两种。
- 静态JB控制算法:缓冲区大小固定,容易实现,网络抖动大时,丢包率高,抖动小时,延迟大。
- 动态JB控制算法:计算目前最大抖动,调整缓冲区大小,实现复杂,网络抖动大时,丢包率低,抖动小时,延迟小。
DelayManager、BufferLevelFilter两个模块配合实现动态JB功能。以设置合理的缓冲空间,保证音频平稳播放。
- DelayManager用来计算接收端接收音频数据包延时时间;
- BufferLevelFilter用来计算系统当前共缓存音频数据包可播放时间(包括RTP报文缓存、音频解码后待播放数据缓存)。
这里首先介绍DelayManager模块实现原理。
二、实现原理
DelayManager模块的核心思想是计算target_level_ms_这个参数,DelayManager::Update是计算target_level_ms_参数的核心函数。

target_level_ms_参数由两个因素决定:单纯丢包时的延时值和丢包乱序下的最低cost值。这两种算法都用到了直方图,下面就详细介绍一下NetEQ直方图算法的实现。
1、IAT直方图介绍
IATVector直方图(Histogram of inter-arrival times)由65成成员变量组成,每个IATVector的成员变量是该延时出现的概率。
| IAT(inter arrival times) | 出现概率 |
| 0 | 72887611 |
| 1 | 999495224 |
| 2 | 529939 |
| 3 | 0 |
| 4 | 0 |
| 5 | 0 |
| 6 | 0 |
| 7 | 75384 |
| 。。。。。。 | 0 |
| 63 | 0 |
| 64 | 0 |
IATVector直方图里面保存的概率是以1<<30为分母的分子部分。
-
1)arrival_delay_ms计算
arrival_delay_ms=实际包间间隔 - 打包时长
函数:DecisionLogic::PacketArrived

packet_arrival_history_记录一个滑窗内最小抖动的报文,其他报文以这个报文为基准,计算delay抖动时延。
-
2)更新概率参数
UnderrunOptimizer::Update函数会根据计算的arrival_delay_ms,将该arrival_delay_ms插入IATVector直方图对应数组下标内。并更新该直方图的数据下标下概率参数。一共有四步操作:
- 1、用遗忘因子,对历史数据的出现概率进行遗忘。
![]()
- 2、增大本次计算到的IAT的概率值。
![]()
- 3、更新遗忘因子f,使f为递增趋势。即通话时间越长,包间隔的概率分布越稳定。

- 4、调整本次计算到的IAT的概率,使整个IAT的概率分布之和近似为1。
调整方式为假设当前概率分布之和为tempSum,则:

这四步操作,都在函数DelayManager::UpdateHistogram中实现。

-
3)根据IATVector直方图计算target_level_
UnderrunOptimizer::Update函数在每收到一包音频数据的时候,都会更新一次optimal_delay_ms_的值。
IATVector直方图的更新原理是,从IAT为0开始,累加出现的概率,当概率达到设定的kLimitProbability门限值时,配置target_level_为该直方图的数组下标。

2、DelayPeakDetector峰值检测算法
IATVector直方图的做法的思想是参考从通话启动,到目前为止的平均延时值,但是实时音视频通话中,还要考虑短时延时波动的影响。
下面这个算法新版本已经废弃。这种抖动峰值更新为在PacketArrivalHistory::GetMaxDelayMs函数中计算,寻找一个时间窗内最大抖动的报文值为抖动峰值。

所以webrtc里面也引入了DelayPeakDetector算法,检测短期内的延时最大值。作为target_level_的参考值。
实现的原理是,采用一个长度为kMaxNumPeaks的二维数组Peak,统计IAT的峰值。二维数组Peak,保存两个参数:峰值幅度(peak_height_packets)、峰值间隔时间(period_ms)。其中峰值间隔时间(period_ms)是统计当前探测到的峰值距离上一次峰值被发现的时间间隔。当Peak成员变量大于kMinPeaksToTrigger,且当前检测周期小于2*max(period_ms)则target_level_参考该峰值配置。若没有,使用 IATVector直方图计算的值。
-
1)DelayPeakDetector::Update函数将IAT异常峰值入队

-
2)DelayPeakDetector::CheckPeakConditions判断该峰值是否达到上报条件

-
3)DelayPeakDetector::MaxPeakHeight获取检测周期内异常峰值

-
4)DelayManager::CalculateTargetLevel修订target_level_

至此,完成target_level_的计算。


三、参考
《WebRTC语音引擎中NetEQ技术的研究_吴江锐》
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)