1. 程式人生 > >RTP打包總結

RTP打包總結

RTP協議頭格式:
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
|V=2|P|X| CC |M| PT | sequence number |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| timestamp |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| … |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
上圖引自rfc3550,由上圖中可知道RTP報文由兩個部分構成–RTP報頭和RTP的負載:
RTP報文由兩部分組成:報頭和有效載荷。RTP報頭格式如圖6.7所示,其中:
1.V:RTP協議的版本號,佔2位,當前協議版本號為2。
2. P:填充標誌,佔1位,如果P=1,則在該報文的尾部填充一個或多個額外的八位組,它們不是有效載荷的一部分。
3. X:擴充套件標誌,佔1位,如果X=1,則在RTP報頭後跟有一個擴充套件報頭。
4. CC:CSRC計數器,佔4位,指示CSRC 識別符號的個數。
5. M: 標記,佔1位,不同的有效載荷有不同的含義,對於視訊,標記一幀的結束;對於音訊,標記會話的開始。
6. PT: 有效載荷型別,佔7位,用於說明RTP報文中有效載荷的型別,如GSM音訊、JPEM影象等,在流媒體中大部分是用來區分音訊流和視訊流的,這樣便於客戶端進行解析。
7. 序列號:佔16位,用於標識傳送者所傳送的RTP報文的序列號,每傳送一個報文,序列號增1。這個欄位當下層的承載協議用UDP的時候,網路狀況不好的時候可以用來檢查丟包。同時出現網路抖動的情況可以用來對資料進行重新排序,在helix伺服器中這個欄位是從0開始的,同時音訊包和視訊包的sequence是分別記數的。
8. 時戳(Timestamp):佔32位,時戳反映了該RTP報文的第一個八位組的取樣時刻。接收者使用時戳來計算延遲和延遲抖動,並進行同步控制。
9. 同步信源(SSRC)識別符號:佔32位,用於標識同步信源。該識別符號是隨機選擇的,參加同一視訊會議的兩個同步信源不能有相同的SSRC。
10. 特約信源(CSRC)識別符號:每個CSRC識別符號佔32位,可以有0~15個。每個CSRC標識了包含在該RTP報文有效載荷中的所有特約信源。
如果擴充套件標誌被置位則說明緊跟在報頭後面是一個頭擴充套件,其格式如下:
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| defined by profile | length |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| header extension |
| … |

一般情況下:擴充套件標誌x=0,故其頭長度為12個位元組,因此第一個位元組常為0x80。
第二個位元組,如果為視訊,PT常為96(0x60),如是開始幀,此值為0xe0,否則為0x60.
在RTP基於TCP傳輸中:
包格式為:RTP標誌+RTP頭+RTP負載資料
在RTP基於UDP傳輸中,無RTP標誌。
其中:RTP標誌位(4個位元組):$+channel id(1 byte)+長度(2位元組)
此長度不包含本身這4個位元組。
如下圖1:是一個SPS,其長度為16, 16+12=28=0x1c , RTP頭的第一位元組為0x80,第2個位元組為0xe0
在這裡插入圖片描述
圖1
在這裡插入圖片描述
圖2
0x05b0=1456=1500-20-20-4
RTP包最大長度:  
TCP:1500-20(ip頭)-20(tcp頭)-4(RTP標誌)=1456
UDP: 1500-20(ip頭)-8(udp頭)=1472

對於一個原始的 H.264 NALU 單元常由 [Start Code] [NALU Header] [NALU Payload] 三部分組成, 其中 Start Code 用於標示這是一個 NALU 單元的開始, 必須是 “00 00 00 01” 或 “00 00 01”, NALU 頭僅一個位元組, 其後都是 NALU 單元內容.
打包時去除 “00 00 01” 或 “00 00 00 01” 的開始碼, 把其他資料封包的 RTP 包即可.
H264的RTP中有三種不同的基本負載(Single NAL,Non-interleaved,Interleaved)
通常在SDP 引數中指定。
如:
m=video 49170 RTP/AVP 98
a=rtpmap:98 H264/90000
a=fmtp:98 profile-level-id=42A01E; packetization-mode=1; sprop-parameter-sets=Z0IACpZTBYmI,aMljiA==
常用的引數:

  1. packetization-mode: 表示支援的封包模式.
    當 packetization-mode 的值為 0 時或不存在時, 必須使用單一 NALU 單元模式.
    當 packetization-mode 的值為 1 時必須使用非交錯(non-interleaved)封包模式.
    當 packetization-mode 的值為 2 時必須使用交錯(interleaved)封包模式.
    每個打包方式允許的NAL單元型別總結(yes = 允許, no = 不允許, ig = 忽略)
    Type Packet Single NAL Non-Interleaved Interleaved
    Unit Mode Mode Mode
    0 undefined ig ig ig
    1-23 NAL unit yes yes no
    24 STAP-A no yes no
    25 STAP-B no no yes
    26 MTAP16 no no yes
    27 MTAP24 no no yes
    28 FU-A no yes yes
    29 FU-B no no yes
    30-31 undefined ig ig ig

  2. sprop-parameter-sets: SPS,PPS
    這個引數可以用於傳輸 H.264 的序列引數集和影象引數 NAL 單元. 這個引數的值採用 Base64 進行編碼. 不同的引數集間用","號隔開。

  3. profile-level-id:
    這個引數用於指示 H.264 流的 profile 型別和級別. 由 Base16(十六進位制) 表示的 3 個位元組. 第一個位元組表示 H.264 的 Profile 型別, 第三個位元組表示 H.264 的 Profile 級別

Rtp payload的第一個位元組 fu indicator和264的NALU類似
±--------------+
|0|1|2|3|4|5|6|7|
±±±±±±±±+
|F|NRI| Type |
±--------------+

F: 1 個位元.
forbidden_zero_bit. 在 H.264 規範中規定了這一位必須為 0.
NRI: 2 個位元.
nal_ref_idc. 取 00 ~ 11, 似乎指示這個 NALU 的重要性, 如 00 的 NALU 解碼器可以丟棄它而不影響影象的回放. I幀應設定成11.

Type: 5 個位元.
nal_unit_type. 這個 NALU 單元的型別. 簡述如下:
0 沒有定義
1-23 NAL單元 單個 NAL 單元包.
24 STAP-A 單一時間的組合包
24 STAP-B 單一時間的組合包
26 MTAP16 多個時間的組合包
27 MTAP24 多個時間的組合包
28 FU-A 分片的單元
29 FU-B 分片的單元
30-31 沒有定義

#ifdef BIG_ENDIAN
struct _nalu 
{
uint8_t Type : 5;
uint8_t NRI : 2;
uint8_t F : 1;
};
#else
struct _nalu 
{
uint8_t F : 1;
uint8_t NRI : 2;
uint8_t Type : 5;
};

#endif

Rtp payload的第二個位元組 fuHead
±--------------+
0|1|2|3|4|5|6|7|
±±±±±±±±±+
|S|E|R| Type |
±--------------+
S:開始標誌
E:結束標誌 (與 Mark相同)
R:必須為0
Type:h264的NALU Type
例:使用FU-A分片,type=28
0x7C85=01111100 10000101 (開始包)
0x7C05=01111100 00000101 (中間包)
0x7C45=01111100 01000101 (結束包)

#ifdef BIG_ENDIAN
struct _fuHeader
{
uint8_t Type : 5;
uint8_t R : 1;
uint8_t E : 1;
uint8_t S : 1;
};
#else
struct _fuHeader
{
uint8_t S : 1;
uint8_t E : 1;
uint8_t R : 1;
uint8_t Type : 5;
};
#endif

易搞混的幾個TYPE:
• RTP 中的PT 負載型別 Payload type (PT) : 7 bits --傳送H264視訊,此值固定設成 96
• NALU 中的TYPE 描述了NALU的屬性,如:7指示順序引數集,8指示影象引數集
• RTP之後的TYPE,即13 BYTE開始,單一打包的TYPE,與NALU中的TYPE一樣;FU 分片打包方式,TYPE設成28,即分片模式;

封包介紹:
 單一NAL單元模式
對於 NALU 的長度小於 MTU 大小的包, 一般採用單一 NAL 單元模式.
對於一個原始的 H.264 NALU 單元常由 [Start Code] [NALU Header] [NALU Payload] 三部分組成, 其中 Start Code 用於標示這是一個
NALU 單元的開始, 必須是 “00 00 00 01” 或 “00 00 01”, NALU 頭僅一個位元組, 其後都是 NALU 單元內容.
打包時去除 “00 00 01” 或 “00 00 00 01” 的開始碼, 把其他資料封包的 RTP 包即可.
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 1 2 3 4 5 6 7
±±±±±±±±±±±±±±±-±±±±±±±±±±±±±±±+
|F|NRI| type | |
±±±±±±±±+ |
| Bytes 2…n of a Single NAL unit |
| ±±±±±±±±±±±±±±±±+ | :…OPTIONAL RTP padding |
±±±±±±±±±±±±±±±±±±-±±±±±±±±±±±±+
例:
如有一個 H.264 的 NALU 是這樣的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F … ]
這是一個序列引數集 NAL 單元. [00 00 00 01] 是四個位元組的開始碼, 67 是 NALU 頭, 42 開始的資料是 NALU 內容.
封裝成 RTP 包將如下:
[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]
即只要去掉 4 個位元組的開始碼就可以了.
 組合封包模式
其次, 當 NALU 的長度特別小時, 可以把幾個 NALU 單元封在一個 RTP 包中.
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 1 2 3 4 5 6 7
±±+±±±±±±±±±±±±±±±±±±±±±±+
| RTP Header |
±±±±±±±±±±±±±±±±±±±±±±±±-+
|STAP-A NAL HDR | NALU 1 Size | NALU 1 HDR
±±±±±±±±±±+±±±±±±±±±±±±±±+
| NALU 1 Data |
±±±±±±±±±±±±±±±±±±±±±±±±+
| | NALU 2 Size | NALU 2 HDR |
±±±±±±±±±±±±±+±±±±±±±±±±±+
| NALU 2 Data |
| ±±±±±±±±±±±±±±±±+
| :…OPTIONAL RTP padding |
±±±±±±±±±±±±±±±±±±±±±±±±±±+
這裡只介紹STAP-A模式,如果是STAP-B的話會多加入一個DON域,
例:
如有一個 H.264 的 NALU 是這樣的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F … ]

[00 00 00 01 68 42 B0 12 58 6A D4 FF … ]
封裝成 RTP 包將如下:
[ RTP Header ] [78 (STAP-A頭,佔用1個位元組)] [第一個NALU長度 (佔用兩個位元組)] [ 67 42 A0 1E 23 56 0E 2F ] [第二個NALU長度 (佔用兩個位元組)] [68 42 B0 12 58 6A D4 FF … ]
 分片的單元:
當NALU的長度超過MTU時,就必須對NALU單元進行分片封包.也稱為Fragmentation Units(FUs).

   0               1             2                   3
   0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7  0 1 2 3 4 5 6 7  0 1 2 3 4 5 6 7 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-———+
  | FU indicator  |   FU header   |                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                             |
  |                                                               
  |                        FU payload                           |
  |                                                                     |                    
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                            :...OPTIONAL RTP padding        |
  +-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  Figure 14.  RTP payload format for FU-A

通過wireshark抓包分析:
ip 過濾設定: ip.src=x.x.x.x

在這裡插入圖片描述