• <strike id="fdgpu"><input id="fdgpu"></input></strike>
    <label id="fdgpu"></label>
    <s id="fdgpu"><code id="fdgpu"></code></s>

  • <label id="fdgpu"></label>
  • <span id="fdgpu"><u id="fdgpu"></u></span>

    <s id="fdgpu"><sub id="fdgpu"></sub></s>
    您當前的位置是:  首頁(yè) > 資訊 > 文章精選 >
     首頁(yè) > 資訊 > 文章精選 >

    拆解SRT:新UDP視頻傳輸協(xié)議

    2019-12-10 13:36:27   作者:文 / Alex Converse 譯 / Adrian Ng   來(lái)源:CTI論壇   評論:0  點(diǎn)擊:


      本文來(lái)自Twitch視頻工程師Alex Converse在San Francisco Video Technology Meetup 2019 的分享。其分享集中于SRT協(xié)議的起源,以及如何在頗具挑戰的網(wǎng)絡(luò )上基于UDP傳輸實(shí)時(shí)視頻。講師也介紹了UDT、open source、SRT聯(lián)盟和SRT的技術(shù)概述,最后分析了SRT數據包、SRT數據包緩沖區和Nak數據包如何容忍packet loss及處理延遲這些問(wèn)題。
      大家好,我是Twitch的視頻工程師,今晚我的演講主題是SRT協(xié)議的內幕。在過(guò)去,我看過(guò)許多關(guān)于支持SRT功能的軟解的精彩演講以及它的各種潛能。但是今天,我將掀開(kāi)幕布,看看SRT協(xié)議背后的東西。
      此SRT(Secure Reliable Transport)非彼SRT(SubRip Subtitle:它是一種字幕格式),這個(gè)視頻傳輸協(xié)議可以在具有挑戰性的網(wǎng)絡(luò )之下進(jìn)行直播。它基于UDP的單播(一對一的形式),注重contribution而不是delivery。此外,它也帶來(lái)亞秒可調的constant latency。
      這么說(shuō)吧,可調(tunable)意味著(zhù)你可以配置協(xié)議并調整延遲,可以在數據包的丟失與延遲中做出權衡(trade-off)。一旦開(kāi)始廣播的時(shí)候,延遲即被鎖定,所以不會(huì )因為不同的網(wǎng)絡(luò )的情況而累積更多的延遲,同時(shí),該系統也提供content encryption。
      為什么我覺(jué)得SRT有趣?我們知道RTMP是公共互聯(lián)網(wǎng)上直播視頻的事實(shí)標準;但RTMP已經(jīng)存在了很長(cháng)一段時(shí)間,其標準在2012年最后一次更新過(guò)后就被放棄了。新的Codec標準諸如HEVC或AV1一般都沒(méi)有RTMP標準支持。退一步來(lái)說(shuō),即使有人在RTMP中hack了這些Codec的支持,在移動(dòng)網(wǎng)絡(luò )上RTMP仍然工作的不大好。
      SRT作為RTMP潛在替換技術(shù)的一種,最近正獲得不錯的增長(cháng)勢頭。SRT聯(lián)盟現在有250多名成員,而在最近的一些展會(huì )上,似乎每個(gè)展位都具有 SRT 聯(lián)盟成員或 SRT-Ready貼紙。
      SRT功能在VLC,Gstreamer和Ffmpeg中基本開(kāi)箱即用,對于 OBS Studio 等工具則有些patches正在流程中。SRT 的源于一個(gè)稱(chēng)為 UDT 的舊協(xié)議。UDT在2001年創(chuàng )建,仍然在Source Forge上有網(wǎng)頁(yè),但UDT的設計目標是在公共網(wǎng)絡(luò )上以最短時(shí)間傳輸大型的文件。
      UDT開(kāi)發(fā)者向IETF提交過(guò)幾份草案去描述UDT工作原理。總共有四份草案,最終的IETF草案是在2010年發(fā)布的。之后,UDT的主要開(kāi)發(fā)者繼續在此協(xié)議工作了3年,其實(shí)現的最終版本停留在了2013年。
      Haivision,一家編碼器供應商,采用UDT且將它由file protocol變成一個(gè)live video協(xié)議。在2013年,他們首次在 IBC大會(huì )上使用了UDT,主要是為了演示HEVC的編碼器。
      過(guò)了四年,他們覺(jué)得自己的自定義協(xié)議可能不是創(chuàng )建interoperable ecosystem的最好方式。因此在2017年,他們開(kāi)源了SRT。
      Haivision 與Wowza 聯(lián)合創(chuàng )建了SRT聯(lián)盟,以促進(jìn)發(fā)展及開(kāi)發(fā)SRT。
      2018年初,他們發(fā)布了SRT的v1.3.0更新版本。這是自最初的開(kāi)源以來(lái),對protocol最大型的修改。同時(shí),其版權協(xié)議改成了MPL(Mozilla public license);重新把文件傳輸模式加了回來(lái)。
      在2018年,他們也發(fā)布了SRT Technical Overview(SRT技術(shù)概述),但實(shí)際上更像規范(specification)。該文檔共有89頁(yè),與此對應的RTMP Spec則是52頁(yè)。該文檔描述了各種細節信息,即使是一些競爭對手也承認SRT規范做得非常不錯。
      從高層看,SRT使用的一個(gè)雙向UDP socket,它可以通過(guò)同一個(gè)socket復用數據和控制流。因為沒(méi)有使用TCP,SRT自行實(shí)現了可靠性、有序性和擁塞控制。SRT使用 selective retransmit的方式處理數據包丟失,另外了基于標準加密原語(yǔ)(standard primitives)(而不是DTLS)構建了其獨特的 “unique”加密系統,
      SRT Data Payload支持可分片的有效負載(payload)。在實(shí)踐中,我僅僅看過(guò)它與MPEG transport stream一起使用。整個(gè)傳輸流引入SRT包,每個(gè)傳輸流包都有自己的同步字節和傳輸流頭。我確信這些sync byte 用以對抗丟包以及重新同步。
      在1500-byte Ethernet MTU情況下,如果你試圖放入188-byte的數據包,會(huì )發(fā)現并沒(méi)有足夠的空間可以容納8個(gè)TS包,這也是使用7個(gè)TS包的原因。與此同時(shí),這也可以給SRT Header留出足夠的空間。
      上圖概述了SRT數據包的布局。初起是UDP header, 還有UDT header,實(shí)際上SRT header改自UDT header。
      第一bit是0,表示的是數據包,之后是packet sequence number,它是從握手過(guò)程中確定的random value開(kāi)始的,隨后每一個(gè)packet值都會(huì )增加1。該值用于標識數據包、packet acknowledgement和數據包丟失消息。有個(gè)message number, message number從0算起,會(huì )在我的視頻中每增加一條消息時(shí)候加一,但看起來(lái)沒(méi)什么用,怎么回事呢?
      我們可以看見(jiàn)一個(gè)微秒單位的時(shí)間戳,這是發(fā)送端的運行時(shí)間(elapsed time)。在接收端,它將這個(gè)packet從SRT的緩沖區中播放到下游的TST MUX RN 視頻解碼器中。這個(gè)實(shí)時(shí)視頻的片段與順序總會(huì )是“1 1 0”。1 1 指的的是獨立編號,而消息編號是針對跨多個(gè)數據包分段的信息。但在實(shí)時(shí)視頻模式下,我們只需要盡可能多地填充TS,我們稱(chēng)之為standalone message。
      Ordering flag下的兩個(gè)標志是encryption和retransmission flags;如果出現了什么問(wèn)題,ordering flag可以將其信息無(wú)序交付。Encryption flag會(huì )提醒你正使用的key,而retransmit flag會(huì )告訴你這是否是第一次發(fā)送還是一個(gè)重復的步驟。Retransmitted packets 通常會(huì )保留原始序列號,原始信息號和原始時(shí)間戳。
      SRT的核心理念是發(fā)送方和接收方都同意延遲緩沖時(shí)間,并且他們試圖在數據包開(kāi)始流出接收方時(shí)同步其內容。目前VLC支持現成的SRT,OBS也有了SRT的patch,發(fā)送方所創(chuàng )建的數據包,同時(shí)會(huì )將其放在延遲緩沖區,因為在網(wǎng)絡(luò )中,該包到達接收方需要一段時(shí)間。
      發(fā)送方不斷生成數據包,接收方最終獲得數據包。發(fā)送方再不斷地生成,接收方也繼續接收。如此往復。
      這里展示了一個(gè)不妙的情況,上圖的packet 3已被丟失,到目前為止,沒(méi)人發(fā)現了數據的差錯。本來(lái)期待packet 3,竟然收取了packet 4,它隨即生成negative acknowledgement packet,將packet 4 放入緩沖區,為packet 3 留下一個(gè)空位(hole)。
      發(fā)送方繼續分發(fā)packet,直到下一個(gè)packet送達。突然間sender得到NACK,它發(fā)現接受者丟失了packet 3,因為它把之前發(fā)送的數據包都保存在了buffer,結果,發(fā)送方重新發(fā)送數據包3,它繼續生成數據包;接收方繼續接收數據包。注意,此時(shí)發(fā)送者的buffer現在已裝滿(mǎn)了數據包。
      Packet 1被吐出,直接被丟掉。接收端終于收取到packet 3,它馬上填補之前的空洞(hole),操作恢復正常。接收端buffer最終填滿(mǎn)了指定的packet,隨后把packet 1給了 TS deuxers 和解碼器。
      這是協(xié)議概述中Nak的表示圖。首先有SRT header,因為它是一個(gè)控制包所以1開(kāi)頭,最后是丟失包的列表。
      每一個(gè)丟失list包含一個(gè)或多個(gè)條目。每個(gè)條目要么是一個(gè)single packet,要么是一個(gè)范圍(range),你可在一條消息內說(shuō)丟失了packet 5、9以及11直到15的所有包。
      除了negative acknowledgment,SRT也有positive acknowledgment。接收器每10毫秒發(fā)送一次acknowledgment。每一次收到 ACK,發(fā)送者立即確認ACK以響應之前的ACK,你可以據此估算往返時(shí)間。如果確認之間的數據速率超過(guò)64個(gè)數據包,則接收器將發(fā)送lightweight acknowledgement。此Ack不會(huì )被重新確認,也不包含Ack所接受的元數據類(lèi)型。
      RTT有點(diǎn)不尋常,因為似乎沒(méi)有辦法在不啟動(dòng)新廣播的情況下調整延遲緩沖區的大小,所以對于廣播場(chǎng)景有些限制。
      以上是acknowledgement packet所顯示的Ack/AckAck包。最重要的是最后接收到的packet包序列號,當然還有的是往返時(shí)間,往返時(shí)間的方差,緩沖統計available size和packets,數據包接受速率及數據接收速率。在lightweight Ack,你只需得到序列號,Ack的acknowledgment將會(huì )顯示它正在確認的Ack,以便于你知道在正確的時(shí)間戳做出扣除。
      我們都知道握手(handshake)非常簡(jiǎn)單。在這個(gè)GIF中,Bill Maher 不斷地誤讀Snoop Dogg (史努比。狗狗)的手勢,Snoop Dogg也不斷地嘗試配合Bill,這場(chǎng)景是body language misinterpretation的一個(gè)例子,我認為它適合隱喻SRT handshake的過(guò)程。
      SRT在sender和receiver之間有四次handshakes(因為后向兼容,所以所有版本都支持)。V4 和V5的rendezvous handshake (匯合握手)比較特殊,不在這次講解。
      V5 以及v4最大的區別在于數據包交換的數量。v4共有四次往返;在v5只有兩次往返。
      圖中是packets的布局,其核心思想是左邊的v4使用了未修改的UDT包加上SRT擴展,接著(zhù)是一個(gè)包含所需延遲和初始序列號的SRT握手包,其后的密鑰素材用于對于數據有效載荷進(jìn)行加密,右邊的v5則更將這些信息smush (合拼) 到一個(gè)包中(指V5直接修改了原始UDT包的布局)。
      之后,我們將看到兩方嘗試v5握手,發(fā)起方創(chuàng )建handshake induction packet (握手感應包)。
      其版本號設置為4,但cookie字段并未設置,它將提示初始端在短時(shí)間內獲得cookie,使得響應端不必處理混亂的數據包,而是需要解析其數據包以將某些內容發(fā)送回去;實(shí)際上,響應端接收到該包之后,創(chuàng )建一個(gè)版本5的induction packet,并設置Cookie。
      此時(shí),v4 initiator將忽略v5,并繼續填充v4以及重復改cookie。但是,如果initiator是通過(guò)v5運行,所以它會(huì )在version字段中填寫(xiě) v5程序,加上SRT handshake extension values包括延遲值等。
      Initiator可能在握手的第二個(gè)包產(chǎn)生stream ID,首先填充加密握手,然后responder會(huì )使用latency value 和cyypto handshake進(jìn)行響應。
      在于Stream ID,這是在handshake的第二個(gè)包中所發(fā)送的可選標識符,因為第一個(gè)包是有可能被拋棄掉的。在此會(huì )有個(gè)application-specific parameter,用于通知你initiator想干什么。
      這與RTMP形成一些對比,在RTMP中,你執行TCP握手和RTMP握手。然后,執行帶寬估計之后調用一組RPCs來(lái)設置RTMP媒體流。
      我之前提到過(guò)SRT不使用DTLS。它以自定義方式使用industry standard primitives,可看見(jiàn)它受到到了DVB scrambling的重大影響。DVB是歐洲廣播標準,keying material是由共享密碼短語(yǔ)生成。隨著(zhù)這些retransmits和密鑰旋轉,一次有兩個(gè)密鑰有效。你有一個(gè)偶數鍵和一個(gè)奇數鍵,在這兩個(gè)鍵中你交替使用哪一個(gè),你就在更新。如果你得到重發(fā),你可以參考舊的密鑰。
      規范中的小注釋說(shuō):‘嘿,全數據包加密看起來(lái)是最安全的選擇,但實(shí)際上,加密header在暴力破解時(shí)候卻有點(diǎn)脆弱。最初的MPEG TS 同步字節,其設計可能是不讓你把TS頭加密。事實(shí)上,我們會(huì )嘗試使用快速的key rotation來(lái)獲得更高的加密強度。
      你可以使用Wireshark 來(lái)分析包,我們會(huì )有個(gè)加密數據包,有效載荷的第一個(gè)字節是12(十六進(jìn)制)。你可能已知道如果是一個(gè)未加密的TS 同步字節,那它將是47(十六進(jìn)制)。
      如果想進(jìn)一步了解其中的協(xié)議,你可以前往SRT GitHub repository,以及technical overview Wireshark的SRT解析器。
      如果你想了解更多關(guān)于SRT生態(tài)系統,或者有關(guān)于SRT的產(chǎn)品或信息請前往srtalliance.org。
     




     
    【免責聲明】本文僅代表作者本人觀(guān)點(diǎn),與CTI論壇無(wú)關(guān)。CTI論壇對文中陳述、觀(guān)點(diǎn)判斷保持中立,不對所包含內容的準確性、可靠性或完整性提供任何明示或暗示的保證。請讀者僅作參考,并請自行承擔全部責任。

    相關(guān)閱讀:

    專(zhuān)題

    CTI論壇會(huì )員企業(yè)

    亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩 乌恰县| 武城县| 波密县| 陵川县| 贺州市| 济阳县| 灌阳县| 湘潭县| 资兴市| 新津县| 安龙县| 佛冈县| 建始县| 枣庄市| 石狮市| 闵行区| 卓资县| 台中县| 双柏县| 滨州市| 抚宁县| 开阳县| 顺昌县| 普洱| 方城县| 香河县| 汝南县| 黔西县| 正宁县| 丹阳市| 文山县| 平遥县| 巨野县| 岑溪市| 四川省| 竹北市| 湟中县| 平昌县| 石阡县| 布拖县| 新密市| http://444 http://444 http://444 http://444 http://444 http://444