[轉(zhuǎn)] 音視頻FEC+Qos提升UDP傳輸?shù)膩G包、亂序抵抗力

https://blog.csdn.net/ljh081231/article/details/78892217

實時音視頻領(lǐng)域UDP才是王道 ? ? ??


? ? ? ?在?Internet?上進行音視頻實時互動采用的傳輸層方案有TCP(如:RTMP)和UDP(如:RTP)兩種。TCP協(xié)議能為兩個端點間的數(shù)據(jù)傳輸提供相對可靠的保障,這種保障是通過一個握手機制實現(xiàn)的。當數(shù)據(jù)傳給接收者時,接收者要檢查數(shù)據(jù)的正確性。發(fā)送者只有接到接收者的正確性認可才能發(fā)送下一個數(shù)據(jù)塊。如果沒有接到確認報文,這個數(shù)據(jù)塊就得重傳。盡管這種機制對傳送數(shù)據(jù)來說是非常合理的,但當用它在Internet傳輸實時音視頻數(shù)據(jù)時就會引發(fā)很多問題。首先就是延遲問題,在傳輸信道丟包率較高時,TCP的傳輸質(zhì)量下滑嚴重,重傳擁塞導(dǎo)致音視頻延時非常大,失去實時互通的意義。特別是無線信道(WIFI、4G、3G)下,使用TCP做雙向互通通訊穩(wěn)定性欠佳,易出現(xiàn)音視頻長時間卡住不動然后快放的現(xiàn)象。?

? ? ? 更多的產(chǎn)品選擇采用的協(xié)議是UDP(一般上層應(yīng)用層協(xié)議為RTP,以提供序號和音視頻同步的服務(wù))。UDP同?TCP?相比能提供更高的吞吐量和較低的延遲,非常適合低延時的音視頻互動場合。


UDP傳輸存在的問題:

UDP性能的提高是以不能保障數(shù)據(jù)完整性為代價的,它不能對所傳數(shù)據(jù)提供擔保,常見的問題有包亂序、包丟失、包重復(fù)。無線信道(WIFI、4G、3G)下,UDP包亂序和包丟失可以說是常態(tài)。

關(guān)于包亂序和包丟失的原因,參考諸多文獻總結(jié)如下:

亂序原因:

? ?(A) 路由器的存儲隊列導(dǎo)致的包亂序。

???(B) UDP包據(jù)經(jīng)過不同的路由造成了發(fā)送數(shù)據(jù)的混亂。?

丟包原因:

(A) 當路由器和網(wǎng)關(guān)發(fā)生擁塞時,某些包可能被丟棄,發(fā)生這種情況一般是由于網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)包大于網(wǎng)絡(luò)信道的承載能力。

(B) 分組數(shù)據(jù)在傳送時有生存時間限制以避免路由中死循環(huán)的出現(xiàn),網(wǎng)絡(luò)狀況惡劣時,分組可能超時丟失。

(C) 接收端工作超載運行時可能因調(diào)度困難而不能及時處理網(wǎng)口數(shù)據(jù)。

? ? ? ?視頻碼流的少量丟失都會導(dǎo)致解碼后的視頻出現(xiàn)花屏的現(xiàn)象。H264、HEVC這樣的高壓縮率視頻壓縮標準使得壓縮的冗余度非常低,碼流的丟失除了影響本幀的解碼外,還將影響以此為參考的視頻幀解碼,導(dǎo)致花屏的累積擴散,直至下一個關(guān)鍵幀的到來視頻畫面方能恢復(fù)。雖然解碼器內(nèi)部會做一定的錯誤掩蓋處理,但效果并不理想,特別是采用ffmpeg這類開源的解碼器,其錯誤掩蓋算法做得比較簡單。為此,在很多產(chǎn)品中不得不采用較小的GOP(較小的I幀間隔),以期在出現(xiàn)丟包花屏后能盡快的用I幀碼流刷新畫面。這種方法副作用較大,而且某些場合下甚至會適得其反。因為I幀壓縮效率遠不如P幀、B幀,I幀往往比P幀、B幀大很多,頻繁的I幀將給傳輸信道帶來持續(xù)的波動壓力,造成更嚴重的丟包、亂序。另外,因為編碼器碼率控制的緣故,I幀占用較多的碼流后,緊接著的P、B幀將不得不采用較大的QP量化參數(shù)(較差的圖像質(zhì)量)以保證碼率的局部可控,這樣帶來的直觀感受是圖像隨著I幀間隔周期性的發(fā)虛、馬賽克。亂序的UDP包不經(jīng)過順序恢復(fù)直接送解碼器同樣會導(dǎo)致解碼花屏,因為解碼器內(nèi)部會將遲到的數(shù)據(jù)包丟棄。

? ? ? ?綜上所述,工程中急需一種抗丟包、抗亂序的增強型UDP方案來提升實時音視頻傳輸效果,經(jīng)過多年的積累與完善,我們推出了一套基于RTP并采用FEC前向糾錯和后端QOS處理的完整解決方案,效果非常明顯。

使用FEC\QOS武裝RTP

?對于丟包,我們采用改進型的vandermonde矩陣FEC(Forward?Error/Erasure?Correction)前向糾錯技術(shù)來進行丟包恢復(fù),由發(fā)送方進行FEC編碼引入冗余包,接收方進行FEC解碼并恢復(fù)丟失的數(shù)據(jù)包。

對于包亂序和包重復(fù),我們采用QOS亂序恢復(fù)處理,該QOS方案特點是在沒有丟包的情況下,不引入任何系統(tǒng)延時,并且可以通過可控的丟包等待時延來適應(yīng)不同的信道亂序程度。QOS需要在接收端進行FEC解碼前進行,確保送FEC解碼模塊的數(shù)據(jù)包序號是正確的(不存在亂序,僅存在丟包)。

眾多產(chǎn)品案例表明:采用FEC+QOS+RTP的組合,能顯著提升UDP傳輸?shù)膩G包、亂序抵抗力,為上層音視頻服務(wù)提供有力保障。下圖1是各模塊在系統(tǒng)中的位置說明。


圖1?FEC、QOS在RTP系統(tǒng)中的位置

需要說明如下幾點:

(A)從差錯控制角度看,傳輸信道可以分為隨機信道、突發(fā)信道和混合信道。在隨機信道中,丟包出現(xiàn)是隨機的,且相互統(tǒng)計獨立,滿足正態(tài)分布。在突發(fā)信道中,丟包是集中出現(xiàn)的,在一些短促的時間區(qū)間會出現(xiàn)大量的丟包,而在這些時間區(qū)間之外又存在較長的無丟包區(qū)間?;旌闲诺绖t是上述二者的合體。本方案側(cè)重于對具備隨機信道特性的傳輸鏈路進行改進優(yōu)化。

? ? ? ?對?Internet信道的丟包特性研究發(fā)現(xiàn),大多數(shù)情況下其滿足隨機信道的特點,丟失的都是單個包。連續(xù)兩個或以上包同時丟失的概率雖然比純隨機過程要高,但發(fā)生的概率還是要比單包丟失低,發(fā)生連續(xù)丟失10個以上包的概率就更低了。由于單包丟失出現(xiàn)的最頻繁,我們的抗丟包方案主要側(cè)重于對單包丟失的修復(fù),同時也應(yīng)該兼顧連續(xù)丟失的少量包的修復(fù)。對大量連續(xù)丟失的包的修復(fù)相對來說就顯得不那么重要了(出現(xiàn)概率低,修復(fù)的代價大)。

(B)當然,任何差錯控制方案都是有其最大糾錯能力限制,當丟包率超出當前系統(tǒng)的糾錯能力時,丟包無法恢復(fù),對于視頻應(yīng)用來說意味著視頻將出現(xiàn)花屏。

? ? ? 為了改善系統(tǒng)在高丟包率下的用戶體驗,避免長時間花屏無法刷新的現(xiàn)象,我們建議使用者采用ARQ(自動請求重發(fā))+FEC機制,這里的ARQ請求并不是請求遠端重發(fā)丟失的數(shù)據(jù)包,因為那樣相當于走了TCP這類內(nèi)嵌ARQ功能協(xié)議的老路,必然引入不可控的延時。這里的ARQ只是請求遠端即刻編碼視頻關(guān)鍵幀,避免長時間花屏無法刷新的現(xiàn)象,ARQ請求一般通過額外的TCP信道發(fā)出(在絕大多數(shù)的系統(tǒng)中,通訊雙方一般會有TCP的信令通道,用于雙方業(yè)務(wù)層信令的交互)。ARQ的發(fā)起是根據(jù)FEC解碼輸出視頻碼流是否丟包作為判斷依據(jù),發(fā)送端和接收端都需要對ARQ的頻率做一定的保護措施,避免頻繁的發(fā)起和響應(yīng),造成過多的I幀(過多I幀的副作用前面已有列舉)。

測試效果

本方案為C++開發(fā),提供PC、Android(JNI)、IOS跨平臺的支持。為了方便測試,我們在PC下開發(fā)了幾個簡易測試DEMO用于驗證演示。

(A)數(shù)據(jù)驗證DEMO

下圖所示為數(shù)據(jù)驗證DEMO界面,它以指定的數(shù)據(jù)作為測試源,可幫助用戶更好的理解處理流程。

圖2 ?數(shù)據(jù)流程驗證DEMO

測試工具為點對點工作模式,可在兩臺PC上各自運行(同時也支持單機模式,只需將收發(fā)IP地址均設(shè)置為本地IP即可),以實現(xiàn)雙方之間RTP(FEC+QOS)通訊。

? ? ? ?軟件收發(fā)自定義的測試包數(shù)據(jù),提供了模擬丟包功能,支持按固定間隔丟包或者按隨機比率丟包;支持設(shè)置FEC冗余度或者選擇冗余度自適應(yīng),支持設(shè)置QOS丟包等待時延等參數(shù)。

? ? ? ?測試工具內(nèi)部默認使用10個媒體包外加冗余度(數(shù)量由選擇的冗余度決定)作為一個GROUP,當選擇冗余度20%時,一個GROUP由10個媒體包附加2個冗余包組成。下圖是Wireshark的觀察情況,10個媒體包后面緊接著2個冗余包。

圖3 Wireshark觀察冗余包情況

需要說明的是:程序主動丟包是在UDP發(fā)送層進行,所以即可能丟媒體包也可能丟冗余包。

下面我們以20%冗余度為例說明系統(tǒng)對各類丟包率的抵抗能力。

? ? ? ?當選擇每10個包丟1個包時(丟包率10%),一個GROUP中最多只會丟棄1個包,20%的冗余度足夠抵抗這一丟包率,測試結(jié)果也驗證了這一結(jié)論,接收到的所有媒體包序號均保持連續(xù),丟包率從10%降為0%,實驗情況如上圖2所示。

當選擇每5個包丟棄1個包時(丟包率20%),丟包情況如下圖4所示:

圖4每5個包丟棄1個包時的情況

對于第一個GROUP,一共丟棄了三個包,包括0號媒體包、5號媒體包、0號冗余包。因為接收的媒體包數(shù)為8個加接收的冗余包數(shù)1個,總數(shù)小于總媒體包數(shù)(10個),因此接收端FEC無法恢復(fù)。對于第二個GROUP,只丟失了兩個媒體包,可以正?;謴?fù)。實驗結(jié)果如下圖5所示,說明了推斷的正確性,0號媒體包、5號媒體包丟失,13號、18號媒體包被成功恢復(fù),系統(tǒng)丟包率從20%降低到10%左右。


圖5 ?20%冗余度時,每5個包丟棄1個包時的恢復(fù)情況

(B)音視頻實測DEMO

圖6 音視頻實測DEMO

本DEMO支持如下特性:

(1)使用Direct進行攝像頭、麥克風的采集和輸出

(2)使用ffmpeg進行高效圖像縮放等前置filter

(3)視頻H264?HighProfile編碼、解碼

(4)音頻AAC-LC、AAC-LD、AAC-ELD編碼、解碼(三種標準可選,44.1KHZ?16bit?2通道立體聲)

(5)音視頻RTP傳輸(帶FEC\QOS功能)

(6)人為丟包測試功能

(7)實時統(tǒng)計輸出線路丟包延時情況

DEMO的內(nèi)部框架如下圖7所示:

圖7 ?DEMO內(nèi)部線程框架

在視頻采集縮放線程與視頻編碼線程之間,我們采用高效的雙隊列機制(隊列元素為指針,進出隊列無數(shù)據(jù)拷貝),如果視頻編碼性能非常充足的情況下,我們也可以將二者合并為一個線程。編碼線程與網(wǎng)絡(luò)發(fā)送線程分離,避免網(wǎng)絡(luò)擁塞影響編碼線程(這個對于UDP來說不成立,但對于RTMP這類TCP系統(tǒng)來說,網(wǎng)絡(luò)收發(fā)線程與音視頻編解碼線程的分離是必須的,因為網(wǎng)絡(luò)的抖動將影響音視頻處理環(huán)節(jié)。站在系統(tǒng)設(shè)計的角度,我們?yōu)閁DP和TCP統(tǒng)一使用上述架構(gòu))。

在音視頻發(fā)送模塊內(nèi),我們都配有定時握手包發(fā)送線程,這個線程與音視頻使用相同的發(fā)送通道(端口),僅在包頭上予以區(qū)別。它的作用非常重要,主要包括兩個方面:為NAT穿越提供保障,當我們的客戶端(內(nèi)網(wǎng)IP)向服務(wù)器(公網(wǎng)IP)發(fā)送數(shù)據(jù)時,鏈路路由器會為該通訊鏈路映射“端口”,這樣服務(wù)器(公網(wǎng)IP)向該客戶端發(fā)送數(shù)據(jù)時,只需將收到的數(shù)據(jù)包的IP地址和端口翻轉(zhuǎn)作為發(fā)送目標IP和端口便能向其發(fā)送數(shù)據(jù)。路由器在收到服務(wù)器的數(shù)據(jù)包時,檢查本地存在對應(yīng)的映射“端口”,予以放行,否則將丟棄這一數(shù)據(jù)包(這是基于安全的考慮,外網(wǎng)向內(nèi)網(wǎng)發(fā)送數(shù)據(jù)不得不防)。值得注意的是,路由器上“端口”是有時效性的,超過一定時間即會失效,為了保證服務(wù)器能持續(xù)有效的向客戶端發(fā)送數(shù)據(jù),客戶端必須以心跳包的方式向服務(wù)器發(fā)送數(shù)據(jù)以保持“端口”的有效性(客戶端根據(jù)業(yè)務(wù)情況不一定向服務(wù)器持續(xù)發(fā)送數(shù)據(jù)包,可能只作為接收者)。以上是對C/S模式下NAT的簡要描述,P2P模式等其他情況請參考專門的資料。定時握手包的另一個作用是傳輸自定義的信道統(tǒng)計數(shù)據(jù),這個類似于RTCP協(xié)議,接收方統(tǒng)計出下行丟包率后可以通過本握手包告知發(fā)送方,以便通知對方調(diào)整發(fā)送甚至編碼策略。

音頻的處理流程與視頻類似,因為音頻編碼耗時非常低,我們一般將音頻采集與編碼放到一個線程內(nèi)進行。音頻的輸出與視頻不同,因為它需要按固定的輸出頻率工作,驅(qū)動將發(fā)起定時輸出線程,我們只需要在該線程內(nèi)向指定內(nèi)存存入指定數(shù)量的PCM數(shù)據(jù)即可。(輸出頻率、存放數(shù)量由音頻輸出通道數(shù)、采樣率、采樣點字節(jié)數(shù)的配置而定)

若本地IP與遠端IP設(shè)置一樣,DEMO則進入本地回環(huán)模式,此時將不存在任何網(wǎng)絡(luò)丟包,我們可以通過設(shè)置手動丟包來模擬測試。若本地IP與遠端IP不同,且不屬于同一網(wǎng)段,我們可以使用開源的WANEM來進行模擬丟包、延時、抖動、重復(fù)包等情況,這一方式后面我們將專門予以介紹。

注意:真實的視頻對比效果請?zhí)D(zhuǎn)視頻對比效果觀看

?圖8 使用4%隨機丟包,關(guān)閉FEC時經(jīng)常性花屏,聲音間歇斷續(xù)

當使用4%隨機丟包時,若關(guān)閉發(fā)端FEC功能,接收端視頻將出現(xiàn)經(jīng)常性花屏,聲音出現(xiàn)丟失斷續(xù)。若使用20%冗余度,視頻花屏概率將大幅降低(不會完全消除,因為丟包是隨機的,短時間內(nèi)可能出現(xiàn)連續(xù)大量丟包的情況,超過20%冗余度的無失真抗丟包率是16.67%即會出現(xiàn)花屏)

若使用按間隔丟包,每6個包丟一個(丟包率將恒定為16.67%),此時選擇20%冗余度可以實現(xiàn)無失真恢復(fù),視頻流暢無花屏,音質(zhì)良好無斷續(xù)。

圖7 使用16.67%恒定丟包,F(xiàn)EC使用20%冗余度時音視頻效果良好

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容