webRTC中音频相关的netEQ(四):控制命令决策 webRTC中音频相关的netEQ(三):存取包和延时计算 webRTC中音频相关的netEQ(三):存取包和延时计算

上篇(webRTC中音频相关的netEQ(三):存取包和延时计算)讲了语音包的存取以及网络延时和抖动缓冲延时的计算,MCU也收到了DSP模块发来的反馈报告。本文讲MCU模块如何根据网络延时、抖动缓冲延时和反馈报告等决定发给DSP模块的控制命令, 好让DSP模块先对取出的语音包作解码处理(若是有的话)以及根据这些命令作信号处理。html

 

MCU模块给DSP模块发的控制命令主要有正常播放(normal)、加速播放(accelerate)、减速播放(preemptive expand)、丢包补偿(PLC,代码中叫expand)、融合(merge),还有些次要的,如解码器从新初始化(decoder re-init)、packet buffer 重置(packet buffer reset)等。这里讲主要的控制命令是怎么决策的,次要的相对简单就略去不讲了,有兴趣的能够本身去看相关代码。DSP模块收到这些命令后会转化为本身的处理命令,下表列出了主要的控制命令和处理命令的映射关系。web

 

MCU模块给DSP模块发什么样的控制命令首先取决于当前帧和前一帧的接收状况。当前帧和前一帧的接收状况主要分如下四种(对当前帧和前一帧作排列组合获得四种状况):网络

1,当前帧和前一帧都接收正常,数据包会进入正常的解码流程。MCU模块会发正常播放、加速播放、减速播放三种控制命令中的一个给DSP,解码后的数据会根据命令作相应的处理。post

2,当前帧接收正常,但前一帧丢失。若是前一帧丢失,但当前帧接收正常,说明前一帧是经过丢包补偿生成的。为了使前一帧由丢包补偿生成的数据和当前没有丢包的帧的数据保持语音连续,须要根据先后帧的相关性作平滑处理。这种状况下MCU模块会发正常播放、融合两种控制命令中的一个给DSP。DSP模块先对当前帧解码,而后解码后的数据会根据命令作相应的处理。url

3,仅当前帧发生丢包或延迟,这时就不须要解码了。MCU模块会发丢包补偿命令给DSP,DSP模块会进入丢包补偿单元来生成补偿数据。spa

4,当前帧丢失或延迟,前一帧一样丢失或延迟。MCU模块会连续的发丢包补偿命令给DSP,DSP模块也会连续的进入丢包补偿单元来生成补偿数据。不过越到后面生成的补偿数据效果越差。code

 

在上面的四种状况中,有些状况下MCU模块只会发一种命令给DSP模块,好比当前帧丢失,只会发丢包补偿控制命令给DSP。但有些状况下MCU模块可能会发几种命令中的一种给DSP模块,好比当前帧和前一帧都接收正常,MCU模块会发正常播放、加速播放、减速播放三种控制命令中的一个给DSP。到底发哪一种命令呢,这就取决于网络延时、抖动缓冲延时以及DSP发给MCU的反馈报告等因素了。这是本文的重点,下面具体讲。orm

 

在DSP发给MCU的反馈报告中有个变量playedOutTS,它表示已经播放到的PCM数据的时间戳。同时MCU中还有个变量availableTS,它表示packet buffer中能得到的有效包的起始时间戳,显然若是availableTS等于0表示packet buffer为空。若是playedOutTS等于availableTS,它说明语音包正常接收;若是playedOutTS小于availableTS,它说明有语音包的丢失或者延时,须要作丢包补偿(PLC)。上篇文章(webRTC中音频相关的netEQ(三):存取包和延时计算)中讲了网络延时值(optBufLevel)和抖动缓冲延时值(buffLevelFilt)的计算,MCU就是要根据时间戳(playedOutTS & availableTS)的关系和延时(optBufLevel & buffLevelFilt)的关系以及上一帧的播放模式等来决定发什么样的控制命令给DSP。先举个简单的例子,若是playedOutTS = availableTS而且buffLevelFilt > optBufLevel,这说明当前包正常接收,可是抖动缓冲延时大于网络延时,即缓冲的包多了增长了时延,须要作加速播放处理,因此MCU会发加速处理命令给DSP。下面给出各个控制命令的条件,即知足所列条件时MCU就会发相应的控制命令给DSP。htm

 

1,正常播放控制命令 / 加速播放控制命令 / 减速播放控制命令的条件blog

正常播放控制命令为BUFSTATS_DO_NORMAL。加速播放控制命令为BUFSTATS_DO_ACCELERATE,加速播放的缘由是要播放的数据正常到达,可是抖动缓冲延时大于网络延时,增长了时延,所以要加速播放。减速播放控制命令为BUFSTATS_DO_PREEMPTIVE_EXPAND,又称为优先扩展控制命令。减速播放的缘由是要播放的数据正常到达,可是抖动缓冲延时小于网络延时,会引发播放时声音的断续,下降音质,所以要减速播放,拉长时间,使不会出现断续。这三种控制命令都有一个必要条件,那就是playedOutTS = availableTS, 因此把这三种控制命令放在一块儿讲。在“playedOutTS = availableTS”条件下,只有三种控制命令可供选择,要么正常播放,要么加速播放,要么减速播放。把加速播放和减速播放的条件搞清楚了,剩下的就是正常播放条件了。下图更直观的说明了正常播放、加速播放和减速播放的关系,去掉加速和减速的就是正常播放的了。

先看加速播放的条件。它的第二个条件是上一帧播放模式不为丢包补偿(第一个条件为playedOutTS = availableTS),第三个条件是下列两个之一:

1) 加速播放第三个条件之一

其中sample_rate为采样率,如8000/16000。samples_per_packet为每一个包的采样点数,以16KHZ/每包20ms为例,samples_per_packet就为320。 timescaleHoldOff初始化为32,且每发生一次加速或减速播放就右移一位。此参数是为了防止连续的加速或减速播放恶化人耳的听觉感觉。

2)加速播放第三个条件之二

 

再看减速播放的条件。它的第一个条件与第二个条件与加速播放同样,第三个条件以下:

说实话我没有彻底理解上面三个加减速的数学表达式的判据,尤为是系数值的选取。我知道不能简单的认为“buffLevelFilt > optBufLevel"就加速“buffLevelFilt < optBufLevel"就减速,要真的这么判断的话效果确定是很差的。若是哪位朋友理解了,麻烦给讲讲,先谢谢了!

除加减速播放这些条件外,剩下的就是正常播放了。能够写成以下的伪代码:

If(playedOutTS == availableTS)

{

    If(上一帧播放模式不为丢包补偿)

    {

        If(加速播放第三个条件是下列之一 || 加速播放第三个条件是下列之二)

            return 加速播放;

        If(减速播放第三个条件)

            return 减速播放;

    }

    return 正常播放;

}

 

2,丢包隐藏控制命令的条件

丢包隐藏控制命令为BUFSTATS_DO_EXPAND,又称为扩展控制命令。丢包隐藏的缘由是要播放的包已丢失或者还没到(延时)。发生丢包隐藏的场景有:

1)availableTS = 0,即packet buffer为空,显然这时须要作丢包补偿。

2)playedOutTS < availableTS,即要播放的包丢失或者延时到,可是packet buffer里有缓冲包,须要知足下面两个条件之一便可:

a)  上一帧播放模式不为丢包补偿

b)  上一帧播放模式为丢包补偿,且前面几帧均为丢包补偿,这是连续丢包的场景,这时要看连续丢包补偿的次数。netEQ设定最多能够补偿100ms的数据,以每包20ms为例,最多能够补偿5个包,其实100ms后的补偿效果也很差了。因此连续丢包补偿的次数小于5的话,还会继续丢包补偿,不然就不作丢包补偿了。

 

3,融合控制命令的条件

融合控制命令为BUFSTATS_DO_MERGE,主要用于丢包隐藏后产生的PCM数据与从packet buffer里取出的数据的衔接过程。因此产生融合控制命令的条件是:

1)playedOutTS < availableTS (此式也表示packet buffer不为空,为空时availableTS = 0)

2)上一帧的处理模式为丢包补偿

 

以上就是主要的控制命令的条件。可能不一样版本之间可能有差别,我是根据我用的版原本讲的。就像上面我说的,有些我也没有彻底理解,只是把它照本宣科的讲出来。苦于没有文档呀,网上也没有相关的论述,目前只能先这样了,后面若是彻底理解了再补充。

相关文章
相关标签/搜索