rtp h264打包和解包
1、學習思路
???????? 在了解rtp對h264數據的打包之前,需要對rtp、h264的一些基本概念有一個初步的了解,然后再使用rtp對h264的打包解包做解析
2、rtp認知
實時傳送協議(Real-time Transport Protocol或簡寫RTP,也可以寫成RTTP)是一個網絡傳輸協議,它是由IETF的多媒體傳輸工作小組1996年在RFC 1889中公布的。
RTP協議詳細說明了在互聯網上傳遞音頻和視頻的標準數據包格式。它一開始被設計為一個多播協議,但后來被用在很多單播應用中。RTP協議常用于流媒體系統(配合RTCP協議或者RTSP協議)。因為RTP自身具有Time stamp所以在ffmpeg 中被用做一種formate.
RTP協議格式:
??? 0?????????????????? 1?????????????????? 2?????????????????? 3
??? 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |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 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |????? defined by profile????????????????? |?????????? length??????????????????????????? |
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |??????????????????????? header extension?????????????????????????????????????????????????? |
?? |???????????????????????????? ....???????????????????????????????????????????????????????????????????????????? |
3、h264認知
H264數據2層結構:
一:視頻編碼層(VCL)
二:網絡適配層(NAL)
??? 在H.264/AVC視頻編碼標準中,整個系統框架被分為了兩個層面:視頻編碼層面(VCL)和網絡抽象層面(NAL)。其中,前者負責有效表示視頻數據的內容,而后者則負責格式化數據并提供頭信息,以保證數據適合各種信道和存儲介質上的傳輸。NAL占一個字節。
??? NAL單元(NALU):NAL的基本語法結構,它包含一個字節的頭信息和一系列來自VCL的稱為原始字節序列載荷(RBSP)的字節流。
數據流是儲存在介質上時: 每個NALU 前添加起始碼:0x00000001(或者0x000001),用來指示一個 NALU的起始和終止位置。
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 解碼器可以丟棄它而不影響圖像的回放. 不過一般情況下不太關心
這個屬性.
Type: 5 個比特.
?nal_unit_type. 這個 NALU 單元的類型. 簡述如下:
0?? ?沒有定義
1 ?? ?一個非IDR圖像的編碼條帶 (bp幀)
slice_layer_without_partitioning_rbsp( ) ?? ?
2 ?? ?編碼條帶數據分割塊A
slice_data_partition_a_layer_rbsp( ) ?? ?
3 ?? ?編碼條帶數據分割塊B
slice_data_partition_b_layer_rbsp( ) ?? ?
4 ?? ?編碼條帶數據分割塊C
slice_data_partition_c_layer_rbsp( ) ?? ?
5 ?? ?IDR圖像的編碼條帶 (i幀)
slice_layer_without_partitioning_rbsp( ) ?? ?
6 ?? ?輔助增強信息 (SEI)
sei_rbsp( ) ?? ?
7 ?? ?序列參數集 (sps幀)
seq_parameter_set_rbsp( ) ?? ?
8 ?? ?圖像參數集
pic_parameter_set_rbsp( pps幀) ?? ?
9 ?? ?訪問單元分隔符
access_unit_delimiter_rbsp( ) ?? ?
10 ?? ?序列結尾
end_of_seq_rbsp( ) ?? ?
11 ?? ?流結尾
end_of_stream_rbsp( ) ?? ?
12 ?? ?填充數據
filler_data_rbsp( ) ?? ?
13 ?? ?序列參數集擴展
seq_parameter_set_extension_rbsp( ) ?? ?
14...18 ?? ?保留 ?? ?
19 ?? ?未分割的輔助編碼圖像的編碼條帶
slice_layer_without_partitioning_rbsp( ) ?? ?
20...23 ?? ?保留 ?? ?
24??? STAP-A?? 單一時間的組合包
25??? STAP-B?? 單一時間的組合包
26??? MTAP16?? 多個時間的組合包
27??? MTAP24?? 多個時間的組合包
28??? FU-A???? 分片的單元
29??? FU-B???? 分片的單元
30-31 沒有定義
4、rtp 對h264的打包和解包
rtp 打包結構分類:
? 1. 單一 NAL 單元模式
???? 即一個 RTP 包僅由一個完整的 NALU 組成. 這種情況下 RTP NAL 頭類型字段和原始的 H.264的
? NALU 頭類型字段是一樣的.
? 2. 組合封包模式
??? 即可能是由多個 NAL 單元組成一個 RTP 包. 分別有4種組合方式: STAP-A, STAP-B, MTAP16, MTAP24.
? 那么這里的類型值分別是 24, 25, 26 以及 27.
? 3. 分片封包模式
??? 用于把一個 NALU 單元封裝成多個 RTP 包. 存在兩種類型 FU-A 和 FU-B. 類型值分別是 28 和 29.通用采用FU-A 。
2.1 單一 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 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
????? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
????? |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 個字節的開始碼就可以了.
2.2 組合封包模式
? 其次, 當 NALU 的長度特別小時, 可以把幾個 NALU 單元封在一個 RTP 包中.
?
?????? 0?????????????????? 1?????????????????? 2?????????????????? 3
?????? 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
????? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
????? |????????????????????????? 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?????? ? ? ? ? ? ? ? ? ?? |
????? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2.3 分片打包(FU A).
? 而當 NALU 的長度超過 MTU 時, 就必須對 NALU 單元進行分片封包. 也稱為 Fragmentation Units (FUs).
?
?????? 0?????????????????? 1?????????????????? 2?????????????????? 3
?????? 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
????? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
????? | FU indicator? |?? FU header?? |????????????????????????????????????????????????????? |
????? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+????????????????????????????????????????????? |
????? |????????????????????????????????????????????????????????????????????????????????????????????????????????? |
????? |???????????????????????? FU payload??????????????????????????????????????????????????????????? |
????? |????????????????????????????????????????????????????????????????????????????????????????????????????????? |
????? |?????????????????????????????? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
????? |?????????????????????????????? :...OPTIONAL RTP padding????????????????????????? |
????? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
????? Figure 14.? RTP payload format for FU-A
?? The FU indicator octet has the following format:
????? +---------------+
????? |0|1|2|3|4|5|6|7|
????? +-+-+-+-+-+-+-+-+
????? |F|NRI|? Type?? |
????? +---------------+
?? ?? F ?? ?NALU頭中的F
?? ?? NRI ?? ?NALU頭中的NRI
?? ?? type?? ?28 表示 FU-A打包
?? The FU header has the following format:
????? +---------------+
????? |0|1|2|3|4|5|6|7|
????? +-+-+-+-+-+-+-+-+
????? |S|E|R|? Type?? |
????? +---------------+
?? ?? S ?? ?bit為1表示分片的NAL開始,當它為1時,E不能為1
?? ?? E ?? ?bit為1表示結束,當它為1,S不能為1
?? ?? R ?? ?bit保留位,必須是0
?? ?? Type?? ?就是NALU頭中的Type,取1-23的那個值
分片打包解包實例:
80 60 01 0f 00 0e 1000 00 00 00 00?7c?85?8882
00 0a 7f? ca 94 053b 7f? 3e 7f? fe14? 2b 27 26 f8
89 88 dd85 62 e1 6dfc 33 01 38 1a 10 35 f214?
84 6e 21 24 8f? 7262 f0 51 7e 10 5f 0d 42 71 12
17 65 62 a1 f1? 44dc df 4b 4a 38 aa 96 b7dd 24
前12字節為RTP頭
7c是分片單元指示,01111100?1c-28(FU-A)
85是分片單元頭, 1000 0101NAl Type=5(關鍵幀)
解包時,取FU-A indicator的前三位和FU Header的后五位,即01100101(0x65)為NAL類型
總結
以上是生活随笔為你收集整理的rtp h264打包和解包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于socket阻塞与非阻塞情况下的re
- 下一篇: Apache源代码全景分析第二卷——HT