一、引言
本文對RTP協議進行簡介。在簡介之前,請各位先下載RTP的官方文檔《RFC 3550》和《RFC 3551》。《RFC 3550》總共有89頁,《RFC 3551》總共有44頁。本文下面所說的“頁數”是指在pdf閱讀器中顯示的頁數:
二、RTP協議簡介
? 根據《RFC 3550》第5頁,實時傳輸協議(Real-time Transport Protocol或簡寫RTP)為交互式音頻和視頻等具有實時特性的數據提供端到端的傳輸服務。這些服務包括有效載荷類型識別、序列編號、時間戳和傳輸監控。應用程序通常在 UDP 的基礎上運行 RTP,以利用其多路復用和校驗服務;這兩個協議都貢獻了部分傳輸協議功能。不過、RTP 也可與其他合適的底層網絡或傳輸協議一起使用。如果底層網絡提供多播分發功能,RTP 支持將數據傳輸到多個目的地。
? 請注意,RTP 本身并不提供任何機制來確保及時傳輸或提供其他服務質量保證,而是依靠底層服務來實現。它既不保證傳送或防止無序傳送,也不假定底層網絡是可靠的并能按順序傳送數據包。RTP 中包含的序列號允許接收方重建發送方的數據包序列,但序列號也可用于確定數據包的正確位置,例如在視頻解碼中,不一定要按順序解碼數據包。雖然 RTP 主要是為了滿足多方參與的多媒體會議的需求,但它并不局限于這一特定應用,連續數據存儲、交互式分布式仿真、活動徽章以及控制和測量應用也可能適用 RTP:
三、Mixers和Translators
根據《RFC 3550》第7到第8頁,到目前為止,我們假定所有網站都希望以相同的格式接收媒體數據。然而,這并不總是合適的。考慮這樣一種情況:一個地區的與會者通過低速鏈路與大多數享有高速網絡接入的與會者連接。與其強迫每個人都使用帶寬較低、質量較差的音頻編碼,不如在低帶寬區域附近放置一個稱為混音器(Mixer)的RTP級中繼器。混音器會重新同步傳入的音頻數據包,以重建發送方生成的20毫秒恒定間隔,這些數據包可以單播給單個接收者,也可以通過不同地址組播給多個接收者。RTP header包含一種混音器識別混合數據包來源的方法,以便在接收器上提供正確的通話者指示。
音頻會議中的某些預期參與者可能使用高帶寬鏈路連接,但可能無法通過 IP 組播直接到達。例如,他們可能位于應用級防火墻之后,無法通過任何 IP 數據包。在這種情況下,可以使用另一種稱為翻譯器(Translator)的 RTP 級中繼。在防火墻兩側各安裝一個翻譯器,外部翻譯器通過安全連接將接收到的所有組播數據包傳送到防火墻內部的翻譯器。防火墻內的翻譯器將這些數據包作為組播數據包再次發送到僅限于網站內部網絡的組播組。
混合器和翻譯器的設計目的多種多樣。例如,視頻混合器可將獨立視頻流中的單個人物圖像進行縮放,然后合成到一個視頻流中,以模擬群體場景。其他轉換的例子包括將一組只講 IP/UDP 的主機連接到一組只懂 ST-II 的主機上,或對來自單個信號源的視頻流進行逐包編碼轉換,而無需重新同步或混合:
根據《RFC 3550》第10頁,Translator(翻譯器,轉換器)是轉發 RTP 數據包并保持其synchronization source identifier(同步源標識符)不變的中間系統。Translator的例子包括不混合轉換編碼的設備、從組播到單播的復制器以及防火墻中的應用級過濾器:
Mixer(混音器,混合器)為從一個或多個來源接收 RTP 數據包的中間系統,可能會更改數據格式,以某種方式合并數據包,然后轉發新的 RTP 數據包。由于多個輸入源之間的定時一般不會同步,因此Mixer會對數據流進行定時調整,并為合并后的數據流生成自己的定時。因此,從Mixer發出的所有數據包都將被識別為以Mixer為同步源(synchronization source):
四、RTP packet
根據《RFC 3550》第8頁,RTP packet(RTP報文)是由固定的RTP頭(RTP Fixed Header)、可能為空的貢獻源(contributing sources,簡稱CSRC)列表和有效載荷數據(payload)組成的數據包。某些底層協議可能要求定義 RTP 數據包的封裝。通常情況下,底層協議的一個數據包包含一個 RTP 數據包,但如果封裝方法允許,也可能包含多個 RTP 數據包:
一個RTP packet =??RTP header +?RTP layload + 填充字節(可選)
五、RTP header
?根據《RFC 3550》第12頁,RTP header包含下圖所示部分:
RTP header =?RTP Fixed Header +?contributing source(CSRC)?identifiers?+?RTP Header Extension(可選)
六、RTP Fixed Header
RTP Fixed Header包含RTP header中必須存在的字段。RTP Fixed Header固定占12字節。
RTP Fixed Header =?version +?padding +?extension +?CSRC count +?marker +?payload type +?sequence number +?timestamp +?SSRC
其中:
version:占2位,該字段標識 RTP 的版本,本規范(《RFC 3550》)定義的版本為'2'(目前都用2版本)。值'1'用于RTP的第一個草案版本,值'0'用于最初在 “vat ”音頻工具中實施的協議):
padding:占1位,為填充位,表示用于RTP packet結束點的預留空間。如果設置了填充位(padding的值為1),該RTP packet的末尾就會包含一個或多個額外的填充八位位組(此時RTP packet末端會附加填充字節),這些八位位組不屬于有效載荷的一部分。填充的最后一個八位位組包含應忽略多少個填充八位位組(包括其本身)的計數。某些具有固定塊大小的加密算法或在下層協議數據單元中攜帶多個RTP packet時可能需要使用填充:
extension:占1位,為擴展位,如果擴展位被設置(extension的值為1),RTP Fixed Header后(CSRC之后)必須有一個擴展頭(?RTP Header Extension):
CSRC count:占4位,為CSRC的計數。指示RTP Fixed Header之后的CSRC標識符數量,即contributing source(CSRC)?identifiers的數量:
marker:占1位,該marker(標記)的解釋由配置文件(profile)定義。其目的是允許在數據包流中標記幀邊界等重要事件。配置文件可定義額外的標記位,或通過改變有效載荷類型字段中的位數來指定沒有標記位:
根據《RFC 3551》第30頁,大多數視頻編碼規定,在視頻幀的最后一個packet(報文,數據包)中,RTP header的marker位應設置為 1,否則設置為0。因此,無需等待具有不同時間戳的后續數據包來檢測是否應顯示新幀(也就是說:視頻的每幀可能會比較大,一個RTP packet可能無法發送完。所以使用了幾個packet來傳輸該幀。對于視頻,通常的規則是marker位的值為1時表示這是該視頻幀的最后一個packet):
根據《RFC 3551》第37頁,音頻靜默后第一個數據包上設置marker位的要求級別從 “是 ”改為 “應該是”,并說明只有在故意不發送數據包時才設置標記位(也就是說:對于音頻而言,常用的規則是marker位值為1時表示通話開始,即 “數據包未連續傳輸的靜默期后的第一個數據包”):
payload type:占7位,為PT值(有效載荷類型),根據該值確定 RTP 有效負載(payload)的格式,并決定應用程序對其的解釋:
《RFC 3551》規定了一套初始的 “有效載荷類型”,?本列表保留并擴展了該列表:
有效載荷標識符 96-127 用于會話期間動態定義的有效載荷。建議動態分配端口號,但端口號 5004 和 5005 已被注冊,以便在不需要動態分配端口時使用配置文件。除了上表中明確指定PT值的負載類型,還有些負載類型由于誕生的較晚,沒有具體的PT值,只能使用動態(dynamic)PT值,即96到127,比如普遍指定H264的PT值為96。
根據《RFC 6184》第11頁(該文檔描述了:RTP Payload Format for H.264 Video),對于H.264,必須通過所使用的配置文件或以動態方式分配有效載荷類型:
sequence number:占16位(2字節),為序列號。每發送一個 RTP數據包,序列號的值就會遞增加1,接收方可利用序列號檢測數據包丟失并恢復數據包序列。序列號的初始值應是隨機的(不可預測的),這樣即使信源本身沒有加密,也能增加已知純文本加密攻擊的難度,因為數據包可能會流經translator (翻譯器)進行加密:
timestamp:占32位(4字節),為產生payload的時間戳。時間戳反映RTP數據包中第一個字節的采樣瞬間。采樣瞬時必須來自一個在時間上單調線性遞增的時鐘,以便進行同步和抖動計算。與序列號一樣,時間戳的初始值也應該是隨機的:
synchronization source (SSRC) identifier:占32位(4字節),SSRC字段用于標識同步源(synchronization source,即RTP數據流的起源)。該標識符應隨機選擇,目的是使同一RTP 會話中沒有兩個同步源具有相同的SSRC標識符(在一個RTP會話中,每個數據流的SSRC都不同,接收者將根據該SSRC標識符來區分不同的信源,進行RTP報文的分組)。雖然多個信號源選擇相同標識符的概率很低,但所有RTP實現都必須做好檢測和解決碰撞的準備。如果源更改了源傳輸地址,它也必須選擇一個新的SSRC標識符,以避免被解釋為循環源:
七、CSRC list
在RTP Fixed Header之后的是CSRC list(CSRC列表),其包含0到15項contributing source(CSRC)?identifiers,,每項占32位(4字節)。CSRC列表標識了該數據包所含有效載荷的貢獻源(contributing sources)。標識符的數量由RTP Fixed Header的CSRC count(CC)字段給出。如果貢獻源超過 15 個,則只能識別 15 個。CSRC 標識符由混合器(mixers)插入,使用貢獻源的 SSRC 標識符。例如,在音頻數據包中,會列出混合在一起創建數據包的所有信源的 SSRC 標識符,以便在接收機上正確顯示通話者:
八、RTP Header Extension
根據《RFC 3550》第16頁,RTP中提供了一種擴展機制,允許各實施機構嘗試與有效載荷格式無關的新功能,這些功能需要在 RTP 數據包報頭中攜帶額外的信息。設計該機制的目的是使其他未進行擴展的互操作實現可以忽略報頭擴展。比如通過該RTP擴展,可以添加前向糾錯碼(FEC),發送冗余數據。使接收端在一定比例丟包的情況下可以恢復原始數據,提高傳輸的穩健性。
請注意,該報頭擴展僅用于有限的用途。例如,RTP Fixed Header的特定配置文件擴展處理成本較低,因為它不是條件性的,也不在可變位置。特定有效載荷格式所需的附加信息不應使用這種標頭擴展,而應放在數據包的有效載荷部分:
九、payload
根據《RFC 3550》第8頁,payload(RTP layload,有效載荷)為RTP在數據包中傳輸的數據,例如音頻樣本或壓縮后的視頻數據,即實際的媒體數據。其格式和內容取決于RTP Fixed Header中的payload type字段:
十、參考
《維基百科——實時傳輸協議》
《Real-Time Transport Protocol (RTP) Parameters》