<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    RTP協議之Header結構解析

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接 實時傳輸協議 RTP,RTP 提供帶有實時特性的端對端數據傳輸服務,傳輸的數據如:交互式的音頻和視頻。那些服務包括有效載荷類型定義,序列號,時間戳和傳輸監測控制。應用程序在 UDP 上運行 RTP 來使用它的多路技術和 checksum 服務。2 種協議都提供傳輸協議的部分功能。不過,RTP 可能被其他適當的下層網絡和傳輸協議使用。如 果下層網絡支持,RTP 支持數據使用多播分發機制轉發到多個目的地。 注意 RTP 本身沒有提供任何的機制來確保實時的傳輸或其他的服務質量保證,而是由低層的服務來完成。它不保證傳輸或防止亂序傳輸,它不假定下層網絡是否可靠,是否按順序傳送數據包。RTP 包含的序列號允許接受方重構發送方的數據包順序,但序列號也用來確定一個數據包的正確位置,例如,在視頻解碼的時候不用按順序的對數據包進行解碼。 但是 RTP 原先的設計是用來滿足多參與者的多媒體會議的需要,它沒有限定于專門的應用。連續數據的儲存,交互分布式仿真,動態標記,以及控制和測量應用程序也可能會適合使用 RTP。 1、RTP 固定頭結構 RTP 固定頭結構如圖2所示。 圖1 RTP固定頭格式 前 12 個字節出現在每個 RTP 包中,僅僅在被混合器插入時,才出現 CSRC 識別符列表。各個域的含義如下所示: (1)版本(V):2 比特,此域定義了 RTP 的版本。此協議定義的版本是 2。(值 1 被 RTP 草案版本使用,值 0 用在最初"vat"語音工具使用的協議中。) (2)填充(P):1 比特,若填料比特被設置,則此包包含一到多個附加在末端的填充比特,填充比特不算作負載的一部分。填充的最后一個字節指明可以忽略多少個填充比特。填充可能用于某些具有固定長度的加密算法,或者用于在底層數據單元中傳輸多個 RTP 包。 (3)擴展(X):1 比特,若設置擴展比特,固定頭(僅)后面跟隨一個頭擴展。 (4)CSRC 計數(CC):4 比特,CSRC 計數包含了跟在固定頭后面 CSRC 識別符的數目。 (5)標志(M):1 比特,標志的解釋由具體協議規定。它用來允許在比特流中標記重要的事件,如幀邊界。 (6)負載類型(PT):7 比特,此域定義了負載的格式,由具體應用決定其解釋,協議可以規定負載類型碼和負載格式之間一個默認的匹配。其他的負載類型碼可以通過非 RTP 方法動態定義。RTP發送端在任意給定時間發出一個單獨的 RTP 負載類型;此域不用來復用不同的媒體流。 (7)序列號(sequence number):16 比特,每發送一個 RTP 數據包,序列號加 1,接收端可以據此檢測丟包和重建包序列。序列號的初始值是隨機的(不可預測),以使即便在源本身不加密時(有時包要通過翻譯器,它會這樣做),對加密算法泛知的普通文本攻擊也會更加困難。 (8)時間戳(timestamp) :32 比特,時間戳反映了 RTP 數據包中第一個字節的采樣時間。時鐘頻率依賴于負載數據格式,并在描述文件(profile)中進行描述。也可以通過 RTP 方法對負載格式動態描述。 如果 RTP 包是周期性產生的,那么將使用由采樣時鐘決定的名義上的采樣時刻,而不是讀取系統時間。例如,對一個固定速率的音頻,采樣時鐘將在每個周期內增加 1。如果一個音頻從輸入設備中讀取含有 160 個采樣周期的塊,那么對每個塊,時間戳的值增加 160。時間戳的初始值應當是隨機的,就像序號一樣。幾個連續的 RTP 包如果是同時產生的。如:屬于同一個視頻幀的 RTP 包,將有相同的序列號。 不同媒體流的 RTP 時間戳可能以不同的速率增長。而且會有獨立的隨機偏移量。因此,雖然這些時間戳足以重構一個單獨的流的時間,但直接比較不同的媒體流的時間戳不能進行同步。對于每一個媒體,我們把與采樣時刻相關聯的 RTP 時間戳與來自于參考時鐘上的時間戳(NTP)相關聯。因此參考時鐘的時間戳就是數據的采樣時間。(即:RTP 時間戳可用來實現不同媒體流的同步,NTP 時間戳解決了 RTP 時間戳有隨機偏移量的問題。)參考時鐘用于同步所有媒體的共同時間。這一時間戳對(RTP 時間戳和 NTP 時間戳),用于判斷 RTP 時間戳和 NTP 時間戳的對應關系,以進行媒體流的同步。它們不是在每一個數據包中都被發送,而在發送速率更低的 RTCP 的 SR(發送者報告)中。 如果傳輸的數據是存貯好的,而不是實時采樣得到的,那么會使用從參考時鐘得到的虛的表示時間線(virtual presentation timeline)。以確定存貯數據中的每個媒體下一幀或下一 個單元應該呈現的時間。此種情況下 RTP 時間戳反映了每一個單元應當回放的時間。真正的回放將由接收者決定。 (9)SSRC:32 比特,用以識別同步源。標識符被隨機生成,以使在同一個 RTP 會話期中沒有任何兩個同步源有相同的 SSRC 識別符。盡管多個源選擇同一個 SSRC 識別符的概率很低,所有 RTP 實現工具都必須準備檢測和解決沖突。若一個源改變本身的源傳輸地址,必須選擇新的SSRC 識別符,以避免被當作一個環路源。 RTP 包流的源,用 RTP 報頭中 32 位數值的SSRC 標識符進行標識,使其不依賴于網絡地址。一個同步源的所有包構成了相同計時和序列號空間的一部分,這樣接收方就可以把一個同步源的包放在一起,來進行重放。 舉些同步源的例子,像來自同一信號源的包流的發送方,如麥克風、攝影機、RTP 混頻器就是同步源。一個同步源可能隨著時間變化而改變其數據格式,如音頻編碼。SSRC 標識符是一個隨機選取的值,它在特定的 RTP 會話中是全局唯一(globally unique)的。參與者并不需要在一個多媒體會議的所有 RTP 會話中,使用相同的 SSRC 標識符;SSRC 標識符的綁定通過RTCP。如果參與者在一個 RTP 會話中生成了多個流,例如來自多個攝影機,則每個攝影機都必須標識成單獨的同步源。 (10)CSRC 列表:0 到 15 項,每項 32 比特,CSRC 列表識別在此包中負載的所有貢獻源。識別符的數目在 CC 域中給定。若有貢獻源多于 15 個,僅識別 15 個。CSRC 識別符由混合器插入,并列出所有貢獻源的 SSRC 識別符。例如語音包,混合產生新包的所有源的 SSRC 標識符都被列出,以在接收端處正確指示參與者。 若一個 RTP 包流的源,對由 RTP 混頻器生成的組合流起了作用,則它就是一個作用源。對特定包的生成起作用的源,其 SSRC 標識符組成的列表,被混頻器插入到包的 RTP 報頭中。這個列表叫做 CSRC 表。相關應用的例子如,在音頻會議中,混頻器向所有的說話人(talker)指出,誰的話語(speech)將被組合到即將發出的包中,即便所有的包都包含在同一個(混頻器的)SSRC 標識符中,也可讓聽者(接收者)可以清楚誰是當前說話人。 2、RTP擴展頭結構 RTP 提供擴展機制以允許實現個性化:某些新的與負載格式獨立的功能要求的附加信息在RTP 數據包頭中傳輸。設計此方法可以使其它沒有擴展的交互忽略此頭擴展。RTP擴展頭格式如圖2所示。 圖2 RTP擴展頭格式 若 RTP 固定頭中的擴展比特位置 1,則一個長度可變的頭擴展部分被加到 RTP 固定頭之后。頭擴展包含 16 比特的長度域,指示擴展項中 32 比特字的個數,不包括 4 個字節擴展頭(因此零是有效值)。RTP 固定頭之后只允許有一個頭擴展。為允許多個互操作實現獨立生成不同的頭擴展,或某種特定實現有多種不同的頭擴展,擴展項的前 16 比特用以識別標識符或參數。這 16 比特的格式由具體實現的上層協議定義。基本的 RTP 說明并不定義任何頭擴展本身。 3、RTP包解析 RTP包解析示例如下所示: [cpp] view plaincopy static int parsingRTPPacket(uint8_t *data, size_t size) { if (size < 12) { //Too short to be a valid RTP header. return -1; } if ((data[0] >> 6) != 2) { //Currently, the version is 2, if is not 2, unsupported. return -1; } if (data[0] & 0x20) { // Padding present. size_t paddingLength = data[size - 1]; if (paddingLength + 12 > size) { return -1; } size -= paddingLength; } int numCSRCs = data[0] & 0x0f; size_t payloadOffset = 12 + 4 * numCSRCs; if (size < payloadOffset) { // Not enough data to fit the basic header and all the CSRC entries. return -1; } if (data[0] & 0x10) { // Header extension present. if (size < payloadOffset + 4) { // Not enough data to fit the basic header, all CSRC entries and the first 4 bytes of the extension header. return -1; } const uint8_t *extensionData = &data[payloadOffset]; size_t extensionLength = 4 * (extensionData[2] << 8 | extensionData[3]); if (size < payloadOffset + 4 + extensionLength) { return -1; } payloadOffset += (4 + extensionLength); } uint32_t rtpTime = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; uint32_t srcId = data[8] << 24 | data[9] << 16 | data[10] << 8 | data[11]; uint32_t seqNum = data[2] << 8 | data[3]; return 0; }RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全