網易乾貨 | 淺析視頻Jitter Buffer

1、 什麼是JitterBuffer

Jitter Buffer也叫作抖動緩衝區,它是實時音視頻裏面的一個重要模塊,它對數據包丟失、亂序、延遲到達等狀況進行處理,平滑的向解碼模塊輸出數據包/幀,抵抗各類弱網狀況對播放/渲染形成的影響,下降卡頓,提升用戶的觀看體驗。

2、JitterBuffer在音視頻系統中的位置

JitterBuffer在實時音視頻系統中的位置以下所示:

3、 視頻JitterBuffer的工做原理

1. JitterBuffer的核心思想
Jitter buffer的核心思想是用時間換空間,以增大端到端的延遲爲代價來換取視頻通話的流暢性。當網絡不穩定時(抖動發生),增長buffer的長度,多緩存一些數據,以應對未來可能發生的抖動;當網絡穩定下來時,減少buffer的長度,少緩存一些數據,下降視頻端到端的延遲,提升實時性。所以jitter buffer的運行過程是一個根據抖動來動態調整buffer長度的過程。好的jitter buffer可以在保證儘可能不卡的前提降低低端到端的延遲,即它可以在延遲和卡頓率之間取得較好的平衡。
2. 產生抖動的緣由
1) 網絡傳輸路徑改變。例如,當前的傳輸路徑是A,可是下一刻路徑A上的某個路由器出現了故障,這時候數據包的路徑就會發生改變,致使端到端的傳輸時長髮生變化。
2) 網絡自身的抖動。不少狀況下網絡有噪聲,產生抖動是很正常的。
3) 網絡發生擁塞。擁塞發生的時候,數據包會在路由器上排隊,致使端到端延遲變大。
4) 抗丟包手段帶來的額外抖動。網絡出現丟包的時候,咱們通常會使用nack/arq去重傳數據,重傳會帶來額外的延遲。
3. 計算抖動的方法
數據包傳輸時長的變化就是抖動,假設相鄰的兩個數據包packet1和packet2,它們發送時間戳是send_timestamp1和send_ timestamp2,接收時間戳是recv_ timestamp1和recv_ timestamp2,那麼它們之間的抖動能夠按照下面的方法計算:
這是最簡單的計算方法,要想準確計算出網絡抖動還須要考慮不少因素,這裏再也不贅述。
4. JitterBuffer的工做原理
1) 接收側收到數據包,開始組幀,這一步是必須的,幀不完整會致使花屏。
2) 每一個幀組好以後,放進buffer裏,而後按照幀序號進行排序。
3) 檢查幀的參考關係。對於解碼器來講,若是一個幀的參考幀丟失了,那麼這個幀將解碼失敗或者花屏,因此參考關係必需要知足以後才能把數據送進解碼器裏。
4) 根據每一幀的時間戳(採集時間戳或者發送時間戳)以及接收時間戳計算抖動。這裏的難點在於如何精確計算抖動。
5) 根據抖動計算buffer的長度。
6) 根據抖動自適應的調整buffer長度。抖動越大,預留的buffer長度越大,這樣能夠利用增長延遲的方式來下降卡頓;抖動越小,預留的buffer長度越小,這樣能夠下降延遲。

4、淺析webrtc裏的視頻JitterBuffer

1.WebRTC裏視頻JitterBuffer的運行機制
Jitterbuffer被兩個線程操做,寫線程負責組幀完成以後把數據寫入JitterBuffer裏,讀線程負責從JitterBuffer裏讀取數據而後解碼。
寫線程:
1) 判斷當前視頻幀是否有效,把幀插入buffer裏,而後移除buffer裏過時的、無效的幀;
2) 判斷幀之間的參考關係是否已經知足;
3) 若是當前幀能夠解碼,那麼激活解碼線程(讀線程)。
讀線程:
1) 找到buffer中第一個能夠解碼的幀(假設它是frame):若是這個幀的渲染時間戳是無效的,那麼根據當前的抖動(開始的時候抖動值是0,它在步驟3中被更新)計算每一個幀的渲染時間戳(render timestamp),並保存在幀信息中,而後根據這個幀的渲染時間戳和當前時間計算最大須要等待的時間(最大的等待時間不會超過200毫秒),而後休眠等待;
2) 若是在等待的時間內還有新的能夠解碼的幀到來,那麼重複步驟2,直到超時;
3) 根據frame的時間信息以及幀大小計算新的抖動值,並用這個抖動更新當前的抖動。
2. 計算抖動延遲
抖動延遲由網絡抖動延遲、解碼延遲、渲染延遲構成。其中,解碼延遲和渲染延遲比較穩定,網絡抖動延遲是動態變化的。計算網絡抖動是Jitterbuffer的核心之一。webrtc認爲網絡抖動由兩個部分構成:
1) 網絡噪聲帶來的抖動延遲,也叫作網絡排隊延遲
2) 傳輸大的視頻幀(特別是關鍵幀)對網絡形成衝擊帶來的抖動延遲
爲了準確估算出抖動延遲,必需要估算出網絡排隊延遲和信道速率(經過信道速率能夠計算大的視頻幀對網絡形成的衝擊所帶來的延遲) 。webrtc使用卡爾曼濾波估算網絡排隊延遲和信道速率。卡爾曼濾波是一種預測的算法,它以協方差爲標準,根據上一時刻的系統狀態估算當前時刻系統的狀態,而後根據當前的測量值調整當前時刻系統的狀態,最後獲得當前最優的系統狀態。它認爲估算出來的值和測量出來值都是有誤差的,所以要根據一個偏好因子(卡爾曼濾波增益係數)來判斷咱們最後須要的值更加偏向於估計值仍是測量值。因爲卡爾曼濾波比較複雜,這裏並不打算深刻探討,下面介紹一下使用卡爾曼濾波計算網絡抖動延遲的大體流程:
1) 抖動的計算與信道速率、網絡排隊延遲有關,所以要計算抖動,就必須先計算信道速度和網絡排隊延遲
2) 把信道速率和網絡排隊延遲看成系統狀態,算法的目標就是估算出最優的信道速度和網絡排隊延遲。假設系統是一個線性系統,若是網絡很是好,那麼很容易估算出當前系統的狀態等於上一個時刻的系統狀態,也就是說信道速度和網絡排隊延遲保持不變
3) 可是實際上網絡是動態變化的,所以須要對估算出的這個系統狀態(即信道速度和網絡排隊延遲)進行調整
4) 調整的具體方式:
a) 根據抖動延遲的觀測值(兩幀傳輸時長的變化值)和預測值(根據上一個系統狀態推導出來),計算它們的殘差;
b) 利用殘差計算網絡噪聲;
c) 根據抖動延遲觀測值、先後兩幀大小差值、網絡噪聲、系統偏差協方差等計算卡爾曼增益係數
d) 利用卡爾曼增益係數更新系統狀態(即信道速率和網絡排隊延遲)
5) 根據更新後的系統狀態計算抖動延遲:
3. 根據抖動延遲計算視頻幀的渲染時間
獲得網絡抖動延遲以後,計算總的抖動延遲:jitter_delay = net_jitter_delay + decode_delay + render_delay。而後根據抖動延遲和當前的時間,計算何時渲染當前的視頻幀,而後根據渲染時間和當前時間肯定當前幀在解碼以前須要等待的時間(wait_time),經過wait_time保證了各個視頻之間是平滑的,減小了卡頓。另外在等待的時間內也能夠緩存更多的視頻幀,避免了下一次遇到弱網時再次卡頓。

5、視頻JitterBuffer在雲信NRTC中的應用

NRTC是網易雲信自研的實時音視頻通訊系統,NRTC的Jitterbuffer在計算網絡抖動的基礎上考慮了丟包帶來的影響。通常的抗丟包手段有FEC和NACK,兩種方法各有優劣,FEC延遲比較低,可是浪費帶寬,NACK能夠節省帶寬,可是會帶來延遲。NRTC使用FEC+NACK做爲抗丟包手段,當遇到突發丟包時,使用NACK請求發送方重發丟失的包,若是丟包持續,那麼使用FEC增長冗餘防止丟包。根據前面的分析咱們知道,NACK做爲抗丟包手段是會引入額外延遲的,這個延遲不是網絡自身的抖動,若是Jitterbuffer不把NACK帶來的延遲考慮進去,那麼很容易致使卡頓,下降用戶的主觀體驗,所以NRTC的Jitterbuffer把網絡抖動和NACK帶來的延遲綜合考慮,經過實時監測網絡變化,在低延遲和流暢性上取得了比較好的平衡。

6、參考

相關文章
相關標籤/搜索