WebRTC基於TransportCC和Trendline Filter的發送端碼率估計(Sendside-BWE)

下文寫的十分不錯,改了一下格式,畫了一下重點

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

1引言

衆所周知,WebRTC的擁塞控制和碼率估計算法採用GCC算法[1]。該算法充分考慮了網絡丟包和網絡延遲對碼率估計的不同影響,分別基於丟包率和網絡延遲進行碼率估計,最後綜合這另種碼率得出最優值。在算法實現上,基於丟包率的碼率估計在發送端進行,基於網絡延遲的碼率估計在接收端進行。最後在發送端計算出最優值,作用於Codec和PacedSender模塊。GCC算法能夠較好地基於網絡實時狀況估計網絡帶寬,爲網絡實時通信應用打下堅實基礎[2][3][4]。

然而,隨着時間推移,在實際測試中發現GCC算法逐漸顯出一些弊端,比如不能適應所有網絡模型,應對網絡峯值能力差,等等。爲此,Google官方從M55版本引進最新的擁塞控制算法Sendside-BWE,把所有碼率計算模塊都移到發送端進行,並採用全新的Trendline濾波器取代之前的Kalman濾波器[5]。實測表明,新的算法實現能夠更好更快地進行碼率估計和網絡過載恢復。

本文基於WebRTC的M66版本和相關RFC,深度分析學習最新Sendside-BWE算法的實現。

2 GCC算法回顧

關於GCC算法已經有很多分析和論述[6][7],本文只回顧其算法框架,並分析其在實際應用中存在的問題。

圖1 GCC算法整體結構

GCC算法分兩部分:發送端基於丟包率的碼率控制和接收端基於延遲的碼率控制。

基於丟包率的碼率控制運行在發送端,依靠RTCP RR報文進行工作。WebRTC在發送端收到來自接收端的RTCP RR報文,根據其Report Block中攜帶的丟包率信息,動態調整發送端碼率As。

基於延遲的碼率控制運行在接收端,WebRTC根據數據包到達的時間延遲,通過到達時間濾波器,估算出網絡延遲m(t),然後經過過載檢測器判斷當前網絡的擁塞狀況,最後在碼率控制器根據規則計算出遠端估計最大碼率Ar。得到Ar之後,通過RTCP REMB報文返回發送端。發送端綜合As、Ar和預配置的上下限,計算出最終的目標碼率A,該碼率會作用到Encoder、RTP和PacedSender等模塊,控制發送端的碼率。

發送端基於丟包率的碼率估計計算公式:

圖2 GCC發送端基於丟包率的碼率估計

接收端基於延遲的碼率估計計算公式:

圖3 GCC接收端基於延遲的碼率估計

GCC算法充分考慮丟包率和延遲對碼率的影響,在實時通訊應用(如視頻會議)中能夠發揮良好效果。然而,在某些特定應用場景下(比如實時在線編輯),GCC算法的表現不太讓人滿意,主要體現在它應對峯值流量的能力上,具體表現在:1)算法一開始基於Increase狀態增加碼率,當檢測到Decrease狀態時調用Ar[t(i)] = Alpha * Rr[t(i)],這個時候實時碼率Rr(ti)可能遠小於Ar[t(i-1)],這樣在後續過程中Ar處於較低水平;此時若有視頻關鍵幀衝擊,則數據包大量在PacedSender的隊列中排隊,造成較大排隊延遲。2)基於1)中論述的情況,碼率估計模塊反饋給Codec的編碼碼率很低,但編碼器需要編碼關鍵幀時,內部的碼率控制模塊控制出的最小碼率仍然大於反饋碼率。這兩種情況都會造成較大的發送端排隊延遲,進而在接收端造成較大的JitterBuffer延遲,最終導致端到端延遲到達500ms的水平,這在實時在線編輯應用中是無法容忍的。

基於此,Google官方從WebRTC M55開始引入新的碼率估計算法,把所有碼率計算模塊都移動到發送端,並採用全新的Trendline濾波器,基於碼率探測機制快速準確地估計出實時碼率。

3 Sendside-BWE算法框架

從本節開始系統分析Sendside-BWE算法的框架和實現,圖4顯示該算法的基本實現框架,以及和GCC算法的對比。

圖4 Sendside-BWE算法和GCC算法的實現和對比[8]

圖4中棕色線是Sendside-BWE算法的數據控制流回路:

1)發送端在發送RTP數據包時,在RTP頭部擴展中設置傳輸層序列號TransportSequenceNumber;

2)數據包到達接收端後記錄該序列號和包到達時間,然後接收端基於此構造TransportCC報文返回到發送端;

3)發送端解析該報文,並執行Sendside-BWE算法,計算得到基於延遲的碼率Ar;

4) 最終Ar和基於丟包率的碼率As進行比較得到最終目標碼率,作用到PacedSender和Codec模塊,形成一個完整的反饋迴路。圖4中紅色線是GCC算法的數據控制流回路:

1)發送端在發送RTP數據包時,在RTP頭部擴展中設置絕對發送時間AbsSendTime;

2) 數據包到達接收端後記錄該絕對到達時間,然後基於此執行GCC算法得到Ar,最後構造REMB報文把Ar發送回發送端;

3) 發送端基於Ar和As得到最終目標碼率,作用到PacedSender和Codec模塊,形成一個完整的反饋迴路。

從中可以看出,Sendside-BWE算法充分複用GCC算法的框架和實現,整個反饋迴路基本類似:發送端在RTP頭部擴展中記錄碼率估計元數據,碼率估計模塊基於此元數據估計出碼率As,在發送端基於丟包率計算Ar,發送端綜合As和Ar得到最終目標碼率,並作用於Codec和PacedSender模塊。

所不同的是:對於GCC算法,RTP報文頭部添加AbsSendTime擴展,在接收端執行基於延遲的碼率估計,網絡延遲濾波器採用Kalman Filter,返回給發送端的是REMB報文;

對於Sendside-BWE算法,RTP報文頭部添加TransportSequenceNumber擴展,在發送端執行基於延遲的碼率估計,網絡延遲濾波器採用Trandline,返回給發送端的是TransportCC報文。表5總結出GCC算法和Sendside-BWE算法的異同。

表5 GCC和Sendside-BWE關鍵模塊異同

需要注意的是,從WebRTC M55開始啓用Sendside-BWE後,其GCC算法就只做前向兼容而沒有進一步的功能開發、性能優化和bug修正。因此,GCC是過去,Sendside-BWE是未來。

4 Sendside-BWE算法實現

本節論述Sendside-BWE算法的實現細節,在論述上力求不過度註釋代碼,以免陷入細節無法自拔。本節按照如下順序論述Sendside-BWE的實現細節:1) SDP協商,2)發送端發送RTP報文,3)接收端接受RTP報文及信息存儲,4)接收端構造TransportCC報文,5)發送端解析TransportCC報文,6)發送端碼率估計。

4.1 Sendside-BWE在SDP層協商

TransportCC和remb一樣都是Codec的feedback params的一部分。爲支持TransportCC,Codec在收集feedback params時需添加額外一條:

codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty));

其中,TransportCC在最終生成的SDP中體現爲如下一條attribute:

a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01

然後,SDP協商過程按照常規操作進行。

4.2 發送端發送RTP報文

發送端在發送RTP報文時,需要在RTP頭部添加新的擴展TransportSequenceNumber,該擴展格式如圖6所示。

圖6 TransportSequenceNumber擴展格式

注意這裏的傳輸層序列號,和RTP報文格式中的媒體層序列號不是同一個東西。傳輸層序列號關注數據的傳輸特性,主要作用是碼率估計;媒體曾序列號關注數據的媒體特性,主要作用是組幀和抗丟包。它們的初始值不一樣,賦值點也不一樣,其中媒體層序列號在RTPSender::AssignSequenceNumber()處賦值,而傳輸層序列號在RTPSender::UpdateTransportSequenceNumber()處賦值。RTP報文在發送時構造該頭部擴展的函數調用棧如下:

=> RTPSender::TimeToSendPacket();
 => RTPSender::PrepareAndSendPacket();
  => RTPSender::UpdateTransportSequenceNumber();
   => RTPSender::AddPacketToTransportFeedback();s
    => SendSideCongestionController::AddPacket();//它是webrtc add packet的對外接口,傳入之後開始走rtp發送到網絡

然後RTP報文走正常的構造發送路徑發送到網絡。

4.3 接收端接收RTP並構造TransportCC報文

接收端worker線程在收到RTP報文後,解析並檢查其頭部擴展,根據其是否有TransportSN擴展,決定採用Sendside-BWE還是GCC,注意這兩種擁塞控制器是互斥的。對於Sendside-BWE,接收端代理解析擴展拿到傳輸層序列號,並記錄RTP報文的到達時間,構造(transport-sn,arrival_time_ms)鍵值對,存儲在隊列中。整個過程的函數調用棧如下:

=> Call::DeliverRtp();
 => NotifyBweOfReceivedPacket();
 => RtpPacketReceived::GetHeader();
 => ReceiveSideCongestionController::OnReceivedPacket();
  => RemoteEstimatorProxy::IncomingPacket();
   => OnPacketArrival(transport-sn, arrival_time_ms):
      Packet_arrival_times_[seq] = arrival_time;

RemoteEstimatorProxy作爲Sendside-BWE在接收端的代理,其實現遵從WebRTC的模塊機制,在Process線程以100ms爲發送週期發送TransportCC報文[9],發送週期會根據當前碼率動態調整,其取值範圍在[50ms, 250ms]之間,其本身可用的發送碼率爲當前可用碼率的5%。TransportFeedback報文是一種RTP 傳輸層feedback報文(pt=205),FMT爲15。其格式如圖7所示:

圖7 TransportCC報文格式

TransportCC報文采用base + bitmap的思想,其各個字段的具體解釋請參考文獻[9],一個TransportCC報文能最多攜帶16個RTP報文的有效信息,每個RTP報文信息包括其傳輸層序列號和包到達時間。TransportCC報文在發送端構造和發送的函數調用棧如下:

=> RemoteEstimatorProxy::Process();
 => RemoteEstimatorProxy::BuildFeedbackPacket();
  => TransportFeedback::AddReceivedPacket()
   => PacketRouter::SendTransportFeedback(fbpacket);
    => RTCPSender::SendFeedbackPacket(fbpacket);

然後按照常規RTCP報文流程發送到發送端。

4.4 發送端接收TransportCC報文並解析

接收端接收操作就是常規的RTCP接收、解析並回調的流程,在worker線程中:

=> WebRtcVideoChannel::OnRtcpReceived();
 => Call::DeliverRtcp();
  => RTCPReceiver::HandleTransportFeedback();
   => RTCPReceiver::TriggerCallbacksFromRtcpPacket();
    => TransportFeedbackObserver::OnTransportFeedback();
     => SendSideCongestionController::OnTransportFeedback();//BWE算法:基於delay估算bitrate

然後就是Send-side BWE算法在發送端的核心實現。

4.5 SendSideCongestionController碼率估計

SendSideCongestionController是Sendside-BWE算法在發送端的核心實現,關於其的分析全部是細節描述。本節限於篇幅,僅勾勒出其大致的函數調用棧和流程說明。

 => SendSideCongestionController::OnTransportFeedback();
 => AcknowledBitrateEstimator::IncomingPacketFeedbackVector();
 => DelayBasedBwe::IncomingPacketFeedbackVector();
 => BitrateControllerImpl::OnDelayBasedBweResult();
 => SendSideCongestionController::MaybeTriggerOnNetworkChanged();
 => ProbeController::RequestProbe();

在SendSideCongestionController的OnTransportFeedback()函數中:

1) 首先調用ALR碼率估計器得到一個實時碼率,

2)然後以此爲參數調用DelayBasedBwe計算得到最新的估計碼率Ar,把Ar經過BitrateController對象和As綜合,得到最新的目標碼率.

3) 最後通過函數MaybeTriggerOnNetworkChanged()把最新目標碼率作用到Codec和PacedSender模塊。

4) 如果本次碼率估計從網絡過載中恢復,則調用ProbeController對象發起下一次碼率探測。

DelayBasedBwe對象是真正實現碼率估計的地方,其內部調用函數棧如下:

=> DelayBasedBwe::IncomingPacketFeedbackVector();
=> DelayBasedBwe::IncomingPacketFeedback();
 => InterArrival::ComputeDeltas();
 => TrendlineEstimator::Update();
=> DelayBasedBwe::MaybeUpdateEstimate();
 => ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrateBps();
 => AimdRateControl::SetEstimator();

DelayBasedBwe首先調用IncomingPacketFeedback針對每個RTP報文信息進行碼率估計,其內部邏輯和GCC算法的相關步驟一致,在此不再贅述。需要注意的是,其內部網絡延遲濾波器採用TrendlineEstimator。然後DelayBasedBwe調用MaybeUpdateEstimate()根據本次判定的網絡狀態計算得到最終的Ar,如GCC算法一樣。

Trendline濾波器的原理就是最小二乘法線性迴歸求得網絡延遲波動的斜率,每個散列點表示爲(arrival_time, smoothed_delay),其中arrival_time爲RTP包到達時間,smoothed_delay爲平滑後的發送接收相對延遲。最後根據當前散列點集合,採用最小二乘法線性迴歸計算得到本次估計的網絡延遲m(i)。其計算過程調用如下:

=> TrendlineEstimator::Update();
 => LinearFitSlope();
 => TrendlineEstimator::Detect();
  => TrendlineEstimator::UpdateThreshold();

至此,關於Sendside-BWE算法的實現初步分析完畢。

5 Sendside-BWE實測數據

實際測試表明,和GCC算法相比,Sendside-BWE算法在快速碼率估計、碼率估計準確性、抗網絡抖動等方面都具有非常大改善。由於保密原因,此處不能發佈內部測試數據,僅貼出一組公開渠道獲得的快速碼率估計比較圖[10]。

圖8 Sendside-BWE和GCC算法對比

該圖表明,Sendside-BWE算法能夠在第一次TransportCC報文返回時即估計出實時網絡帶寬,相比GCC算法更快速更準確。

6 總結

本文在總結對比GCC和Sendside-BWE算法基礎上,深入學習Sendside-BWE算法的框架和實現細節,爲進一步學習WebRTC擁塞控制算法和優化算法細節打下堅實基礎。
 

參考文獻

[1] A Google Congestion Control Algorithm for Real-Time Communication. draft-alvestrand-rmcat-congestion-03
[2] Understanding the Dynamic Behaviour of the Google Congestion Control for RTCWeb.
[3] Experimental Investigation of the Google Congestion Control for Real-Time Flows.
[4] Analysis and Design of the Google Congestion Control for Web Real-time Communication (WebRTC). MMSys’16, May 10-13, 2016, Klagenfurt, Austria
[5] WebRTC視頻接收緩衝區基於KalmanFilter的延遲模型.http://www.jianshu.com/p/bb34995c549a
[6] WebRTC基於GCC的擁塞控制(上) - 算法分析 https://www.jianshu.com/p/0f7ee0e0b3be
[7] WebRTC基於GCC的擁塞控制(下) - 實現分析 https://www.jianshu.com/p/5259a8659112
[8] WebRTC的擁塞控制和帶寬策略 https://mp.weixin.qq.com/s/Ej63-FTe5-2pkxyXoXBUTw
[9] RTP Extensions for Transport-wide Congestion Control
draft-holmer-rmcat-transport-wide-cc-extensions-01
[10] Bandwidth Estimation in WebRTC (and the new Sender Side BWE) http://www.rtcbits.com/2017/01/bandwidth-estimation-in-webrtc-and-new.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章