音視訊學習 -- 弱網對抗技術相關實踐

聲網Agora發表於2021-10-23

音視訊學習--弱網對抗技術相關實踐

背景介紹

實時音視訊通話在當前的生活中是無時不刻存在的,包括社交、安防、交通等等各個方面都需要。使用者場景複雜多變、要求嚴苛、網路環境不一致等給實時音視訊通話帶來很大條件。我們在這方向稍微做了一些工作,雖然和其他大廠的優化工作相比,我們還處於劣勢,還有很多可以優化和改進的,但是目前的一些進展和工作內容和大家分享一下。

0.1 網路傳輸:

我們知道網路傳輸目前有 TCP 和 UDP 兩種,相關優缺點如下腦圖;而影響網路傳輸質量也有很多原因:包括網路擁塞、網路丟包等等。這些因素直接決定當前實時視訊通話的質量,也會給使用者帶來很大的體驗影響。這也是我們為什麼要進行優化的基本原因了。

img

0.2 弱網定義:

對於實時音視訊通話來說:網路的複雜性、異構性、協議部分不規範性、網路異常,網路錯誤等各種網路環境被破壞的特性都稱之為弱網。弱網環境無法提供高質量的網路傳輸,對於接收端就是無法收到連續的媒體包,造成聲音異常、視訊馬賽克、花屏、黑屏等現象,對於音視訊實時通話來說是非常致命的,直接影響到使用者的體驗,造成產品質量問題或者客訴問題。

img

0.3 實時音視訊特點

對於實時音視訊通話來說要求最高的條件低延遲和高質量,這一對特性的存在就是天生的矛盾結合體。高質量就要求傳送端儘可能傳送高解析度,高質量的音視訊流,對於頻寬和網路環境要求比較高,不允許有各種丟包、高抖動的現象存在;而低延遲則對於網路環境沒有那麼嚴苛,是允許存在一定丟包量、允許一定範圍內的接收抖動的,否則只能用空間換時間,導致音視訊實時性時效,無法達到低延遲的要求。所以這是一對矛與盾的故事。只能在矛上尋求突破,在盾上給予保護,才能滿足這樣苛刻的條件。

img

一 FEC

webrtc FEC 的實現方式有三種:RED(rfc2198)、ULPFEC(rfc5109)、FLEXFEC(還未通過)。但是 Ulpfec 是套用了 RED 的殼進行傳輸的,所以我們採用的是 ULPFEC 進行 FEC 保護。

img

其基本原理是:在傳送端,針對媒體包增加一定冗餘 FEC 包,FEC 包是通過異或 XOR 得到的。如果在網路傳輸過程中丟掉了一部分媒體包,則在接收端通過接收到的媒體包和 FEC 包進行異或 XOR 得到丟失的媒體包,這樣就不用傳送 NACK 重發包占用網路資源了。

由於這部分在 WebRTC 中已經實現的比較好,只需要進行相容性測試即可,這部分沒有作為重點優化物件,沿用 WebRTC 中內容即可。

二 NACK

2.1 NACK 介紹:

NACK 代表否定確認。 它是 WebRTC 中的錯誤恢復機制之一。NACK 是接收端表明它沒有收到特定資料包的一種方式。

NACK 訊息通過 RTCP 傳送給媒體的傳送方,後者需要根據其在快取中的可用性以及對重傳有用性的估計(是否可以使用)來決定是否重傳丟失的資料包 它曾經收到。傳送端維護一個緩衝佇列,如果重發包在緩衝佇列中則從緩衝佇列中取出再次傳送;如果沒有在緩衝佇列中,則不再傳送,這樣解碼端就無法收到重發包了。

img

2.2 優化和改進:

由於當前系統中採用的仍然是舊版本中的 NACK 流程,具體流程如下:

  • RTP 模組解封包後,將資料包按照到達順序依次傳送到 JitterBuffer 模組中;
  • 每個資料包在插入 JitterBuffer 模組時都需要進行序列號的比較和排序,如果序列號比較新的資料包,則進行 NACK 構建,以上次儲存的序列號+1 為起始值,以新收到的序列號為結束,將之間的序列號先快取到 missing_sequence_numbers 中;
  • WebRTC 在 JitterBuffer 中採用執行緒查詢的方式,每個一定時間進行一次遍歷,確認當前 nack List 中是否存在當前時間節點沒有按照順序收到的資料包,如果存在就會組裝併傳送 NACK RTCP 包到傳送端,請求傳送對應的為接收到的資料包。

NACK 是一個未到達資料包的確認過程,原先流程中有很多巢狀功能,或者流程複雜的地方,因此我們再理解的基礎上做了兩次優化,其兩輪優化的大概流程圖如下:

img

還有一個 NACK 無法迴避的問題時:如果網路丟包率比較高,或者網路抖動,網路異構導致網路各種亂序到達情況比較嚴重,比如抖動超過 200ms 時,某些丟失的資料包遲遲不到達,則該包會重複傳送多次,這樣會導致網路擁塞的現象,特別是解析度比較高時,極容易造成視訊幀無法完整解碼,出現馬賽克或者黑屏現象。

因此我們再次基礎上增加和修改了一些判斷條件,進行快取佇列和清空佇列判斷條件優化,以及獲取完整視訊幀流程部分調整和優化,儘量減緩以上情況的影響,提升使用者體驗。

三 頻寬自適應

3.1 頻寬自適應:

我們在進行視訊實時通話時,在裝置端按照不同的幀率採集資料設定的引數,這樣傳送端就維護一個最大幀率引數集。之後採集的影像進行編碼,分包傳送到網路中。但是如果網路發生了變化,仍然按照當前的位元速率逐幀傳送到上行網路時,亦或者採集端編碼效能不穩定無法消耗採集的影像幀序列,傳送端將採取降幀率或者丟幀的方式緩解傳送端的傳送壓力。

在 WebRTC 中當編碼後的傳輸位元速率過載或負載不均時,通過呼叫 MediaOptimization 類相關介面降低或升高幀率進而減小或者升高位元速率,從而有效利用當前頻寬,防止網路更差,或者網路頻寬負載不夠,影響使用者體驗。

3.2 框架圖

傳送端:基於丟包率估算當前可用頻寬

接受端:基於包到達時間計算可用頻寬

綜合:接收端傳送 REMB 反饋給傳送端,然後基於傳送端的頻寬估算和接收端的頻寬估算決定最終的傳送速率。

img

3.3 傳送端

傳送端的頻寬估計演算法基本原理:是讀取 RTCP 中的丟包率資訊,進而通過演算法來動態計算當前網路中基本情況,並判斷是否增加或減少頻寬資源。如果判斷需要減少頻寬時,則採用 TFRC 演算法來平滑處理,減弱突然增加或者減少的風險。

img

3.4 接收端

接收端的頻寬估計演算法基本原理:讀取收到 RTP 資料統計進而估算當前網路頻寬;WebRTC 中採用卡爾曼濾波幀對當前幀的接收時間戳和傳送時間戳完成基本統計和計算,從而估算當前網路頻寬擁塞情況和利用率,評估和修正頻寬大小,進而影響網路頻寬。

img

四 優化和改進:

4.1 優化和改進

我們做的工作主要的優化點如下:

NACK 兩輪優化:包括之前版本演算法的整體提升(重構原來 R4X 相關程式碼,採用和 iOS 相同的 NACK 獲取演算法,並在此基礎上進行快取佇列和清空判斷條件調整優化、獲取完整解碼幀相關流程優化、長時間快取幀丟棄策略調整等方案)、Jitterbuffer 引數的優化調整;

FEC、動態解析度、NACK 整體策略優化:針對不同的網路條件,依據丟包率、RTT 等相關引數,以及 5s 內的抖動平均值等,設計一套動態調整當前組合的整體方案,既增加一定冗餘防止 FEC 高丟包時時效現象,也可以在高丟包時逐步降低解析度達到流暢播放的體驗。

網路風暴抑制優化:WebRTC 中有重發包的網路抑制策略,重發包占比為 35%時候不再傳送 NACK 重發包和 FEC 冗餘包,但是這個佔比對於 720P、30%以上丟包時非常不友好,因此大量實際驗證測試,重發包和 FEC 冗餘包占比為 30%時,能夠合理規避網路風暴現象,同時滿足 NACK 請求重發的策略,達到 720P、30%丟包仍然可以獲取 15~25 幀率,實現流暢播放。

4.2 優化結果

img

整體方案進行了部分實驗室場景的測試和驗收:包括 IP 和 SIP 通話,720P 和 VGA 解析度驗證,相比之前的版本,在一定程度上提高的使用者體驗。特別是有線網路條件下 IP 直播時提升明顯,總體主觀的分有了明顯提升。同時對抗延遲也從無到有,能夠覆蓋 300ms 一下環境。該方案得到用到實際環境中,得到使用者認可,並在和競爭對手 PK 過程中,全面領先。

五 問題和措施:

5.1 擁塞檢測:

需要更加快速準確定位到當前網路狀態,一旦出現擁塞可以快速調整當前傳送策略。已經有視訊專項開始預研。

5.2 最新 WebRTC 中弱網控制

WebRTC 中 NACK 模組作為獨立的 module 整合到 VIE 模組中,和 Jitterbuffer 模組解耦,實現實時監控網路丟包,並獨立傳送。

優點:可以實時獲取到 NACK 列表; 和 JitterBuffer 解耦,獲取更便捷、更迅速。已經有視訊專項開始預研。

5.3 弱網前沿

2020-10-24 參加聲網 RTE2020 網際網路實時網際網路大會,聲網已經實現 720P 2.0M 頻寬下 65%的丟包,流暢播放了。

img

1.深度強化演算法那在擁塞控制中的應用;

2.實時 H264 視訊編碼器演算法的深度優化。

img

img

這些是我們之後要去調研學習的地方,也期待有相關經驗的童鞋可以一起探討學習。

相關文章