音视频编解码--Opus

1 简介Opus 是一个完全开源,免费的,通用性高的音频解码器。Opus 在网络上有着无与伦比的交互式语音和音乐传播功能,但也可以用来存储,在流媒体上使用。Opus 遵从 Internet Engineering Task Force (IETF) RFC 6716 标准,整合了 Skype's SILK 解码和 Xiph.Org's CELT 解码的技术。新的WebRTC中WebRTC中默认是采用Opus编码,Opus编码是由silk编码和celt编码合并在一起,silk编码是由skype公司开源的一种语音编码,特别适合人声,适合于Voip语音通信。celt和mp3,aac类似,适合于传输音乐。Opus编解码器的范围从6 kbit / s的窄带单声道语音扩展到510 kbit / s的宽带立体声音乐,算法延迟范围从5 ms到65.2 ms。

1.1 控制参数Opus编解码器包含许多控制参数,这些参数可以在编解码器的常规操作期间动态更改,而不会中断从编码器到解码器的音频流。 这些参数仅影响编码器,因为它们对位流的任何影响都通过带内信号通知,这样解码器可以解码任意Opus流而无需发送任何带外信号。 任何Opus实施都可以添加或修改这些控制参数,而不会影响互操作性。 下面列出了参考编码器中最重要的编码器控制参数。1.1.1 比特率Opus支持6 kb /秒到510 kb / s的比特率,比特率越高,质量越好。对于20 ms的帧大小,这些是各种配置下Opus的比特率“最佳点”

1.1.2 通道数Opus单独流可以支持单通道和立体声。在立体声解码器中解码单声道帧时,左声道和右声道相同,而在单声道解码器中解码立体声帧时,单声道输出是左声道和右声道的平均值。1.1.3 音频带宽Opus支持8 kHz(窄带)到48 kHz(全频)。就像通道数一样,任何解码器都可以解码在任何带宽下编码的音频。1.1.4 帧长Opus支持帧长度为:2.5、5、10、20、40、60毫秒。Opus还支持将多个帧组成一个120ms的包进行处理。在实际应用中,每秒发送较少的数据包会略微提高编码效率,也会降低比特率,因为它减少了IP,UDP和RTP标头的开销。 但是,这样操作增加了等待时间和对数据包丢失的敏感性,丢失一个数据包会造成更大一部分音频的丢失。同时对于20 ms以上的帧,音频增益值会变小。 因此,对于大多数应用而言,20 ms帧是一个不错的选择。1.1.5 复杂度Opus编码过程的各个方面都可以在CPU复杂度和质量/比特率之间进行权衡。 在参考编码器中,使用从0到10的整数选择复杂度,其中0是最低的复杂度,而10是最高的。 这种折衷计算有很多例子,包括:Ø 音调分析白化滤镜[WHITENING]的顺序,Ø 短期噪声整形滤波器的阶数,Ø 残留信号的延迟决策量化中的状态数,以及Ø 使用某些比特流功能,例如可变的时频分辨率和音调后置滤波器。1.1.6 丢包弹性音频编解码器通常利用帧间相关性来降低误码率,但代价是错误传播:当丢失一个数据包之后,在解码器能够准确地重建语音信号之前,需要优先接收几个数据包。 Opus利用帧间相关性的程度可以即时调整,以在比特率和错误传播量之间进行有效权衡。1.1.7 前向纠错(FEC)提供防止丢包的鲁棒性的另一种机制是带内前向纠错(FEC)。被确定为包含感知性重要语音信息(如开始或瞬变)的数据包将再次以较低的比特率进行编码,并将此重新编码的信息添加到后续数据包中。1.1.8 恒定/可变比特率使用可变比特率(VBR)(默认设置)时,Opus效率更高。当在相对较慢的连接上需要低延迟传输时,也可以使用受约束的VBR。这以模拟“位存储库”的方式使用VBR,基本等效于MP3(MPEG 1,第3层)和AAC(高级音频编码)称为CBR(即由于位存储库不是真正的CBR)。在某些特殊应用中,确实需要CBR技术,其主要原因有两个两个方面:Ø 当传输时,每个压缩帧仅仅支持一种固定大小的情况Ø 当一个高度受限或高度敏感的音频流被用于加密时,例如是否包含录制提示、STRP-VBR等。只要速率不受输入信号的影响(例如,为了匹配不断变化的网络条件),即使使用敏感数据,也可以允许比特率变化。为此,应用程序仍应在CBR模式下运行Opus,但在发送每个数据包之前需要更改目标速率。1.1.9 不连续传输(DTX)不连续传输(DTX)降低了静音或背景噪声期间的比特率。启用DTX时,每400毫秒仅编码一帧。2 Opus数据帧Opus编码器产生“数据包”,每个“数据包”是一组连续的字节,旨在作为单个单元进行传输。这里描述的数据包不包括通常在传输层数据包中发现的IP,UDP或RTP包头部分。一个数据包可以包含多个音频帧,只要它们共享一组公共参数即可,包括编解码操作模式,音频带宽,帧大小和通道数(单声道与立体声)。2.1 TOC字节Opus封包务必包含至少一个字节。 该字节形成目录表头(Table-Of-Contents,TOC),,该字节协商数据包使用哪种模式和配置。 它由配置编号“ config”,立体声标志“ s”和帧计数Code “ c”组成,其排列如图1所示。

TOC字节的前五位(标记为“ config”)对32种可能的操作模式,音频带宽和帧大小配置之一进行编码。 如上所述,可以在三种可能的操作模式下组合LP(SILK)层和MDCT(CELT)层:1.仅用SILK模式:用于带宽小于或等于WB的低比特率连接,2.混合模式:以中等比特率进行SWB或FB语音的混合(SILK + CELT)模式,以及3.仅用CELT模式:用于非常低延迟的语音传输以及音乐传输(从NB到FB)。32种可能的配置分别标识数据包使用这些操作模式中的哪一种,以及音频带宽和帧大小。 表2列出了每种配置的参数。

每个范围中的配置编号(例如,对于NB SILK-仅0 ... 3)以相同的顺序依次对应帧大小内的各个值大小。 例如,配置0的帧大小为10 ms,配置3的帧大小为60 ms。标记为“ s”的另一位用信号表示单声道与立体声,其中0表示单声道,而1表示立体声。标记为“ c”的TOC字节的其余两位编码每个数据包的帧数(Code 0到3),如下所示:0:数据包中的1个帧1:数据包中的2个帧,每个数据帧具有相同的压缩大小2:数据包中的2个帧,每个数据帧具有不同的压缩大小3:数据包中任意数量的帧根据“ c”的值将数据包称为Code 0数据包,Code 1数据包等。2.2 帧打包方式本节介绍如何根据TOC字节中每个“ c”值打包帧。2.2.1 帧长编码当一个数据包包含多个VBR帧(即Code2或3)时,这些帧中一个或多个的压缩长度以一个或两个字节的序列表示,第一个字节的含义如下:0:无帧(不连续传输(DTX)或丢失的数据包)1 ... 251:帧的长度(以字节为单位)252 ... 255:第二个帧的字节长度。 总长度是(second_byte*4)+first_byte2.2.2 Code 0:单帧包对于Code 0的封包来说,TOC字节之后紧跟这一个帧的N-1个字节的压缩数据(其中N是数据包的大小),如下图所示:

2.2.3 Code 1:相同压缩数据大小的双帧包对于Code 1的封包来说,TOC字节之后紧跟着是第一帧的(N-1)/2个字节的压缩数据,然后是第二帧的(N-1)/2个字节的压缩数据。针对Code 1类型数据包,其压缩数据的有效载荷字节的数目N-1,必须是偶数。

2.2.4 Code 2:不同压缩数据大小的双帧包对于Code 2数据包,TOC字节之后紧跟着一个或两字节的序列,用于指明第一帧的长度(在图4中标记为N1),长度之后跟N1字节的第一帧压缩数据。 剩余的(N-N1-2) 或 (N-N1-3)字节是第二帧的压缩数据,如图4所示。Code 2包必须包含足够的字节来表示有效长度。 例如,一个1字节的Code 2数据包总是无效的,而第二个字节在252 ... 255范围内的2字节的Code 2数据包也是无效的。第一帧的长度N1,也必须是不大于解码所有Code 2数据包的长度后剩余的有效负载大小。 例如,这也会使第二字节在1 ... 251范围内的2字节Code 2数据包也无效(唯一有效的2字节Code 2数据包是两个帧的长度均为零的数据包)。

2.2.5 Code 3:包含确定帧数的数据包Code 3数据包通过增加称为“ Opus填充”的附加填充以明确制定当前数据包中的帧数,同时指示此填充是在Opus层而不是在传输层添加的。 Code 3的数据包必须至少有2个字节。 TOC字节后跟一个字节,该字节在第2到7位(图5中标记为“ M”)对数据包中的帧数进行编码,而第1位指示是否插入了Opus填充(图5中标记为“ p”) ),位0表示VBR信息(在图5中标记为“ v”)。 M的值绝对不能为零,并且数据包中包含的音频持续时间不得超过120ms。 这将任何帧大小的最大帧数限制为48(对于2.5 ms帧),同时限制最长帧的帧的大小。 图5说明了帧计数字节的布局。

使用Opus填充时,填充的字节数将被编码,紧跟在帧字节之后的字节中。从0 ... 254的值用于指示填充大小的字节为0 ... 254个填充字节,该字节标识总共的填充字节大小。如果值为255,则标识填充的大小为254个字节,再加上下一个字节中填充值。在这种情况下,数据包中必须至少有一个字节。额外的填充字节出现在数据包的末尾,必须由编码器设置为零,以避免创建隐蔽通道。但是,解码器必须接受填充字节的任何值。尽管此编码提供了多种方法来指示给定数量的填充字节,但是每种编码都使用不同数量的字节来指示填充大小,因此将在不同程度上增加总数据包的大小。例如,要向数据包中添加255个字节,请将填充位p设置为1,在帧计数字节后插入一个值为254的单个字节,然后将254个填充值为零的填充字节附加到包的末尾。要向数据包中添加256个字节,请将填充位设置为1,在帧计数字节后分别插入两个字节,其值分别为255和0,并在数据包末尾附加254个填充值为零的填充字节。通过多次使用值255,可以创建任何特定的所需大小的数据包。令P为用于指示填充大小的标头字节数加上其自身的填充字节数(即P为添加到数据包的总字节数)。然后,P必须不超过N-2。在CBR情况下,令R = N-2-P为减去(可选)填充后数据包中剩余的字节数。然后,每个帧的压缩长度(以字节为单位)等于R / M。值R必须是M [R6]的非负整数倍。随后是所有M帧的压缩数据,每个压缩数据的大小为R / M字节,如图6所示。

(0)

相关推荐