个人总结,如有错误,还请指正。
1.什么是Jitter?
Jitter是一个统计变量,它用来表征RTP数据包与包的传输时间之间的差异程度。具体的推算公式如下:
J(i) = J(i-1) + (|D(i-1,i)| - J(i-1))/16
i时刻的jitter是由i-1时刻的jitter推出的。其中D(i-1,i)
表达式如下:
D(i,j) = (Rj - Ri) - (Sj - Si) = (Rj - Sj) - (Ri - Si)
Si表示i包里的RTP timestamp,Ri表示i包到达目的端时的timestamp。
1.1 Jitter的单位
jitter的单位是RTP中timestamp的单位。RTP timestamp单位和RTP data的采样频率有关,比如采用PCMU编码的audio包采样频率是8000Hz,那timestamp单位就是1/8000 s;采用OPUS编码的audio包采样频率是48000Hz,那timestamp单位就是1/48000 s。
whireshark抓包测试:
1>PCMU:
如图相隔1s的两个包,timestamp相减1441520544 - 1441512544
结果等于8000
,即PCMU采样频率;
2>OPUS:
相隔1s的两个包,timestamp相减879484868 - 879436868
结果等于48000
,即OPUS采样频率。
1.2 RTCP中的Jitter
RTP接收端根据上面的公式推算出jitter值后,会通过RTCP发送给对端。以Receiver Report为例,jitter在RTCP中的存放位置如下:
1.3 Jitter计算实例
让我们以一个jitter的计算实例来加深对jitter的理解。我们假设发送端每隔20ms发送一个RTP包,并且理想的传输时间是10ms。为了便于理解,我们使用ms为jitter的计算单位(timestamp单位和时间单位可以换算)。RTCP规定timestamp的起始值是一个随机值,同样为了便于理解,我们起始值设为0。具体计算如下表:
I | Si | Ri | D(i, i-1) | J(i) |
---|---|---|---|---|
1 | 0 | 10 | 0 | 0 |
2 | 20 | 30 | 0 | 0 |
3 | 40 | 49 | -1 | 0.0625 |
4 | 60 | 74 | 5 | 0.3711 |
5 | 80 | 90 | -4 | 0.5979 |
6 | 100 | 111 | 1 | 0.6230 |
7 | 120 | 139 | 8 | 1.0841 |
8 | 140 | 150 | -9 | 1.5788 |
9 | 160 | 170 | 0 | 1.4802 |
10 | 180 | 191 | 1 | 1.4501 |
11 | 200 | 210 | -1 | 1.4220 |
12 | 220 | 229 | -1 | 1.3956 |
13 | 240 | 250 | 1 | 1.3709 |
14 | 260 | 271 | 1 | 1.3477 |
从表中可以看出,当包与包的传输时间之间的差异变大时,jitter值也开始增长。同时,jitter并没有随着差异的急速变大而剧烈变化,这是由于有去噪增益1/16。当差异逐渐缩小趋于稳定时,jitter的推算值也趋近于一个预估的均值。
2. Jitter Buffer
因网络状况总是千变万化的,那么包在网络上传输的时间也就不断变化。对于RTC audio的应用场景,为了得到良好的音频效果,我们需要以一个固定的时间间隔来播放音频包。因此,在接收端,无论网络延时怎么变化,我们都需要将变化的延时转化成固定的延时。而这,可以通过jitter buffer来实现。
jitter buffer的实现很简单:我们可以创建一个buffer来存储100ms时长的audio包。假设audio的采样频率是8000Hz,那么100ms就对应800个sample。我们可以设定如果buffer的sample数达到总的一半了,就可以去取出来播放了。
当然,这样做并不能确保播放质量。因为有可能网络实在是太差了,我们想要去取下一个audio包,但是buffer已经空了;也可能buffer已经满了,但是又接收到了audio包(只能丢弃)。为了减少这种风险,我们可以增加buffer的大小,但这样同时也增加了音频的滞后:因为如果buffer里满了50ms的audio包才取出来播放,那audio音频其实滞后了50ms。能不能再改进呢?能。我们可以使用根据jitter值自适应调整大小的buffer。这样既能适应网络状况变换,又能兼顾音频滞后的负面影响。
3. Jitter的起因
除了因为网络状况导致的传输时间变化,jitter还可能是由发送端自身导致的。当发送端的audio包不是从系统声卡采集的,而是从其他应用软件或某个音频文件采集的,那么也可能造成较大的jitter。
参考资料:
1.https://tools.ietf.org/html/rfc3550
2.http://toncar.cz/Tutorials/VoIP/VoIP_Basics_Jitter.html