WebRTC的丟包計算方法

背景

      目前WebRTC的版本主要還是基於GCC的擁塞控制,發送端需要根據丟包率控制發送碼率,而丟包率是在接收端計算並通過RR(Receiver Report RTCP)包通知發送端。

版本

      66

問題

      重傳包可能會影響丟包率,如果發送端重傳的包都被接收端收到,並且接收端沒有區分重傳包,那麼丟包率會是0,與實際的網絡狀態不符,發送端也無從控制發送碼率。

丟包與NACK、RTX的關係

      在使能RTX的情況下,發送端的重傳包會使用新的SSRC通過RTX發送,這些包並不會被計入正常的接收包,這樣接收端丟包率的計算是天然正確的。
      在沒有使能RTX的情況下,發送端的重傳包就在原來的SSRC上簡單重傳,接收端沒有辦法通過什麼特殊標識區分是否是重傳包,而是以接收到包的時間戳以及估算的RTT來判斷是否是重傳包。

判斷當前包是否重傳包的算法

      t1=上一個未亂序的包到當前包時間戳的時間間隔
      t2=上一個未亂序的包到當前時間的時間間隔
      如果t2 > t1 + f(rtt)則認爲當前包是重傳包,f(rtt)是rtt的線性函數,目前f(rtt)=rtt/3+1。
      直觀解釋就是,當前包的時間戳已經是過去的時間,其加上f(rtt)後仍然是過去的時間,說明可能是接收端通過NACK通知發送端發送的重傳包(可能經過了一個rtt),可以認爲是重傳包。

丟包的計算

   1. 接收端維護兩個計數器,每收到一個RTP包都更新:

  • transmitted,接收到的RTP包的總數;
  • retransmitted,接收到重傳RTP包的數量;

   2.某時刻收到的有序包的數量Count = transmitted-retransmitte ,當前時刻爲Count2,上一時刻爲Count1;

   3.接收端以一定的頻率發送RTCP包(RR、REMB、NACK等)時,會統計兩次發送間隔之間(fraction)的接收包信息:
      //兩次發送間隔之間理論上應該收到的包數量=當前接收到的最大包序號-上個時刻最大有序包序號
      uint16_t exp_since_last = (received_seq_max_ - last_report_seq_max_);
     
      //兩次發送間隔之間實際接收到有序包的數量=當前時刻收到的有序包的數量-上一個時刻收到的有序包的數量
      uint32_t rec_since_last = Count2 - Count1
     
      //丟包數=理論上應收的包數-實際收到的包數
      int32_t missing = exp_since_last - rec_since_last

      missing即爲兩次發送間隔之間的丟包數量,會累加並通過RR包通知發送端。

RR中的丟包

      接收端發送的RR包中包含兩個丟包,一個是fraction_lost,是兩次統計間隔間的丟包數,一個是cumulative_lost,是總的累積丟包。發送端收到後在狀態統計Stats中看到的是累積丟包,而在計算髮送碼率的時候更多的是使用分段丟包fraction_lost,因爲其屬於比較實時的參數。

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