1. 程式人生 > >【原創】WebRTC的擁塞控制技術(Congestion Control)

【原創】WebRTC的擁塞控制技術(Congestion Control)

本文為個人原創,歡迎轉載,但請務必在明顯位置註明出處!

1. 概述

對於共享網路資源的各類應用來說,擁塞控制技術的使用有利於提高頻寬利用率,同時也使得終端使用者在使用網路時能夠獲得更好的體驗。在協議層面上擁塞控制是TCP的一個總要的組成部分;但是對於非面向連結的傳輸層協議,如UDP,其在協議層面上並沒有對擁塞控制進行強制性的要求,這樣做保證了最優的傳輸效能,且在擁塞控制的設計上也保留了更大的靈活性。

WebRTC為我們提供了強大的音視訊媒體引擎,前端開發者可以通過呼叫幾個簡單的js介面就能實現基於Web瀏覽器的實時音視訊通訊。而在媒體資料傳輸上,WebRTC採用了實時性較強UDP協議,並使用了RTP/RTCP技術。本文的主要內容就是介紹WebRTC中基於RTP/RTCP實現的擁塞控制技術。

2. 擁塞控制演算法

WebRTC採用了兩種擁塞控制演算法:(1)基於延遲(delay-based)的擁塞控制演算法;(2)基於丟包(loss-based)的擁塞控制演算法。演算法(1)由資料的接收方實現,接收方需要記錄每個資料包到達的時間和大小,並計算每個資料分組之間(inter-group)的延遲的變化,由此判斷當前網路的擁塞情況,並最終輸出位元速率估計值由RTCP feedback(TMMBR或 REMB)反饋給傳送方;演算法(2)則由資料的傳送方來實現,傳送方通過從接收方週期性發來的RTCP RR(Receiver Report)中獲取丟包資訊以及計算RTT,並結合TMMBR或REMB中攜帶的位元速率資訊算得最終的位元速率值,然後由媒體引擎根據位元速率來配置編碼器,從而實現位元速率的自適應調整。從上面的描述可以看出,這兩個演算法在系統中並不是孤立存在的。


擁塞控制演算法時序圖.png

2.1 基於延遲(delay-based)的擁塞控制演算法

基於延遲的擁塞控制演算法可以分成以下4個部分:(1)到達時間模型(arrive-time model);(2)預過濾(Pre-filtering);(3)到達時間濾波器(arrive-time filter);(4)過載檢測器(over-use detector)。


基於延遲的擁塞控制演算法.png

2.1.1 到達時間模型(arrive-time model)

設相鄰兩個資料分組到達接收方的時間間隔為t(i) - t(i-1),而兩者被髮送的時間間隔則為T(i) - T(i-1),那麼就有延遲變數d(i)=t(i)-t(i-1) - (T(i)-T(i-1))

。如果d(i) > 0,就說明資料在網路傳輸時存在延遲的現象。

在WebRTC中延遲變數d(i) = w(i)被視為隨機過程W中一個取樣點,並且是鏈路承載能力、網路當前傳輸狀況以及當前傳送速率等因素綜合作用的結果。該隨機過程W符合正態分佈。當網路發生過載(over-use)時,我們期望w(i)會上升;當網路空閒(Under-use)時,則期望w(i)會下降。

測量方程進一步改寫為 d(i) = m(i) + v(i),其中m(i)符合均值為0的正態分佈(標準正態分佈),v(i)表示為網路抖動等因素帶來的對資料延遲的影響。

2.1.2 預過濾(Pre-filtering)

預過濾的目的是處理由於通道中斷造成的延遲瞬間變大的情況。在通道發生中斷時,資料包會持續進入網路佇列中,而當通道恢復時,所有的資料包會在一個burst時間(5 ms)裡面全部發送,而這些資料包可能原先包分佈於多個數據分組。而預過濾所要做的就是將這些在同一個burst時間裡傳送的資料包合為一個數據分組。

這裡涉及到了WebRTC中關於資料傳輸的一個設計--PacedSender。Encoded資料完成RTP封裝之後先是被儲存在本地應用的佇列中,而不是直接傳送到網路。此時可以將PacedSender視為一個數據傳送的節拍器,它每隔一個burst時間啟動一次,啟動之後會將佇列中的RTP包全數發出。

資料包會在下面兩種情況下被劃分到一個數據分組:

  • 在同一個burst時間區間內被髮送的資料包序列;
  • 一個數據包與相鄰資料包的到達時間間隔小於一個burst時間,同時d(i) < 0,那麼這個資料包將會被劃到當前的分組中。

2.1.3 到達時間濾波器(arrive-time filter)

在此係統希望通過預測m(i)來檢測當前的網路是否過載;而這裡所採用的預測方法是卡爾曼濾波(Kalman filter)
狀態方程:m(i+1) = m(i) + u(i), 其中u(i)表示為狀態噪聲,符合0均值正態分佈。
測量方程:d(i) = m(i) + v(i), 其中v(i)表示為測量噪聲,符合0均值正態分佈。
卡爾曼濾波器根據“5組公式”來迭代更新m(i) 的估計值m_hat(i),該估計值m_hat(i)則是下文過載檢測器的檢測依據。關於卡爾曼濾波器如何實現預測的詳細介紹在這裡就不做展開了,可參考文獻[3]

2.1.4 過載檢測器(over-use detector)

通過Kalman 濾波器能夠獲得延遲變數m(i)的估計值,而過載檢測器的工作原理其實就是通過m(i)與閾值del_var_th進行比較來對當前的網路擁塞狀況進行檢測。如果m(i) > del_var_th且m(i) > m(i-1),同時該狀態至少持續了overuse_time_th毫秒,則判斷為網路過載(Over-use);如果m(i) < -del_var_th,則判斷為網路空閒(Under-use);剩餘的情況都被判斷為Normal狀態。

由此可見,閾值del_var_th的設計對於整個演算法的效能來說至關重要。如果del_var_th的值設得過大,那麼整個演算法的動態就會顯得過於平滑,此時只有在資料分組嚴重delay時檢測器才會觸發over-use的訊號;相反的,如果del_var_th的值設得過小,那麼檢測器就會對delay非常敏感,從而導致頻繁觸發over-use訊號。因此,WebRTC提出了針對閾值del_var_th的動態調整演算法:

del_vat_th(i) = del_var_th(i-1)+ (t(i) - t(i-1)) * K(i) * (|m(i)| - del_var_th(i-1))

其中,當|m(i)| < del_var_th(i-1)時K(i)=K_d;否則,K(i)=K_u。

在WebRTC中本小節所涉及的各引數的參考值如下:
del_var_th(0) = 12.5 ms, overuse_time_th = 10 ms, K_u=0.01, K_d=0.00018

2.1.5 速率控制(rate control)

速率控制子系統根據當前網路的擁塞情況(由過載檢測器提供),計算頻寬估計值並請求傳送方對速率進行調整。該子系統通過有限狀態機對速率進行自適應調整。其狀態遷移如下圖所示:


速率控制狀態機.png
  • 狀態 Increase: 表明當前沒有檢測到網路擁塞,在此狀態下傳輸速率需要逐步增加;它先是通過乘性增加來調整速率(乘性因子為1.08),當速率接近臨界值時再通過加性增加逐步收斂,而這裡所謂的臨界值是指上一次在狀態Decrease 時統計的下行位元速率;
  • 狀態 Decrease: 表明當前檢測到了網路擁塞,在此狀態下傳輸速率需要逐步下降;在這裡,WebRTC所採用的方法是乘性下降,其乘性因子為0.85;
  • 狀態 Hold: 表明保持當前的速率不做改變。

速率控制子系統最終會輸出一個頻寬估計值A_hat,並通過RTCP Feedback(TMMBR/REMB)請求傳送方進行速率調整。

2.2 基於丟包(Loss-based)的擁塞控制演算法

基於丟包的擁塞控制是通過對丟包率,RTT和頻寬估計值A_hat這三個引數進行決策而實現的。其中頻寬估計值A_hat正是由上節中的速率控制子系統所提供。

基於丟包的擁塞控制在每次收到對方傳送RTCP之後都會執行:

  • 當丟包率保持在[2%, 10%]時,當前資料傳送方的頻寬估計值As_hat保持不變;
  • 當丟包率大於10%時,頻寬估計值將會降低:As_hat(i) = As(i-1)*(1-p),其中p為丟包率;
  • 當丟包率小於2%時,頻寬估計值將會上升:As_hat(i) = As(i-1)*1.05。

As_hat更新之後將與A_hat進行比較,然後取兩者中的較小值作為最終的帶頻寬估計值。

其實在原生的程式碼中,系統還會將丟包率和RTT作為引數,通過TFRC [RFC 5348]的吞吐率計算公式對當前的頻寬進行估計,而最終的估計值則是取三者中的最小值。

3. 後語

通過上文的介紹,我們知道WebRTC中的擁塞控制演算法還是非常完備的。其分別針對資料包的延遲和丟包設計了delay-based和loss-based擁塞控制演算法,在兩者的共同作用之下,WebRTC能夠滿足大部分場景下的實時視訊通話業務。但是,如果有要對WebRTC中的媒體引擎進行移植的朋友,首先要分析一下WebRTC的擁塞控制演算法是否滿足你的業務需求:如果是開發獨立應用,由於業務閉環,直接使用現有的演算法應該問題不大;但是,如果是用於開發提供類似VoLTE/VoWIFI這樣的運營商增值服務的應用,需要依據運營商的技術手冊和3GGP協議等來對擁塞控制演算法進行適配。

Reference
[1] A Google Congestion Control Algorithm for Real-Time Communication draft-ietf-rmcat-gcc-02
[2] RFC 5348
[3] http://blog.csdn.net/xiahouzuoxin/article/details/39582483
[4] 3GPP TS 26.114