【腾讯】一文读懂腾讯会议在复杂网络下如何保证高清音频( 三 )


后来 , 我们还做了服务器混音 。 首先可以减少下行用户的流量 , 其次多路混音成一路 , 也可以对融合通信发挥基础作用 。 在对外提供 OpenSDK 的时代 , 因为对外用户的需求很不一样 , 因为应用场景的差别 , 有的用户需要不通类型 Codec , 有的用户需要关掉 3A 处理 , 有的用户不需要那么大流量 , 有的用户更加在乎质量而不在乎流量 , 所以云端的 Spear 可配置参数的流控策略可以满足我们企业内部应用 , 包括外部用户的差异化需求 。
【腾讯】一文读懂腾讯会议在复杂网络下如何保证高清音频
本文插图
腾讯会议对于拥塞控制的做法 接下来我们看比较核心的拥塞控制(Congestion Control) 。 其实拥塞控制在实时 RTC(Real Time Communication)音视频通讯领域应用中是必不可少的模块 , WebRtc 在开源以后分别向社区贡献了 GCC1 和 GCC2 版本 , 当然这块不是说 Linux 系统下编译器的那个 GCC 。
GCC1(Google Congestion Control ver.1)是一个基于接收端的算法 , 根据每家系统的软件架构的不同 , 它部署的位置也不一样 。 GCC1 核心算法是通过实时监控端到端延时的变化量(Jitter) , 从而判断当前这个网络是否趋于达到网络拥塞的情况 。
我们首先看端到端延时这个基础概念 , 端到端延时由三部分组成:一个是传输延时 , 跟数据包大小及链路宽有关;第二个是队列延时 , 即数据包在路由器的队列中通过的时长;第三个传播延时 , 一般传播延时跟传输介质有关 。
实际上在 GCC1 或者 GCC2 里面 , 它真正进入系统、进入计算的这个变量不是端到端延时 , 而是其变化量即 Jitter;Jitter=(TR(i)- TR(i-1))- (TS(i)- TS(i-1)) 包括前后两个数据包的接收时间戳之差再减去前后两个包发送时间戳之差 , 算法输入的是一个 Jitter , GCC1 通过 Kalman 自适应滤波器去除噪点 , 通过网络传输也好 , 通过整个链路传输过程也好 , 实际上这种延时的变化值 Jitter 是一种符合高斯分布的特征 , 当我们把噪点去掉以后就可以得出它的 Jitter 趋势 。 GCC1 算法将滤波后的 Jitter 值与动态阈值进行相应的状态判断 , 从而得出当前的网络是否趋于拥塞或者处于正常 , 与此同时还通过实时接收到的流量和预测算法给出当前一个合理的带宽预测值 。
后来 GCC2 又更新了 , 是基于发端的 , 它的数据处理源还是 Jitter , 就刚才说那个 Jitter , 它是一个什么概念呢?自变量就是 Jitter , 应变量是什么呢?应变量是它的历史平均值 。 所以它对自变量和应变量做了一个最小二乘法的一元线性回归 , 相当于去观察当前的 Jitter 值相比较历史平均值有怎样的发展趋势 , 被称作 TrendLine 算法 。 GCC 算法它在发送端也好还是在接收端也好 , 带来了工作上的灵活性 , 而 GCC1 中绝对值的阈值比较变成了 GCC2 中趋势线的判断 , 算法的准确性上有提高 。 而从及时性上来说 , 我们在 QQ 时代使用 GCC1 算法是 , SDK 的架构还是有私有协议的 , 比如说反馈机制都是基于两秒的机制 , 在最新重构的第三代 xCast SDK 上上 , 完全兼容了标准协议 , RTP 算法核心有准确度的提升 , 反馈上 RTCP 时机和及时性也有提升 , 所以“腾讯会议”相关的算法控制会远远老一代的 SDK 产品更加及时和准确 。

【腾讯】一文读懂腾讯会议在复杂网络下如何保证高清音频
本文插图
FEC 如何把丢失的数据包恢复? FEC(Forward Error Correction)实际上没有太多新意 , 这块无非就是利用其基本的特性 。 比如分组划分 , 接收端恢复不受数据包顺序影响等特征 。 举个例子:如果是分组是 4 , 那么在网络传输过程中任意丢掉一个 , 在接收端任意收到任何顺序的 4 个属于本分组的数据包 , 那就可以把丢失的包恢复 。