談談弱網絡環境下的視頻傳輸

所謂的弱網絡環境就是網絡不是很好,比如無線wifi,跨多層網絡路由、或者網路負載過大等等情況。這樣數據在傳輸種會發生丟失的情況。

再說,網絡協議,傳輸層分udp和tcp.本人對tcp做了專門的分析。見下圖。


看圖,我只開了開了2%的丟包,導致發送速度從>500Mb/s下降到 <160Mb/s。速度下降比率達70-80%,發生這個現象的原因是TCP的擁塞處理,當發現網絡丟包的時候,就啟動擁塞控制機制,降低發送速度,達到tcp可靠性傳輸的目的。大于大數據和視頻的傳輸,速度在傳輸成降低這么多,很難滿足應用層的需求,如果是視頻就會導致視頻的卡頓。因為接收端收不到需要的視頻幀,只有停下來花更多的時間等待。實時上筆者在實際開發視頻傳輸的時候使用過tcp,在我無線網絡的情況下,tcp確實特別容易卡頓。關于tcp擁塞控制,大家可以搜索查閱相關的資料,這個不做細說。

筆者用的丟包工具是clumsy0.2。


我們查明了tcp卡頓的原因后,決定放棄tcp,那只有udp了,但是udp又不可靠,會有丟包和亂序的問題,導致視頻播放的花屏,這個花屏是因為關鍵幀或者參考幀丟失了,導致后界的視頻無法正常的恢復,從而出現花屏。于是有查閱了相關的資料,找到了一個udt 協議。

關于udt協議,網上的說明如下:

基于UDP的數據傳輸協議(UDP-based Data Transfer Protocol,簡稱UDT)是一種互聯網數據傳輸協議。UDT的主要目的是支持高速廣域網上的海量數據傳輸,而互聯網上的標準數據傳輸協議TCP在高帶寬長距離網絡上性能很差。顧名思義,UDT建于UDP之上,并引入新的擁塞控制和數據可靠性控制機制。UDT是面向連接的雙向的應用層協議。它同時支持可靠的數據流傳輸和部分可靠的數據報傳輸。 由于UDT完全在UDP上實現,它也可以應用在除了高速數據傳輸之外的其它應用領域,例如點到點技術(P2P),防火墻穿透,多媒體數據傳輸等等。

??? 按照這個及時他是基于udp的協議,又是可靠的,那么是否不會有tcp丟包擁塞的問題。

于是對udt協議做了測試,利用其項目代碼里面的demo測試。

udp是開源的項目,下載地址是:https://sourceforge.net/projects/udt/。目前是udt4.


如下圖是沒有丟包干擾的情況下的發送截圖:


開了丟包干擾又會如何呢,見下圖。


我們看到udt 協議也是一樣的開了丟包干擾后速度下降更多。那為什么呢,不是說udt是基于udp的協議,而udp不會發生擁塞控制么?為此筆者閱讀了udt的代碼,發現他就是在udp的基礎上做加了應答處理,讓udp變得可靠,當然也有“擁塞控制算法”,只不過是應用層的,筆者認為由于這個控制算法是基于應用層的,而且發展的時間,使用的頻率都沒有tcp長,所有在發生擁塞的時候的表現自然要弱于tcp很多。

那么筆者又想到一個問題,那為什么要有udt協議呢?直接使用tcp不是挺好么?筆者又查閱了資料,其實在此文關于udt介紹里面就有答案:由于UDT完全在UDP上實現,它也可以應用在除了高速數據傳輸之外的其它應用領域,例如點到點技術(P2P),防火墻穿透,多媒體數據傳輸等等。udt就是為了做p2p翻墻容易 和 傳輸可靠而已。

至此,關于本文標題的答案探索,似乎走向了死角,所有的探索都失敗了。在筆者不屑的努力下,終于又柳暗花明。


筆者查到了webrtc項目關于抗丟包處理策略,簡稱為QOS-FEC-NACK技術,FEC 中文意思是向前糾錯。NACK 是選擇性重傳,QOS 是處理亂序問題?;谶@樣一整套在應用層的丟錯重傳機制,最大程度了保證了視頻的傳輸的可靠性。下面筆者分別來介紹這個技術。

首先介紹FEC(Forward Error Correction),FEC算法的原理,參見這個博客https://blog.csdn.net/u010178611/article/details/82656838。這里貼出其博客的全文。

筆者經過半年的技術攻關開發出了QOS-NACK-FEC抗丟包傳輸協議,可以加群了解。



閱讀了FEC的糾錯原理后,筆者有了疑問:FEC生成冗余包大小跟原始包是一樣的,那么實際上是增加了傳輸的數據量,發生丟包的時候,為什么還要增加數據量。筆者做了一個計算。加入一個視頻幀有100個包,生成了10個冗余包,傳輸的時候會丟到9個包,那么視頻還會恢復。但是如果沒有這10個冗余包,即使只丟一個包視頻也無法恢復。這就是FEC的好處,在一定數量的丟包的情況下,可以快速的恢復視頻,因為不用請求重傳,所以恢復速度快。只有當丟失過多,比如丟失了11個包,無法恢復的時候,需要請求重傳。

NACK是丟包請求重傳,下面介紹一下其實現原理,和系統框架設計。

NACK可以放置在原來的FEC-QOS傳輸層之外,作為上層應用層,這種實現方式NACK將FEC-QOS看做普通的UDP傳輸,二者并無緊密結合,其優勢是可以與成熟的NACK方案無縫銜接。我們知道任何NACK方案都必將引入延時抖動,因為接收端在發起重傳請求后,需要等待發送端重新發出的數據,在“重傳等待時間”內不對外輸出數據。而QOS階段里為解決UDP亂序包的問題也引入了一個“丟包等待時間”,當遇到包序號不連續時,將等待這一時間,若仍未收到所需的包則認定丟包,不再等待。如果將這兩個時間合二為一,可以盡量的降低系統時延和抖動,畢竟我們需要的是一個高實時性的NACK傳輸方案。我們將NACK的發起和等待放置在QOS之中,入下圖所示:


圖1 在QOS中實現NACK發起

當QOS檢測到序號不連續時,可能是發生丟包或者是亂序,此時QOS將通過FEC解碼模塊分析當前疑似丟包是否將導致FEC無法恢復。此時將產生三種分析結果:

A、當前丟包即使丟了也不影響FEC恢復,比如當前丟失的包為一個或者多個冗余包,且該冗余包所在的group內的媒體包均已接收,或者借助已接收的冗余包足夠恢復。

B、當前丟包不能確定是否影響FEC恢復,需要接收更多的包才能確定。比如丟包發生在group的中段且丟的數量小于冗余包總數。

C、當前丟包將導致FEC確定無法恢復,比如同一個group內丟失的包數大于冗余包總數。

對于情況A,QOS將直接不予等待,將后續接收的包直接交與FEC。對于情況B,QOS將進入“丟包等待時間”,以期收到亂序的包。對于情況C,QOS將發起NACK重傳并進入等待,這個等待時間即是“丟包等待時間”又是“重傳等待時間”,在等待期內不管是該亂序包到達或者重傳包到達,都能滿足FEC的恢復條件。

在介紹了NACK的發起條件后,我們來關注“重傳等待時間”的取值問題。若設置固定的重傳等待時間將很難滿足各類網絡情況。時間過小將導致重傳包尚未到達,QOS已結束等待并輸出后續包,后續即便再收到重傳包也將直接丟棄。重傳包也可能因網絡原因丟包,若“重傳等待時間”過大,將導致更大的延時和抖動。為了提高自適應能力,系統通過實時獲取當前網絡的UDP通訊RTT時間來作為“重傳等待時間”的參考,計算出合理的值。

三、信令通道與媒體通道分離

我們使用獨立的一個UDP信令通道用來傳輸NACK請求,而不是復用媒體通道。這樣做的主要考慮是:

A、媒體通道上使用的FEC\QOS將必然引入部分延時和抖動(具體參見FEC\QOS原理說明),NACK請求對于時間特別敏感,希望是越早越快通知對方越好。在信令通道上我們將只進行裸UDP收發,不會加入FEC和QOS。

B、避免出現NACK請求包丟失后也發起NACK重傳請求的情況。

C、更好的兼容性,對于不支持NACK的節點,只需要忽略信令通道的內容即可與NACK節點互通。

D、程序實現上更加簡潔,無需在媒體通道上新增包類型來區分哪個包是NACK請求包。媒體包上增加字節也都會直接轉化為帶寬的增長。

四、實現流程

方案的實現流程如下圖所示:


圖2 NACK的整體流程

對于傳輸層模塊,它是全雙工的,為演示方便我們只列出單向的情況,另外一個方向也是完全一致的。在FEC編碼之后,所有的發出的UDP(RTP)包均會被存入一個環形緩存區中,當收到遠端NACK請求時,將在下一個媒體包傳輸時觸發重傳動作,后者將在環形緩存區中檢索需要重傳的包并在媒體通道上發出。我們沒有新增內部線程去執行重傳動作,而是借助原本的媒體包發送行為來觸發,這樣可以簡化設計提高穩定性。

檢索過程中我們進行了數據包的合法性校驗和時間戳有效性校驗,當發現當前時間距離數據包初次發送時間的間隔已經較大時,將放棄重傳,因為此時遠端極有可能已經退出等待,沒有必要再浪費帶寬。檢索使用的是RTP頭中的序號字段,需要考慮序號達到最大值時的跳變動作。

有意交流的可以私信留言 微信:Lovexx201709

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容