iOS 边学边记 直播SRT、UDT协议详解
什么是SRT協議?
概述
SRT協議是基于UDT的傳輸協議,保留了UDT的核心思想和機制,抗丟包能力強,適用于復雜的網絡。在LiveVideoStack線上分享中,新浪音視頻架構師 施維對SRT協議的原理、優缺點特性以及在流媒體中的應用進行了詳細解析。
UDT
UDT是基于UDP的數據傳輸協議(UDP-based Data Transfer Protocol,簡稱UDT)是一種互聯網數據傳輸協議。UDT的主要目的是支持高速廣域網上的海量數據傳輸,而互聯網上的標準數據傳輸協議TCP在高帶寬長距離網絡上性能很差。 顧名思義,UDT建于UDP之上,并引入新的擁塞控制和數據可靠性控制機制。UDT是面向連接的雙向的應用層協議。它同時支持可靠的數據流傳輸和部分可靠的數據報傳輸。 由于UDT完全在UDP上實現,它也可以應用在除了高速數據傳輸之外的其它應用領域,例如點到點技術(P2P),防火墻穿透,多媒體數據傳輸等等。
-
UDT協議是什么?
是一種基于UDP的數據傳輸協議(UDP-based Data Transfer Protocol,簡稱UDT)。
-
UDT協議的主要作用是什么?
UDT的主要目的是支持高速廣域網上的海量數據傳輸,而互聯網上的標準數據傳輸協議TCP在高帶寬長距離網絡上性能很差。 -
那么UDT與UDP的區別又是什么?
UDT建于UDP之上,并引入新的擁塞控制和數據可靠性控制機制。UDT是面向連接的雙向的應用層協議。它同時支持可靠的數據流傳輸和部分可靠的數據報傳輸。 -
UDT的使用場景是什么?
由于UDT完全在UDP上實現,它也可以應用在除了高速數據傳輸之外的其它應用領域,例如點到點技術(P2P),防火墻穿透,多媒體數據傳輸等等。 -
UDT協議的主要特性有哪些?
- 基于UDP的應用層協議: 有基本網絡知識的朋友都知道TCP和UDP的區別和使用場景,但是有沒有一種協議能同時兼顧TCP協議的安全可靠和UDP協議的高效,那么UDT就是一種。
- 面向連接的協議:面向連接意味著兩個使用協議的應用在彼此交換數據之前必須先建立一個連接,當然UDT是邏輯上存在的連接通道。這種連接的維護是基于握手、Keep-alive(保活)以及關閉連接。
- 可靠的協議:依靠包序號機制、接收者的ACK響應和丟包報告、ACK序號機制、重傳機制(基于丟包報告和超時處理)來實現數據傳輸的可靠性。
- 雙工的協議:每個UDT實例包含發送端和接收端的信息。
- 單播的數據流
- 新的擁塞算法,并且具有可擴展的擁塞控制框架:新的擁塞控制算法不同于基于窗口的TCP擁塞控制算法(慢啟動和擁塞避免),是混合的基于窗口的、基于速率的擁塞控制算法。可擴展的擁塞控制框架開源的代碼和擁塞控制的C++類架構,可支持開發者派生專用的擁塞控制算法。
- 帶寬估計:UDT使用對包(PP -- Packet pair)的機制來估計帶寬值。即每16個包為一組,最后一個是對包,即發送方不用等到下一個發送周期內再發送。接收方接收到對包后對其到達時間進行記錄,可結合上次記錄的值計算出鏈路的帶寬(計算的方法稱為中值過濾法), 并在下次ACK中進行反饋。
-
UDT支持哪些數據傳輸類型
-
基于流的send, recv。
-
基于數據報sendmsg,recvmsg。
-
文件傳輸sendfile,recvfile。
-
-
UDT的其他特點
-
不和原生socket api沖突;
-
線程安全;
-
進程間不共享句柄;
-
錯誤處理;
-
防火墻穿透;
-
安全性好;
-
建立連接快速;
-
-
UDT有兩種包:
-
數據包
-
控制包
-
-
UDT在接收端使用4個定時器來觸發不同的周期事件:
-
RC定時器(原文為SND定時器)
用來觸發周期性的速率控制。
-
ACK定時器
用來觸發應答包(ACK)
-
NAK定時器
用來觸發丟失包應答(NAK包)
-
EXP定時器
用來觸發一個數據包的重傳和維護連接狀態
-
SRT
SRT是(Secure Reliable Transport)的簡稱,SRT由Haivision和Wowza合作成立的,管理和支持SRT協議開源應用的組織,這個組織致力于促進視頻流解決方案的互通性,以及推動視頻產業先驅協作前進,實現低延時網絡視頻傳輸。
-
SRT協議特點
- 安全
SRT支持AES加密,保障端到端的視頻傳輸安全。 - 可靠
SRT通過前向糾正技術(FEC)保證傳輸的穩定性。 - 延遲低
由于SRT建立在UDT協議之上,解決了UDT協議傳輸延遲高的問題。(前面部分為UDT)
- 安全
SRT解決了復雜的傳輸時序問題,可以做到支持高吞吐量文件和超清視頻的實時傳輸。
-
為什么選擇SRT?
毋庸置疑,現今存量最大的直播協議是RTMP,但隨著新技術的不斷發展與使用場景的不斷拓展,繼續使用RTMP會令人感到有些力不從心。RTMP協議的缺陷主要有以下四個方面:- 協議太老,不再更新
- rtmp over tcp 鏈接過程長
- rtmp擁塞控制完全依賴傳輸層
- 無法實現自適應帶寬編碼
-
SRT協議的特點
- 基于UDT來自Haivision
- 良好的丟包重傳機制
- 基于時間的報文發送
- 豐富的擁塞控制統計信息
-
SRT基本思想
通過協議中精準的時間戳,解決公網傳輸幀間隔不固定。
規定延時量,和劃定send buffer (發送端緩沖區)和receive buffer (接收端緩沖區)。
對接受端的反饋信號進行一系列設置、糾錯、流量控制,使編碼后的音視頻碼流擁有與源碼流一樣的碼率特性。
整個SRT協議思想基于編碼,具有抗丟包、抗擁塞、抗抖動等特性。
-
SRT的交互過程
- 握手(Handshake)
- 重要信息(Capability)
- 媒體(Media)
- 控制信息(Control)
- 關閉(Shutdown)
-
SRT的數據報文
每個承載SRT的UDP報文都帶有SRT頭(其緊跟在UDP頭后面)。在所有的協議版本中,SRT頭包含4個32bits字段:-
PH_SEQNO
-
PH_MSGNO
-
PH_TIMESTAMP
-
PH_ID
SRT有兩類報文,PH_SEQNO字段的第一個bit用來標識報文類型,0是數據報文,1是控制報文。(不做詳解)
-
-
SRT丟包重傳
-
Send/Receive Buffer
SRT在接收和發送端都有receive buffer與send buffer,send Buffer嚴格按照時間戳間隔來發送,定時器默認10毫秒。
-
ACK
大概解釋一下ACK機制。發送端緩沖區發送n個數據包給接收端緩沖區,接受端緩沖區在成功接受到這些數據包之后想發送端緩沖區發送ACK信號,表示已經成功接受數據包,發送端在收到ACK后回收空間,刪除已發送的包,并準備發送其他的包。 -
ACK/ACKACK/RTT
- ACK是接收端收到包之后發送的信號。
- ACKACK是發送端在收到接收端發送的ACK之后,自己向接收端發送的ACK,所以兩個ACK一個是接收端的,一個是發送端的。
- RTT是ACK發送時間t1到收到ACKACK時間t2,的時間差(t2 - t1 = RTT)。表示報文一個來回的耗時
-
ACK信息
- Last Acknowledge Packet Sequence Number:當前收到第幾個包
- RTT:RTT的變化表示網絡變化情況
- Available Buffer Size:表示接收端緩存可用率,SRT是可以用作文件傳輸的,Available Buffer Size對文件傳輸的擁塞控制非常有用。
- Packets Receiving Rate:表示每秒鐘的收包率,這里統計的是包的個數。
- ReceivingRate:表示接收包的比特率。
-
NACK
常規情況下QUIC或TCP僅提供ACK方式,也就是接收端向發送端反饋哪些包成功接收;而WebRTC的RTP或RTCP常用選擇NACK,也就是接收端向發送端反饋哪些包沒有成功接收。NACK回傳的是接收端沒收到的數據包的列表。SRT同時支持ACK與NACK,這樣設定的原因在我看來是帶寬搶占的強勢。例如,接收端向發送端發送ACK表示該數據包已經成功接收,不排除該ACK報文本身丟失,導致發送端以為數據報文丟失而要超時重發,實際接收端對該數據包已經成功接收了。
還有一種情況是:NACK的周期性發送可能會造成發送端多發報文,例如發送端成功發送5號與6號數據包,卻一直未收到來自接收端的ACK消息,當達到重發的時間時發送端再次發送5號與6號數據包,在此之后發送端收到了來自接收端的NACK消息,表示接收端未成功接收5號數據包與6號數據包;于是發送端第三次發送5號數據包與6號數據包。一個周期下來,發送端發了兩次數據包。從協議原理角度分析,我們發現 SRT在丟包過程中對帶寬的消耗比QUIC與其他協議要高。 一旦出現丟包,SRT的重傳要多于其他協議,SRT以此來搶占帶寬從而達到音視頻的同步效果。
-
-
SRT基于時間發送
按時間發送是一個標準的音視頻傳輸特性。我們知道編碼器發送是以編碼器的速度向外發送數據,但有時編碼器會太樂觀,完全按照編碼輸出向外發送會導致輸出超過預期過高的比特率。在這種情況下SRT Packet就不會足夠快地輸出,因為SRT會最終被過低的錯誤配置影響到。
-
可配置比特率
SRT中包含三個配置選項:INPUTBW表示編碼器輸入帶寬,MAXBW表示最大帶寬,以及OVERHEAD(%)表示過載率,配置原則如上圖所示:
如果不配置INPUTBW與OVERHEAD(%)而僅配置MAXBW,則當前編碼器輸出的比特率是<mbw>也就是MAXBW;
如果不配置MAXBW與INPUTBW而僅配置OVERHEAD(%),則當前編碼器輸出的比特率是(1080+<oh>)/100,默認為25%;
第三種情況是不配置MAXBW而配置OVERHEAD(%)與INPUTBW,最大輸出比特率便為<ibw>(100+<oh>)/100。
SRT最大的特點便是可配置。在有配置的情況下按照配置來做,在無配置的情況下按實際測量的比特率來做。常規情況下我們不選擇進行配置,尤其是針對互聯網而言,因為單一配置無法保證能夠在不同時段應對不同境況的網絡。通常我們選擇使用實際測量出的編碼比特率計算:<smpinpbw>*(1080+<oh>)/100。
-
SRT簡單擁塞控制——簡單,太簡單
接下來我們討論一下SRT的流控。我們知道在丟包重傳機制下,如果報文在網絡傳輸中丟失,則發送端會重新發送。例如在某網絡環境下發送端與接收端之間的帶寬僅有1M,現在由于背景流量與噪聲等影響,原來1M的帶寬減少100k變成了900k,此時就會出現10%的丟包;發送端未收到來自接收端的ACK或者收到NACK認為出現丟包,于是嘗試重傳這10%的數據;但實際上發送端與接收端之間的帶寬就剩下900k了,而加上丟包重傳的發送量是1.1M,帶寬變窄發送的流量不降反增,就會導致網絡情況越來越糟糕,最后造成網絡擁塞卡頓頻繁,最后網絡崩潰。SRT單純地丟包重傳不能解決網絡擁塞的問題,出現網絡擁塞的最好解決方案是限流,降低帶寬流量壓力。
SRT的擁塞控制過于簡單,僅在congctrl.cpp中實現。其包括以下幾個變量:
- M_iFlowWindowSize表示接收方的緩存大小,
- m_dCWndSize等于1秒內發送的bytes數據 / (RTT + 10),
- sendbufer表示發送方未發送buffer大小。其中這里的1秒內發送的bytes數據,具體是指一個RTT內發送的數據。
總結算法如下:m_iFlowWindowSize用以衡量接收方緩存是否耗盡,同時監測發送方每RTT發送數據size是否大于發送buffer大小。接收方緩存一般在傳輸文件時起作用。
-
SRT協議總結
SRT在快速連接方面有明顯優勢,兩次握手成功即可建連;SRT的丟包重傳策略出色,ACK、ACKACK、NACK等提供了豐富的控制消息,還有RTT、Receive比特率等。但是同時我們經過測試也發現SRT在丟包時,發送數據的帶寬占用率還是有些大,丟包率越高發送帶寬占用越大。
SRT按照時間發送音視頻數據,根據實際的編碼比特率來發送音視頻數據;但SRT的擁塞控制過于簡單,只針對接收方緩存是否有能力接收與編碼比特率是否發送過快。
-
SRT推流
我們推薦從編碼器到推流至邊緣節點的部分使用SRT。其目的主要有兩個:提高源流質量與基于SRT自適應比特率編碼,發送端和接收端配合從而解決最后一公里的推流問題。是自己對SRT的理解。SRS支持 SRT的接收端推流,邊緣SRS在接收到來自推流端的SRT推流之后會將其轉為RTMP并分發給中央節點,而后所有的邊緣節點都可以進行RTMP拉流。
總結
以上是生活随笔為你收集整理的iOS 边学边记 直播SRT、UDT协议详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跟周鸿祎学互联网思维 ——《周鸿祎自述|
- 下一篇: 瑞星杀毒软件爆出高危漏洞 可被利用为“抓