在前文中介紹了RTT計算原理及其應用。下面介紹網絡抖動Jitter原理、計算方法以及在Webrtc中的應用。
什么是抖動?在網絡傳輸中,每個包從發送端到接收端的時延都是不相同的,而Jitter就是用來衡量這種不同。一般在發送端,數據包發送時間間隔是相同的,也就是均勻發送數據,但是傳輸過程中由于各種情況,例如擁塞,丟包,網絡錯誤等,接收端收到的數據包間隔就會不一樣,可能一會大,一會小,導致時延發生變化,這個時延的變化程度就是所謂的抖動。網絡中存在抖動會導致接收端收包不均勻、甚至亂序,如果按照收包順序去播放,對于視頻而言,會導致幀率變化,視頻播放就不平滑,有卡頓感。對于音頻而言,肯定會有時快時慢、來不及播放導致卡頓、錯音等問題,在比較差的網絡場景中語音基本是沒法聽。接收端如果不做任何處理,就會影響用戶體驗。
WebRTC針對網絡抖動問題,根據音視頻分為:NetEQ與JitterBuffer2種,分別對音頻、視頻進行抖動處理,消除抖動造成的影響,這些會在我的后續文章介紹。
按照抖動的頻率,也可以分為:
穩定抖動:這種抖動是網絡和算法固有屬性導致的,有一定的統計上的穩定性,在一段時間內呈現統計上的穩定性;
突發抖動:這些抖動是在穩定抖動基礎上疊加上突發的抖動尖峰,突發通常沒有太大規律,無法找到統計上的規律性。
一般的Jitter算法都是盡力去解決穩定抖動,對于突發抖動解決的并不是太好。
如下圖片是抖動的一個形象描述。
圖1 -Jitter
如何計算抖動?假設RTP中第i包中記錄的時間戳為Si(單位為采樣率),到達接收端的時間為Ri(單位同樣為采樣率),如果Si代表第i個包的發送時間戳,Ri代表第i個包的接收時間戳。Sj、Rj同理。
圖2 - Jitter計算原理圖
抖動(i, j) = |(Rj - Ri) - (Sj - Si)| = |(Rj - Sj) - (Ri - Si)| (1)
WebRTC為了統一抖動,并且為了很好地降噪、降低突發抖動的影響,把上面的抖動(i, j)定義為D(i, j),抖動J(i)定義為:
J(i) = J(i-1) + (|D(i-1, i)| - J(i - 1)) / 16 (2)
增益參數1/16是為了消除噪聲影響,使抖動收斂在較合理范圍內,避免突發數據的影響。從上一個公式中可以看到D(i-1, j)是唯一引起J(i)變化的因素。
WebRTC統計參數中的抖動計算代碼位于
StreamStatisticianImpl::UpdateJitter中
圖3 - 代碼
time_diff_samples =|D(i−1,i)| (3)
J(i) = J(i-1) + (time_diff_samples - J(i - 1)) / 16 (4)
圖4 - 代碼
至此我們得到了jitter_diff_q4,單位為采樣率,如果需要轉換為毫秒時間單位。由于jitter_diff_q4放大了16倍,首先需要還原回去jitter = jitter_q4_ >> 4;轉換為毫秒單位:jitter_ms = jitter / (clockrate_hz / 1000)(一般視頻的時鐘采樣頻率clockrate_hz為:90kHz)。jitter_ms就是得到的毫秒級別的抖動。