【多媒體基礎】如何優化傳輸機制來實現實時音視頻的超低延遲(FEC,ARQ,PLC)

轉自:語音視頻SDK如何實現超低延遲優化?

 

要在語音視頻 SDK 中實現超低延遲,實時的語音視頻傳輸機制是必不可少的,而 FEC 和 ARQ 的智能結合是實時語音視頻傳輸機制的基石。

在語音社交、視頻社交、遊戲語音和互動直播等領域,關於在語音視頻實時傳輸中實現低延遲這個議題,已經有不少的文章提出各種方案。絕大部分方案的思路都是“優化”,比如說,優化編碼、推流、傳輸播放等各個環節。

愚以爲,要在實時語音視頻傳輸中獲得超低延遲,是不能單靠挖空心思去“優化”的,而是要依靠實時的傳輸機制。就像高鐵和火車有着本質的區別一樣,火車不管如何優化,也只是跑得更快的火車,永遠達不到高鐵的速度。沒有一套實時的傳輸機制,再怎麼在各個環節“優化”,也無法獲得真正超低的延遲。

 

即構的實時語音視頻通訊架構圖

 

要實現超低延遲,信道 QoS 十分關鍵。首先要選擇合適的網絡傳輸協議,採用基於 UDP 的私有協議還是標準 RTMP 協議?然後根據網絡環境採用合適的 QoS 技術,採用 FEC,ARQ,還是雙管齊下? 如果採用 FEC 和 ARQ 雙管齊下,那麼一套智能的 QoS 策略就必不可少。沒有任何一種 QoS 技術能解決所有問題,實時語音視頻傳輸機制必須是多種 QoS 技術的有機結合。

 

協議的選擇

 

如果是視頻直播 SDK,一般會選擇 RTMP 協議,因爲要能夠普遍兼容 CDN 分發網絡,從而向圍觀的廣大用戶進行直播。如果是音頻社交 SDK、視頻社交 SDK 或者遊戲語音 SDK,一般會選擇 RTP/RTCP 協議(或者類 RTP 的私有協議),因爲不需要通過 CDN 網絡向圍觀用戶廣播媒體流。是否要考慮兼容 CDN 網絡,是語音視頻通話 SDK 和視頻直播 SDK 的重大區別。

RTMP 協議是基於 TCP 協議的,RTP 協議或者私有協議是基於 UDP 協議的,因此 RTMP 協議和 RTP 協議之爭,本質就是 TCP 協議和 UDP 協議之爭。

 

TCP 協議的特點

 

1) 是通用的 IP 網絡協議,不是爲實時媒體傳輸而設計的,在弱網網絡環境下延遲會增大。

2) 有內嵌的 ARQ,但沒有 FEC,不允許開發者對 ARQ 策略進行控制,不能實現 FEC。

3) 不是從實時語音視頻的角度進行設計的,更多考慮網絡傳輸的公平性,內嵌的傳輸控制策略比較溫和。

 

UDP 協議的特點

 

1) 適合實時語音視頻通訊,允許端到端全鏈條進行信道策略控制,在弱網環境下可控性更強。

2) 延遲時間的大小取決於丟包時候的 ARQ 和 FEC 策略,允許開發者深度控制 ARQ 和 FEC 策略。

3) 適合設計實時語音視頻的通訊機制,根據網絡狀況自適應地選取 ARQ 和 FEC 策略,以及調整傳輸碼率和報文的數量。

在網絡環境好的情況下,只要語音視頻編解碼器相同,RTMP 協議和基於 UDP 的私有協議的傳輸效率是相當的,都可以實現低延遲、不卡頓和高品質的實時通訊效果。

在網絡環境較差的情況下,特別是在跨網甚至跨國的情況下,基於 UDP 的私有協議對端到端全鏈條可控,包括流控碼控、ARQ、FEC 和抖動緩衝等,對抗惡劣網絡環境會更有保障。

 

信道保護

 

IP 網絡是“盡力而爲”地提供數據傳輸服務的,盡最大的可能性來發送報文,但對時延、可靠性等性能概不負責效果,傳輸的數據出錯是避免不了的,因此對信道進行保護是必須的。

信道 QoS 技術主要包括前向糾錯 FEC,丟包重傳 ARQ 和混合型 ARQ。這幾種算法都是成熟的技術,在最基礎的算法上又衍生出多個變種,而且在實現的過程中也可以進行定製化。

在 FEC 和 ARQ 的基礎上,爲了更好地適應弱網環境,需要讓碼率自動適應網絡環境的波動,這樣能夠更好地保障實時語音視頻通話的可用性和流暢性。

 

信道 QoS 的三大措施

 

 

前向糾錯 FEC

 

FEC 全稱是 Forward Error Correction,中文翻譯爲前向糾錯,是一種通過增加冗餘數據對丟失的數據包進行恢復的信道編碼算法。具體地說,由發送端對原始數據進行 FEC 編碼,生成冗餘奇偶校驗數據包,原始數據和冗餘數據包合併稱作 FEC 數據塊,原始數據包和冗餘數據包的數量比例是固定的。發送端發送 FEC 數據塊。接收端接收到 FEC 數據塊後,通過冗餘數據包和原始數據包來恢復出丟失或者出錯的數據包。

FEC 編解碼算法推薦使用比較成熟的 RS(Reeds-Solomon) 算法、Raptor 算法和 Tornado 算法。使用 FEC 編碼算法的時候要根據丟包率(PLR, Packet Lost Rate)來設置冗餘度。

下面使用 RS 的一個例子來說明 FEC 編解碼算法的使用方法。

因爲在一個 FEC 數據塊中,原始數據包的個數和冗餘數據包的個數的比例是固定的,所以很容易根據丟包的個數和冗餘包的個數來判斷是否能夠全部恢復丟失的數據包。RS (n, k) 表示通過 RS 算法把 k 個原始數據包進行編碼,生成(n-k)個冗餘數據包,總共是一個包含有 n 個數據包的 FEC 數據塊。假設丟失了 m 個數據包,如果 m<=(n-k),那麼 RS 算法可以完全恢復丟失的數據包;如果 m>(n-k),那麼 RS 算法就無法恢復丟失的數據包,這時候就要進行發送請求要求重傳丟失的數據包。

下圖展示了通過 RS(6,4) 進行丟包恢復的過程。發送端有 4 個原始數據包,通過 RS 算法編碼生成 2 個冗餘包,形成了一個擁有 6 個數據包的 FEC 數據塊。RS 算法最多能夠恢復 2 個丟失的數據包。發送端把 FEC 數據塊發出去,在傳輸過程中第 2 號原始數據包丟失了。接收端接收到 FEC 數據塊以後,通過 r1 冗餘包把已經丟失的第 2 號原始數據包恢復出來。

RS(6,4) 算法恢復出丟失的數據包

使用前向糾錯 FEC 算法,優點是數據包只需要傳輸一次,傳輸延遲不會受到 RTT(Round Trip Time) 的影響,不會增加額外的延遲時間;缺點是需要增加冗餘數據包,降低了傳輸信道的利用率。總的來說是一種“空間換時間”的策略。

下文將會綜合對 FEC 和 ARQ 的特點進行全面對比。

 

丟包重傳 ARQ

 

ARQ 全稱 Automatic Repeat reQuest,中文意譯爲丟包重傳,是一種通過重傳關鍵數據包來糾錯的信道保護算法。

具體地來說,發送端給每一個數據包都植入順序號碼和時間戳,順序號碼代表被髮送數據包的順序,允許接收端可以通過監測順序號碼來發現丟包事件;時間戳代表語音視頻數據包解碼的時間點。發送端發送數據包後,如果接收端沒有收到,接收端將會通過 RTCP/TCP 信道發送一個重傳請求。發送端維護一個緩衝隊列,當收到重傳請求的時候將會重傳數據包。接收端也會維護一個緩衝隊列,等待尚未收到的數據包以及對已經收到的數據包進行排序。在解碼的 deadline 到來之前,接收端把緩衝區的數據包交給解碼器進行解碼。在解碼 deadline 的時間點,接收端要麼已經收齊了預期的數據包,要麼已經決定放棄繼續等待。

傳統的丟包重傳 ARQ 包括以下三種:

1)Stop-and-wait ARQ,也就是停止等待的 ARQ,發送端發送數據包後就停止並等待接收端的確認消息,在收到確認消息之前,信道處於空閒狀態。

2)Go-Back-N ARQ, 也就是退回 N 步的 ARQ,發送端不需等待接收端的確認,不停地發送數據包,直到收到接收端的重傳請求。發送端除了重傳被要求重傳的數據包以外,還會把該數據包時間戳後面已經被接收端成功接收到的一批數據包全部重傳一遍。

3)Selective Repeat ARQ,也就是選擇性重傳的 ARQ,發送端不需等待接收端的確認,不停地發送數據包;接收端只會有選擇性地對關鍵的數據包要求重傳,而發送端只重傳被要求重傳的數據包。

第一種和第二種 ARQ 效率比較低下,第三種 ARQ 相對來說效率比較高。目前主流的丟包重傳算法大部分是第三種 ARQ 的變種或者定製化版本。

選擇性重傳 ARQ 的優越性在於它能確定哪些關鍵的數據包需要重傳,從而大大地提高重傳的效率,降低造成重傳風暴的風險。比如說,在出現花屏的時候,請求發送端立即編碼視頻關鍵幀發送過來,避免長時間花屏無法刷新的現象。選擇要重傳的數據包的算法十分關鍵,這裏必須要有比較謹慎的策略,不能任何丟失的數據包都要求重傳,那樣就相當於又走了 TCP 協議內嵌 ARQ 模塊的老路,必然引入不可控的延時。

選擇性重傳的 ARQ 要考慮實時性,要估算計劃要重傳數據包到達的時間(以 RTT 的倍數來估算),如果數據包預期的到達時間在解碼的 deadline 之前,就要求重傳,如果在 deadline 之後,就放棄重傳。下面通過一個例子來說明選擇性重傳的 ARQ 這個實時策略。

下圖展示了選擇性重傳的 ARQ 的實時策略:

1)發送端發送 #1、#2 和 #3 三個數據包,數據包 #2 丟失了;

2)N 倍 RTT<數據包 #2 解碼 deadline, N=2,判斷可以接受重傳 2 次;

3)接收端通過 RTCP/TCP 信道請求重傳;

4)發送端重傳,數據包 #2 再次丟失;

5)接收端通過 RTCP/TCP 信道請求重傳;

6)發送端重傳,數據包 #2 成功到達;

7)接收端把 #1、#2 和 #3 三個數據包排序,交給解碼器解碼。

選擇性重傳 ARQ 考慮 RTT 和編碼 deadline 等實時因素

 

如果在 2 次以內能重傳成功,那麼就可以縮短接收端的緩衝時間,在解碼 deadline 之前把數據包排序並交給解碼器解碼。如果在 2 次內不能重傳成功,那麼就放棄繼續重傳。因此,接收端總能維持解碼的時間 t<= 解碼 deadline,維持了傳輸的實時性。

使用選擇性重傳的 ARQ 算法,優點是只需要有選擇性地傳輸關鍵的數據包,不會明顯增加額外的帶寬,帶寬利用率十分高;缺點是需要請求和重傳,增加了傳輸延遲時間。總的來說是一種“時間換空間”的策略。

下表對 FEC 和 ARQ 的特點進行綜合對比。

FEC 和 ARQ 的特點對比

碼率自適應 ABC

 

ABC 全稱 Adaptive Bit-rate Control,中文意譯爲碼率自適應,是服務端和推流端協作控制碼率來自動適應網絡環境變化的技術。碼率自適應的目的是爲了對抗弱網環境。在網絡好的情況下,適當提高碼率,提高語音視頻的質量和降低延遲;在網絡差的情況下,適當降低碼率,保障語音視頻通話的可用性和流暢性,適當犧牲音畫質量。

碼率自適應包含了帶寬估算和碼率控制:

1)帶寬估算,服務端和推流端協作完成,推流端把網絡環境統計信息上報給服務端,服務端通過帶寬估算算法估計出當前帶寬。

2)推流端按照估算出來的帶寬進行推流,如果網絡情況良好(沒有檢測到網絡擁塞)則持續的地提高碼率,試探網絡帶寬的上限,直到出現網絡擁塞爲止。

3)當網絡擁塞出現的時候,推流端降低碼率來保障可用性和流暢性,直到網絡擁塞緩解爲止。

4)當網絡擁塞緩解的時候,轉到 #2。

整個過程可以類比成駕駛汽車過程中控制方向盤的方法,偏左了就往右邊調整一點,偏右了就往左邊調整一點,來來回回的微調讓駕駛處於安全和順暢的狀態。碼率自適應也是一樣的道理。

 

錯誤隱藏 PLC

 

PLC 全稱 Packet Lost Concealment, 意譯爲錯誤隱藏,應用於實時語音通話的場景。語音數據包的丟失會造成語音的歪曲。爲了減少語音數據包丟失造成對語音通話質量的傷害,錯誤隱藏 PLC 算法通過前一個語音數據包和後一個語音數據包的相關性來“推測出”當前丟失的語音數據包,從而“隱藏”了信道傳輸所造成的錯誤。錯誤隱藏 PLC 算法在接收端進行,不需要發送端參與。

 

智能 QoS

 

上面介紹了信道保護的各種 QoS 算法。沒有哪一種算法能夠解決所有問題,也不是把所有算法一起混着用就能實現通訊機制。如何綜合使用這些算法對信道進行保護從而達到實時的效果?這裏需要一套智能的 QoS 策略,既要能對抗網絡損傷,又要能保持媒體數據傳輸的實時性。

 

混合 FEC&ARQ

 

FEC 和 ARQ 各有各的優點和缺點。FEC 雖然不會增加額外的延遲,但是會增加額外的帶寬成本。ARQ 雖然算法相對簡單而且幾乎不增加帶寬成本,但是會增加額外的延遲。因此,一般的做法是把 FEC 和 ARQ 混着通過智能的策略來使用,也就是混合型 HARQ(Hybrid ARQ)。

混合型 HARQ 的智能策略要充分考慮網絡情況,也就是要根據 RTT 和 PLR 的數值來智能地決定使用 FEC 還是 ARQ,還是兩者一起使用,哪個用多一點哪個用少一點?

下圖是筆者和團隊在工作經驗中總結,僅供參考。

 

即構的智能 HARQ 策略

 

上圖中有三塊區域,代表兩個極端情形和一箇中間情形:

1)較弱網絡的極端情形:在 RTT>250ms 或者 PLR>10%, 網絡延遲特別大或者丟包率特別高的情況下(藍白色區域),不使用 ARQ 而使用 FEC,因爲在延遲大或者丟包多的弱網情況下,ARQ 可能會進一步加大延遲。

2)較好網絡的極端情形:在 RTT<70ms 或者 PLR<3%,網絡延遲很小並且丟包率比較低的情況下(深藍色區域),適合使用 ARQ,如果對成本不敏感,可以適當使用 FEC。

3)中間的情形:在 (RTT<=250ms 而且 PLR<=10%) 的前提下,RTT>=70ms 或者 PLR>=3% 的情況,可以根據成本和體驗的考慮,智能地選擇使用 FEC 和 ARQ 的權重。

語音數據可以適當地通過 PLC 來恢復,可以減低延遲時間和帶寬成本。另外,由於語音數據比起視頻數據小好多,與其通過 FEC 和 ARQ 複雜的算法處理,還不如在適當的網絡情況下,在一定的時間間隔內發送兩次同樣的語音數據包,從而達到用冗餘數據糾錯的效果。

 

帶寬估算

 

無論是碼率自適應、FEC 還是 ARQ,都要依賴帶寬估算算法來工作。碼率自適應根據帶寬估算的結果來自動調節碼率;FEC 和 ARQ 根據帶寬估算的結果來分配冗餘數據所佔的帶寬。

發送端和服務端協同對網絡帶寬進行檢測和估算,發送端把網絡帶寬的統計信息上報給服務端,服務端把網絡帶寬的估算結果反饋給發送端。當然,也可以完全在推送端進行帶寬估算。

除了帶寬估算以外,網絡擁塞探測對碼率自適應也十分關鍵。比較傳統的網絡擁塞探測算法是根據網絡丟包率來探測網絡擁塞的。然而,當發生較大規模丟包的時候才提示網絡擁塞,網絡擁塞已經發生了,這時候纔來調整碼率已經太晚了。

拿地震預報舉例子。如果等到發現桌子電燈搖晃的時候才“預報”說有地震,“預報”的時機太晚了。如果發現老鼠或者飛禽逃走等異常情況,或者探測到地震波,就真正做到預報地震。

現代的網絡擁塞算法也是力求做到預報擁塞的效果。一般的做法是,發送端發送一些探測數據包,接收端監控數據包的延遲時間和緩衝隊列長度。當探測數據包經過網絡擁塞節點的時候,延遲時間會變長而且不穩定。如果發現探測數據包的延遲時間變大或者出現異常波動,或者緩衝隊列變長了,那麼網絡擁塞很可能將要出現,相應地可以降低碼率來適應網絡情況的變化。另外,也有通過濾波器來進行網絡擁塞預測,當濾波器的某些特徵超過一定的閾值,就預示網絡擁塞將要發生。

 

帶寬分配

 

碼率自適應 ABC 模塊估算出帶寬以後,發送端把帶寬分配給原始數據包、FEC 校驗包和 ARQ 重傳包,這裏需要一個智能的帶寬分配策略。帶寬分配策略是根據網絡情況,包括 RTT 和 PLR 等因素,來給原始數據包和冗餘數據包分配帶寬。冗餘數據包的帶寬分配得越多,QoS 信道保護算法的糾錯能力就越強,然而原始數據包就相應分配得越少,語音視頻的質量也就相對降低。相對而言,冗餘數據包的帶寬分配得越少,QoS 信道保護算法的糾錯能力就越弱,然而原始數據包的帶寬分配越多,語音視頻的質量也就相對得到保障。因此,智能的帶寬分配策略是要在語音視頻的質量和 QoS 信道保護算法的糾錯能力之間尋找平衡點。

一般來說,帶寬分配的策略可以按照下面的方法進行:

1)總共的帶寬由碼率自適應 ABC 模塊估算得出;

2)丟包重傳 ARQ 的重傳數據包所佔帶寬根據 RTT 和 PLR 估算得出;

3)前向糾錯 FEC 的校驗數據包所佔帶寬根據 RTT,ARQ 恢復後的 PLR,和總共的帶寬估算得出;

4)原始數據包所佔的帶寬根據 ARQ、FEC 和總共的帶寬計算得出。

下面是一個例子,展示隨着 RTT 和 PLR 的增加,如何在原始數據包、ARQ 和 FEC 之間分配帶寬。

 

智能的帶寬分配策略示例

 

上圖中左邊的座標系中,縱座標是帶寬,橫座標是 RTT。在 RTT 比較小的網絡情況下,ARQ 分配的帶寬比較多,不採用 FEC;在 RTT 比較大的情況下,FEC 分配的帶寬比較多,不採用 ARQ。不管使用 ARQ 還是 FEC 冗餘數據包進行信道保護,原始語音視頻數據所佔的帶寬都要適當犧牲。

上圖中右邊的座標系中,縱座標是帶寬,橫座標是 PLR。在 PLR 比較小的網絡情況下,ARQ 和 FEC 冗餘包分配的帶寬都比較小,甚至沒有;在 PLR 比較大的網絡情況下,逐漸給 ARQ 和 FEC 增加帶寬來增強數據糾錯能力,原始語音視頻數據所佔的帶寬也相應降低。

 

結語

 

實時語音視頻通話要獲得超低延遲,不能僅僅依靠在各個環節不斷地優化,而是要通過 FEC、ARQ 和碼率自適應構建實時通訊機制。在這個基礎上,還要充分考慮網絡情況、實時要求和成本因素,以及需要大量經驗數據的支撐(比如說,PLR 和 RTT 的關鍵閾值等)。

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