RTC 弱網對抗之冗餘策略

語言: CN / TW / HK

動手點關注 乾貨不迷路 :point_down:

1. 背景

當下社會,實時音視訊通話已經成為人們生活、工作中重要的組成部分,如商務會談、親朋聊天等。而在通話過程中,總會存在著這樣那樣的意外情況:可能你坐在飛馳的高鐵上——訊號時好時壞;又或者在會議途中離開辦公室——網路從 wifi 切換到 4G……實現高質量的實時音視訊通話需要搭建一座無視距離連線人們的“橋樑”,而這座“橋樑”需要優秀的“基建技術”來保障網路傳輸的穩定性和可靠性。

網路傳輸鏈路上存在著許多不穩定的情況,造成所發出去的資料包出現丟包、延時或者抖動。不穩定的原因有很多,兩個通訊雙方在物理空間上存在距離,傳輸過程經過很多裝置的處理,中途存線上路硬體故障、軟體驅動限制、或者鏈路資料擁塞等情況,都會導致傳送出去的資料包在接收端沒有辦法收到或者延遲收到。

我們可以通過一些簡單基礎的工具檢測網路是否處於波動情況,比如 ping 命令或者 Iperf 工具可以幫助統計丟包、延時以及單向抖動。我們用 ping 命令向一個遠端的主機發送 ICMP 訊息,遠端主機會對你進行應答,這個過程中如果你傳送出去的 ICMP 訊息丟了,或者遠端伺服器應答的訊息丟了,在命令列介面上,對應的 icmp_seq 就會顯示超時未收到,這種情況就直觀地體現了丟包。

ping vs iPerf   

頻寬分配和冗餘策略是弱網對抗核心模組,隨著演算法的演進迭代,我們能夠保證線上大部分場景的優質音視訊體驗。 對於一些小概率或特殊場景,如突發網損、擁塞恢復、PPT 翻頁等,我們還引入了多種冗餘策略,來兼顧流暢、恢復效率和低延時的需求。

2. 常用包恢復技術

通常,一個數據包在網路傳輸鏈路中丟失了,主要有兩種方式將包進行恢復:一種是傳送端利用接收端通知或者超時的機制,重新將這個包傳送過來;另一種則是基於其他收到的冗餘包,在接收端將該包恢復出來。

第一種是我們熟知的自動重傳請求 ARQ 技術。與 TCP 協議中的 ACK 應答機制不同,實時音視訊場景使用的是 NACK 否定應答機制,通過接收端檢查包序號的連續性,主動將丟失的包資訊通知給傳送端進行重新發送。這種方式的優點是在低延時場景下的恢復效率高,頻寬利用率好,但在高延時場景下的效果比較差,存在重傳風暴等情況。

第二種是 Forward Error Correction (FEC) 即前向糾錯編碼,一種通過冗餘傳送對抗網路丟包的技術。它主要的技術原理就是分組編碼,組內進行冗餘恢復。假設每個分組由 k 個媒體包和 r 個冗餘包組成,一個分組中 k+r 個數據包中任意 k 個包可以用來重建 k 個原始媒體包。這種方式的優勢是根據先驗知識進行冗餘決策,不受延時影響。

3. 冗餘策略

在上述基本的包恢復技術下,為了使各種場景的整體抗弱網能力最大化,需要針對頻寬分配、抗丟包技術的組合配置等進行一系列的優化,從而達到抗丟包能力、端到端延時、卡頓率、冗餘率的平衡,達到“消耗最小的代價,實現最優的體驗”。

下面具體介紹我們在這方面做的幾項優化。

3.1 自適應調整策略

冗餘策略大致可以分為兩類,一類是前向冗餘,一類是被動冗餘。按照前文的描述,我們知道前向冗餘的優點是不需要互動,在高延時環境下更加適用,缺點是頻寬佔用過多。被動冗餘的優點是按需傳送,佔用頻寬較少,缺點是高延時場景效果會急劇下滑。

我們的冗餘策略則是在尋找一個平衡點,通過被動冗餘和前向冗餘策略比例的調整,在保證丟包恢復率(比如 99.5%)的前提下,儘量的減小冗餘佔比,儘量的減小抗丟包恢復時間。所以,我們可以將當前問題抽象成如下一個數學場景:

  • 假設 m 個媒體包,在重傳 k 次後,收到 i 個包的概率記為: P(m, i, k)

  • 假設 n 個冗餘包,接收端收到 j 個包的概率記為: P(n, j, 0)

  • 根據當前的 FEC 演算法,這個 m + n 的分組在重傳 k 的情況下,接收端只需要接收到任意 m 個包,就能夠恢復全部的媒體包, 這個概率為:

  • Nack FEC 演算法就是基於恢復概率大於 99% 的情況來計算當前最少需要配置的 FEC 冗餘度 n

基於上面的模型,在 m (平均幀分組大小), k (允許時間範圍內的重傳次數), i,j 是可以自變數。我們只要將 n 從 0 開始代入,上面求和的結果大於 99%,就可以將這個 n 作為 FEC 的冗餘率。

通過上面的演算法,我們定義一個抗丟包恢復時間 resend_delay,就可以獲得被動重傳次數 k。通過引數 k,可以推匯出為了達到恢復率 99%,還需要的 FEC 比例。

上述就是理論上的最優冗餘率計算邏輯。通過該演算法邏輯,我們可以獲得一個自適應的冗餘調整策略,從而獲得最優的冗餘比例、最合適的延時損耗、以及最佳的丟包恢復率。

3.2 可靠重傳策略

在接收端媒體快取中,對於 seq 最新和最老範圍內沒有接收到的資料,接收端會發送 Nack 請求,然後傳送端接收 Nack 請求,將相應的包傳送過來。

正常工作狀態中,Pacer 優先發送 RTX 重傳資料,然後再發送媒體資料,這樣接收端這邊較老的丟失資料包,總能夠優先得到恢復。

但是在一些場景下,比如大丟包(70% 或以上的丟包率),或者突然限寬(4M ---> 300K)時,會出現大量的資料包被丟棄掉。這個資料包既包括原始包,也包括 Nack 重傳包,這樣會導致如下圖的一些問題。

如圖,如果丟包恢復效果比較差,比如上面 n + 3 的幀已經開始傳送了,但是 n 幀還沒有被接收端全部接收到,這時,接收端生成的需要重傳的包列表 nack_list 就會很長。對於傳送端來說,由於媒體資料還在繼續傳送,理論上接收端請求的 nack 會越來愈多,這樣就會形成 nack 風暴。

Nack 風暴不但會導致大量的重傳流量擠佔媒體頻寬,導致頻寬分配模組分配給媒體的位元速率降低,也會導致 Pacer 擁堵,從而帶來更大的端到端延時。同時,由於不是選擇性的重傳某個幀的媒體包,導致接收端需要解碼的幀能夠被完整丟包恢復的概率比較低。

為了避免上述情況,我們引入了可靠重傳模組:在檢測到上述情況後,及時暫停媒體傳送,同時全力保障已經發送的幀資料能夠完全恢復。

我們通過 TccAck 和 Nack 請求的資訊來確定某一個包處於什麼狀態,然後統計當前已經發送的資料中沒有被完整 ACK 的幀數量。如果這個數量過大,則會暫停媒體傳送(同時暫停編碼器)。暫停媒體傳送後,按照幀從老到新的順序,把 pacer 預算分配給最高優先順序的幀,主動傳送這些幀裡面沒有被 ACK 的資料。

通過上面的方式,我們有效解決了目標場景長時間卡死或者卡頓過多的問題。

3.3 擁塞恢復場景下快速抑制 FEC 位元速率

我們 FEC 使用 loss 計算 FEC 冗餘率,為了防止抖動帶來的劇烈變化,這個 loss 值被平滑過。但是對於一些場景,比如頻寬突然掉落到較低的場景下,當擁塞狀態解除後,網路丟包就會消失。這個時候,我們需要快速的抑制 FEC 位元速率,讓出頻寬給到媒體,這樣可以儘快地提升畫面質量。

使用上面的狀態機,在接收到擁塞解除訊號(擁塞狀態解除,並且瞬時 tcc loss 變為0)後,在平滑 loss 沒有變為 0 的情況下,使用瞬時 loss,可以快速取消掉 FEC 冗餘。

3.4 空餘頻寬利用優化

在共享場景下,冗餘策略會遇到進一步的挑戰。比如在 PPT 不翻頁的時候,空餘頻寬需要讓給視訊。但是在翻頁的時候共享流又會迅速佔據頻寬。這樣就會導致視訊位元速率在翻頁時出現較大的波動。如果整體可用頻寬較低,就能夠看到視訊質量的明顯變化——卡頓率、延時上升。

如圖,在 PPT 翻頁場景,video 會使用 screen 空餘未被使用的頻寬。靜止畫面下,video 使用了大部分原本共享的預算。一旦 PPT 翻頁,共享的位元速率瞬時提高,而 video 沒有及時把編碼位元速率降下來,就會造成 pacer 模組的擁堵,導致丟幀從而攝像頭流卡頓。

針對該場景,我們對頻寬分配策略進行了優化:

  • 緩升快降

頻寬分配過程中對每個媒體流使用的上一層傳過來的空餘位元速率進行緩升快降操作,防止高優先順序碼流過快讓出空餘頻寬,導致低優先順序碼流的分配位元速率大幅波動。

  • 關鍵幀檢測

當某個媒體流開始收到關鍵幀的時候,降低該流讓出空餘頻寬的量,使得整體輸出位元速率的波動性降低。

  • 波峰檢測

使用 300ms 統計視窗判斷波峰,出現較大的波峰資料時,降低該流讓出頻寬的量,減小整體輸出位元速率的波動性。

4. 優化效果

在上述的冗餘策略優化下,飛書會議整體冗餘率大幅度降低(部分上漲是由於原有演算法冗餘不足,出現大量卡頓,演算法優化後,整體冗餘率調整為最佳值)。同時,在保證了音視訊整體效果的前提下,整體端到端延時也進一步下降,提升了飛書會議的整體音視訊體驗。

  • 演算法優化大幅度降低了低延時場景的冗餘率,高延時場景的冗餘率也趨於理論上的合理值。

  • 解決了原有演算法在高丟包場景下的問題,對於高延時,高丟包率的弱網場景下的體驗大幅提升。

  • 解決了場景,網路狀態變化過程中的收斂速度,提升了變化過程中的音視訊體驗。

在與同類產品的比較中,我們優化演算法的冗餘度明顯低於同類產品,在流暢度對齊的情況下,消耗更小的頻寬。特別是在高丟包,高延時場景下,我們的冗餘率只相當於同類產品的 40%。

5. 未來展望

通過這些經優化的冗餘策略,當前飛書會議在弱網場景下的卡頓率、端到端延時、冗餘率等指標得到了大幅度的優化。在此基礎上,我們未來會在極端弱網支援,帶內冗餘聯動策略,智慧場景識別等方面,進一步加大投入,增加飛書會議在各種弱網場景下的客戶端體驗。

5.1 極端場景下的抗弱網能力支援

增加針對極高丟包、極高延時、丟包+延時,低頻寬+高丟包等場景的支援,配合冗餘策略以及頻寬分配策略,達到極端弱網場景下面的最佳音視訊體驗。

5.2 帶內冗餘聯動下的抗弱網策略

冗餘策略,除了前面提到的非音視訊編碼內的帶外冗餘(Nack,FEC 等),也包含音視訊編碼內的帶內冗餘。相比於帶外冗餘,帶內冗餘往往結合編碼自身的特點,使用更少的冗餘位元速率代價,達到更高的抗弱網效果。

我們的冗餘策略也會進一步結合、更大化利用帶內冗餘演算法,進一步提高抗弱網能力,降低整體延時和頻寬佔用。

5.3 場景識別下的抗弱網策略優化

後續,我們還將對當前的網路環境進行識別,獲取到當前的網路場景,從而可以進一步對冗餘策略以及編碼策略進行預判式的策略下發。

比如,我們識別到當前場景為高鐵場景,就可以在冗餘策略生成的時候偏向於抗連續丟包的策略,也可以預先增加預設前向冗餘來增加突發弱網的抗性。根據識別場景的特性,可以在實際發生弱網之前以及發生弱網之後,做出策略上的區別。

6. 加入我們

火山引擎 RTC,致力於提供全球網際網路範圍內高質量、低延時的實時音視訊通訊能力,幫助開發者快速構建語音通話、視訊通話、互動直播、轉推直播等豐富場景功能,目前已覆蓋互娛、教育、會議、遊戲、汽車、金融、IoT 等豐富實時音視訊互動場景,服務數億使用者。

我們是 RTC Lab 部門,負責 RTC 產品中音訊、視訊、網路等基礎功能的研發,通過極致的工程和音視訊演算法,打磨頂級的實時音視訊基礎體驗,期待優秀同學的加入!

:runner: 掃描上方二維碼,或點選 閱讀原文 ,趕緊加入我們吧!