温馨提示:这篇文章已超过450天没有更新,请注意相关的内容是否还可用!
摘要:WebRTC中的NetEQ音频处理模块针对网络延时和丢包问题提供了有效的实现机制。该机制通过动态调整音频处理流程,实现音频的抗网络延时与抗丢包能力。NetEQ利用数据包的重传和预测技术来应对网络波动,确保音频数据的连续性和流畅性。其核心功能包括检测网络状况、调整音频缓冲和处理策略,以应对不同网络环境下的音频传输问题。这一实现有助于提升WebRTC音视频通话的音质和用户体验。
目录
1、引言
2、WebRTC简介
3、什么是NetEQ?
4、NetEQ技术详解
4.1、NetEQ概述
4.2、抖动消除技术
4.3、丢包补偿技术
4.4、NetEQ概要设计
4.5、NetEQ的命令机制
4.6、NetEQ的播放机制
4.7、MCU的控制机制
4.8、DSP的算法处理
4.9、DSP算法的模拟测试
5、NetEQ源文件说明
6、参考文档
C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++基础与进阶(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_11931267.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)
https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_2276111.html 音视频软件随着应用场景和使用环境的变化,对音频的质量要求越来越高,要实现高质量的音频效果,可以借鉴音视频领域一些成熟的解决方案。WebRTC正是目前解决话音质量最先进的语音引擎之一,其中NetEQ网络均衡器模块很好地解决了音频数据在低带宽下出现的延迟、抖动与丢包问题。本文将详细分析WebRTC中NetEQ网络均衡器的实现原理、处理流程以及丢包补偿处理机制。
1、引言
由于IP网络主要用于数据传输业务,与传统的电话占用独立的逻辑或物理线路不同,因此没有服务质量(Qos)保证,存在包乱序到达、延迟、丢包和抖动等问题。对于丢包,业务上可以采用重传或者多倍发送机制,但音视频软件都是实时业务,对带宽、时延和抖动有严格的要求,所以必须有一定的Qos保证。
音视频软件中影响音频质量主要有两个因素:时延抖动和丢包处理。一般通过抖动缓冲区来消除网络传输所带来的不良影响,抖动缓冲区技术直接影响丢包处理。接收缓冲区可以用来消除时延抖动,但如果发生丢包,会卡顿或者填静音或者插值补偿,但在时延大、抖动大、丢包严重的网络中,效果都不理想。
如何借用WebRTC中的NetEQ网络均衡器的技术来提高软件的音频质量,首先需要分析分解NetEQ的原理和处理流程,其次是了解丢包补偿算法的原理和使用场景,然后就是将之有效到应用到软件产品的设计中去。
2、WebRTC简介
在详细介绍WebRTC中的NetEQ网络均衡器之前,我们先来大概地了解以下WebRTC。
WebRTC(Web Real-Time Communication)是一个由Google发起的实时音视频通讯C++开源库,其提供了音视频采集、编码、网络传输,解码显示等一整套音视频解决方案,我们可以通过该开源库快速地构建出一个音视频通讯应用。
一个实时音视频应用软件一般都会包括这样几个环节:音视频采集、音视频编码(压缩)、前后处理(美颜、滤镜、回声消除、噪声抑制等)、网络传输、解码渲染(音视频播放)等。其中每一个细分环节,还有更细分的技术模块。
虽然其名为WebRTC,但是实际上它不光支持Web之间的音视频通讯,还支持Windows、Android以及iOS等移动平台。WebRTC底层是用C/C++开发的,具有良好的跨平台性能。
- WebRTC主要使用C++开发实现,代码中大量使用了C++11及以上的新特性,在阅读源码之前需要大概地了解C++的这些新特性。
- 学习C++11新特性很有必要,不仅在C++开源代码中会频繁地使用到新特性,在跳槽时的笔试面试时也会经常被问到。
- 推荐大家仔细研读一下新版的、免费公开的《Google 开源项目风格指南(zh-google-styleguide)》,它不仅仅是Googe的编码规范,它不仅告诉你编码时要怎么做,还告诉你为什么要这么做!对于学习C++11及以上的新特性也很有好处!这本项目风格指南,我们项目大组去年系统地研读过,收获很大,很有参考价值!
WebRTC因为其较好的音视频效果及良好的网络适应性,目前已被广泛的应用到视频会议、实时音视频直播等领域中。在视频会议领域,腾讯会议、华为WeLink、字节飞书、阿里钉钉、小鱼易连、厦门亿联等国产厂商均提供了基于WebRTC方案的视频会议。
大家熟知的音视频专业服务商声网(Agora),更是基于开源WebRTC库,提供了社交直播、教育、游戏电竞、IoT、AR/VR、金融、保险、医疗、企业协作等多个行业的音视频互动解决方案。使用声网服务的企业包括小米、陌陌、斗鱼、哔哩哔哩、新东方、小红书、HTC VIVE 、The Meet Group、Bunch、Yalla等遍布全球的巨头、独角兽及创业企业。除了头部公司声网之外,也陆续有多家公司基于开源的WebRTC,开发出了多个音视频应用,提供了多个领域的音视频通信解决方案。
3、什么是NetEQ?
NetEQ 本质上就是一个音频的 JitterBuffer(抖动缓冲器),全称是 Network Equalizer(网络均衡器)。
GIPS 语音引擎的两大核心技术之一就是包含丢包隐藏算法的高级自适应抖动缓冲器技术,称作 NetEQ。2010 年谷歌公司以6820万美元收购Global IP Solutions公司而获得的这项技术,另一个核心技术就是3A算法。随后,谷歌在2011年将其集成到 WebRTC 中对外开源发布。
NetEQ 集成了自适应抖动控制算法和语音丢包隐藏算法,并且与解码器进行集成,所以 NetEQ 能够在较高的丢包环境下始终能够保持较好的语音质量。
在这里,给大家重点推荐一下我的几个热门畅销专栏:
专栏1:(该精品技术专栏的订阅量已达到430多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!)
C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)
https://blog.csdn.net/chenlycly/article/details/125529931
本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!
考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!
专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!
专栏2:
C/C++基础与进阶(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_11931267.html
以多年的开发实战经验为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对C++相关知识点进行详细地展开与剖析!专栏涉及了C/C++开发领域多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!
专栏3:
VC++常用功能开发汇总
https://blog.csdn.net/chenlycly/article/details/124272585
专栏将10多年C++开发实践中常用的功能,以高质量的代码展现出来,并对相关功能的实现细节进行了详细的说明。这些常用的代码,其质量与稳定性是有保证的,可以直接拿过去使用,可以有效地解决C++软件开发过程中遇到的问题。
4、NetEQ技术详解
4.1、NetEQ概述
NetEQ处理中包括了自适应抖动控制算法和语音丢包补偿算法。自适应抖动算法能够快速适应不断变化的网络环境,而语音丢包补偿算法能够保证一定的音质和清晰度且缓冲延迟最小,另外对NetEQ算法的模拟测试有助于评估音质效果和如何与现有软件设计的有机结合。
NetEQ处理中包括了自适应抖动控制算法和语音丢包补偿算法。自适应抖动算法能够快速适应不断变化的网络环境,而语音丢包补偿算法能够保证一定的音质和清晰度且缓冲延迟最小,另外对NetEQ算法的模拟测试有助于评估音质效果和如何与现有软件设计的有机结合。
NetEQ的模块概要图如下所示:
从上图可以看出,NetEQ分为4部分:自适应缓冲(Adaptive packet buffer)、语音解码器(Speech decoder)、抖动控制和丢包补偿(Jitter control and error concealment)和播放(Play out)。其中抖动控制和丢包补偿模块是NetEQ的核心算法,既控制着自适应缓冲,又控制着解码器和丢包补偿算法,并且将最终的计算结果交给声卡去播放。
首先,NetEQ是目前最为完善的抖动消除技术。与固定抖动缓冲和传统的自适应抖动缓冲相比,NetEQ能够快速适应不断变化的网络环境,因此保证了更小的延迟和更少的丢包。NetEQ自适应抖动算法性能比较如下图所示:
其次,抖动控制和和丢包补偿模块由三大操作所组成,即Expansion、Normal和Accelerate:
Expansion:扩展操作,即对语音时长的拉伸,其中包括expand和preemptive_expand两种模式。前者为NetEQ的丢包补偿处理,其作用是等待延迟包并补偿丢包;后者为优先扩展,即在原有数据的基础上拉伸语音时长,其作用是实现减速播放。
Normal:正常播放操作,即网络环境正常且相对平稳时的操作。
Accelerate:加速操作,即实现快速播放。综上所述,本文主要讨论NetEQ的抖动消除和丢包补偿技术,并结合模拟测试和产品设计分析来进一步提高视频会议产品的通话音质。NetEQ性能列表如下所示:
4.2、抖动消除技术
有两种抖动的定义:
抖动定义1:指由于各种延迟的变化导致网络中的数据分组到达速率的变化。具体地说,可将抖动定义为数据流在发送端发送间隔与接收端接收间隔之差,适用于可变码率场景。
抖动定义2:接收端某个数据包到达间隔与平均数据包达到间隔之差定义为该数据包的延时抖动,使用于恒定码率场景。
抖动是一个零均值的随机序列,是由排队IP包的延迟时间差构成的。数据包堆积时意味着数据包提前到达,虽然保证了语音的完整性,但是容易造成接收端缓存溢出并且会增大端到端延迟。数据包超时时意味着数据包经过网络传输后,一段时间后仍未到达接收端,说明数据包可能会延迟到达或者丢包。由于溢出和超时均可导致丢包,会增加端到端的丢包概率。因此,必须对抖动进行有效的控制,以减少由此引起的丢包。
抖动通常采用抖动缓冲技术来消除,即在接收方建立一个缓冲区,语音包到达接收端时首先进入缓冲区暂存,随后系统再以平稳的速率将语音包从缓冲区提取出来,经解压后从音频端口播放。抖动消除的理想状态为:每个数据包在网络传输中的延迟与缓冲区中的所有缓冲数据的延迟应该相等,而缓冲区的大小应该与每个数据包提前到达的抖动加上缓冲数据的延迟之和相等。
抖动缓冲控制算法包括静态抖动缓冲和自适应缓冲抖动控制算法两类:
静态抖动控制算法:缓冲区的延时和大小在语音通话建立后一直到通话结束,均为固定值,对于超时和抖动超出缓冲区大小的数据将会被丢弃。该算法模型简单,易于实现;但网络延时大、抖动大时,丢包率较高,而网络延时和抖动小时,语音延迟较大,不能根据网络状况动态改变缓冲区的延时和大小,而且初始值限定了适用的网络状况。
自适应抖动控制算法:缓冲区的延时和大小随着实际网络的抖动情况而变化。接收端将当前收到的数据包的延迟与算法中保存的延迟信息相比较,得到当前网络的最大抖动,从而选择恰当的缓冲区延时和大小。该算法的优点是:网络抖动大时丢包率小,网络抖动小时延时小;缺点是算法多样且相对复杂。
考虑到当前网络的复杂多变,一般采用自适应抖动算法,NetEQ的抖动消除也属于这类算法。
4.3、丢包补偿技术
丢包补偿又称为丢包隐藏,即Packet Loss Concealment,简称为PLC,可以分为两类:基于发送端补偿和基于接收端补偿。丢包补偿技术构成如下:
基于发送端的补偿也称为丢包恢复,即Packet Loss Recovery。一般来说,基于发送端的补偿要比基于接收端的补偿效果要好,但会增加网络带宽和时延。
FEC(Forward Error Correction,前向纠错技术)是目前最看好的一种改善VoIP语音质量的冗余编码技术,目的在于提高语音数据传输时的可靠性。为此FEC不仅要传输原始数据,同时还要根据相关性,传输一些冗余数据,以便使解码端根据数据之间的相关性重构丢失的数据包。在VoIP中最简单是奇偶校验码。这种方法是每个n-1个数据包就传输一个包含前面n个数据包的异或操作的校验码,当网络每n个数据包只丢失一个包时,可从别的n-1个数据包重构丢失的数据包。基于奇偶校验包的FEC如下所示:
当发生连续丢包时,FEC等各种补偿技术的效果都不理想。为了抵抗大段的突发连续语音丢失,可采用交织(interleaving)技术。交织技术不是真正的丢包恢复技术,因为它不能恢复已经丢失的数据包,但是这种技术能够减少丢包带来的损失。交织技术是通过把原始数据分成若干个比IP包小的单元,在发送前,重新排序这些单元的顺序,使得每个IP包中的数据来自不同的语音帧,当发生丢帧时,只是每一帧的一部分数据丢失,不会出现一帧数据全部丢失现象,在接收端这些单元再重新排序。交织技术利用了人脑能够利用听觉感知自动恢复丢失的一部分数据的功能。当每帧数据只丢失少量数据时,对人耳听觉的影响较小,从而提高音质。由于没有输出额外的信息,所以不会增加带宽,但是由于需要在接收端重新排序,所以会增加时延,达到一定程度也会让人无法忍受。GSM系统就采用了交织技术。
交织技术如下:
低比特率冗余编码(Low-rate Redundant Coding)是一种冗余技术,每个数据包除了包含自身的数据外,还包含前一帧数据经过压缩后的复制,该复制质量低,占用比特数少。当接收端丢包后,可从后面的数据包利用这个复制快速重构丢失包。不像FEC增加的比特数与前后帧具有相关性,它只是简单的在后续包中一份复制,所以也会增加带宽和时延,但是在网络拥塞时与FEC一样,对于连续丢包不适用,会导致丢包更严重。G.729A就采用了冗余编码技术。冗余编码恢复丢包示意图如下:
接收端丢包补偿技术的基本原理是产生一个与丢失的语音包相似的替代语音,这种技术的可行性是基于语音的短时相似性和人耳的掩蔽效应,可以处理较小的丢包率(0.9)或者为信号能量很低时才会加速,算法与减速处理类似。如下图所示:
2)减速:将一个语音包的样本数增加,增加的数据是根据语音样本的相关性所得到的基音周期。将两个样本周期的语音数据经过平滑处理,插入两个样本周期之间。减速操作以30ms为一帧,且待播放数据至少有0.625ms,否则重复播放上一帧;当解码后数据缓存不足30ms时,直接拷贝至播放缓存。基音周期的范围为2.5ms至15ms,所以最多延长15ms。如下图所示:
3)插帧:采用iLBC的丢包补偿算法,即重建线性预测系统、重建残差信号和将补偿帧能量逐帧递减。插帧操作时待播放缓存要小于播放读取时长(10ms)。如下图所示:
4)融合:上一帧丢包之后会进行插帧操作,当新的数据解码后,为了提高语音数据的连贯,对新的解码数据和插帧数据进行平滑处理,能量渐强。融合操作生成的数据中间数据较大,需要预留最大空间。如下图所示:
5)正常:这时新的解码数据正常输出播放,但如果上一帧数据是插帧数据,需要先插帧再平滑。
4.9、DSP算法的模拟测试
针对以上DSP算法操作,本文分别对间断的语音信号(Test1)、连续的语音信号(Test2)和音乐信号(Test3)在不同丢包率下进行了模拟测试,并采用ITU-T P563客观测量标准进行MOS值估计,LostData为丢包时填补静音,Expand为丢包时插帧,Expand+Merge为丢包时先插帧再融合。
测试
序列
输出帧
时长
丢包率
MOS(P563)
LostData
Expand
Expand+Merge
test1
10ms
10.00%
2.131
2.163
2.377
11.11%
2.237
3.085
3.073
12.50%
1.717
2.930
3.231
14.29%
2.159
3.138
3.348
16.67%
1.656
2.650
3.275
20.00%
2.364
2.161
2.333
25.00%
1.838
3.001
3.033
间断话音信号对丢包率的变化不是很敏感,因为丢包的时候没有丢失太多语音时MOS值就会比较好,丢包时产生的爆破音在丢包补偿之后都有明显改善,主观感受良好。
测试
序列
输出帧
时长
丢包率
MOS(P563)
LostData
Expand
Expand+Merge
test2
10ms
10.00%
2.656
2.872
3.598
11.11%
2.568
2.997
2.926
12.50%
2.634
3.162
3.038
14.29%
2.530
3.169
3.007
16.67%
2.290
2.903
2.980
20.00%
2.522
3.206
3.108
25.00%
1.952
2.943
2.952
连续话音信号跟随丢包率呈现出逐渐下降的趋势,丢包补偿的效果与Test1相近,爆破音明显改善,主观感受良好。
测试
序列
输出帧
时长
丢包率
MOS(P563)
LostData
Expand
Expand+Merge
Test3
10ms
10.00%
2.428
2.658
2.855
11.11%
2.577
2.708
2.663
12.50%
3.420
2.478
2.739
14.29%
3.552
2.444
2.863
16.67%
3.251
2.421
2.792
20.00%
1.000
2.208
2.527
25.00%
1.099
1.993
2.474
音乐信号选取的是久石让的《天空之城》,整个频谱变化较大,丢包率较小时补偿效果不错,丢包率越大补偿的主观效果越差。
加速、减速和正常操作就不一一对比了,其中加速和减速操作在不丢包时对消除抖动的音质效果非常好,保持语音信号的完整性。
上图中动态模拟的初始值为37个样本,即初始时待播放样本为37个。Expand之后Merge得到的MOS值下降,有两个可能的原因:1、Expand前待播放字节数较少,导致插帧数据音质不高;2、Merge前Expand补偿的数据较多影响Merge后的音质,理想情况应该是Expand和Merge一一对应。
上图中固定模拟的固定值为500个样本,即待播放样本保持为500个。这时Expand得到的MOS值有较大提升,之后每次都进行Merge操作,帮助提高MOS值。
上图中动态模拟的初始值为0,即初始时待播放样本为0个。这时Expand之前待播放样本减少导致Expand插帧数据的MOS值降低,之后虽然不是Expand和Merge一一对应,但是每次Merge之前待播放数据较少,所以需要平滑的数据就会更少,帮助提高MOS值。
P563标准的几个重要参数为:信噪比(SNR)、静音间隔和平均基音周期等,没有参考相位变化,但是相位变化对听觉的主观影响很大,比如在插帧数据之后相位不连续的波形有可能会产生爆音,这时会影响音质,所以插帧与融合虽然采用P563的MOS值估计有时相差无几,但是融合的主观感受要明显好于插帧。
5、NetEQ源文件说明
mcu_dsp_common.h:NetEQ实例。
neteq_error_codes.h:NetEQ错误码。
neteq_statistics.h:NetEQ PLC统计信息。
dsp.h:dsp上PLC操作的头文件。
accelerate.c:加速操作以减少延时。当信号的相关性很强且信号能量很弱的时候进行处理。
expand.c:生成音频信号并生成背景噪声。
preemptive_expand.c:减速以增加延时。
normal.c:正常播放。
merge.c:将新的一帧数据与扩展的上一帧数据做平滑处理。
bgn_update.c:背景噪声估计和更新。
cng_internal.c:生成舒适背景噪声。
dsp.c:dsp操作的初始化函数和常量表的定义。
recin.c:添加RTP数据包。
recout.c:解码输出PCM。
dsp_helpfunctions.h
dsp_helpfunctions.c:两个dsp的函数,频率是8k的倍数和降采样到4k。
min_distortion.c:最小失真计算。
correlator.c:计算信号的相关性。
peak_detection.c:相关性峰值检测和定位。
mix_voice_unvoice.c:混音
mute_signal.c:静音(减弱)
unmute_signal.c:关闭静音(渐强)
random_vector.c:随机向量。
codec_db_defines.h
codec_db.c:管理算法库的数据库。
dtmf_buffer.h
dtmf_buffer.c:DTMF消息和解码。
dtmf_tonegen.h
dtmf_tonegen.c:生成DTMF信号。
mcu.h:MCU侧操作。
mcu_address_init.c:MCU地址初始化。
mcu_dsp_common.c:MCU和DSP之间的通信。
mcu_reset.c:重置MCU侧的数据。
set_fs.c:DTMF采样率。
signal_mcu.c:通知MCU数据可用并请求一个PLC命令。
split_and_insert.c:分拆RTP头并添加到数据包缓冲。
rtcp.h
rtcp.c:RTCP统计。
rtp.h
rtp.c:RTP函数。
automode.h
automode.c:动态缓存策略。
packet_buffer.h
packet_buffer.c:数据包缓存管理。
buffer_stats.h
bufstats_decision.c:根据缓存抖动来给出PLC命令。
webrtc_neteq.h
webrtc_neteq_help_macros.h:NetEQ宏定义
webrtc_neteq.c:NetEQ API。
webrtc_neteq_internal.h:NetEQ内部函数
webrtc_neteq_unittest.cc:NetEQ单元测试。
6、参考文档
《GIPS NetEQ》,Global IP Solutions
《WebRTC语音引擎中NetEQ技术的研究》,吴江锐
《WebRTC语音引擎中分组缓存技术研究》,肖洪亮
《VoIP丢包处理技术的研究发展》,李如玮,鲍长春
《ITU-T P.563 Single-ended method for objective speech quality assessment in narrow-band telephony application》,国际电联ITU(International Telecommunication Union)
http://en.wikipedia.org/wiki/Opus_(codec)
还没有评论,来说两句吧...