H264的RTP封包

  • H264流結構

        H264的ES流的結構分爲兩層,包括視頻編碼層(VCL)和網絡適配層(NAL)。視頻編碼層負責視頻內容表示,而網絡適配層負責對數據進行打包和傳送。NAL和VCL分離主要有以下兩方面的好處:
1、信號處理和網絡傳輸分層,VCL和NAL可以在不同的處理平臺上實現;
2、VCL和NAL分離設計,可以在不同的網絡環境內,網關不需要因爲網絡環境不同而對VCL比特流進行重構和重編碼。
        H264的ES流由一系列的NALU(Network Abstraction Layer Unit)組成,不同的NALU數據量各不相同。每個NALU前添加起始碼:0x000001或0x00000001,用來指示一個NALU的起始和終止位置。在這樣的機制下,解碼器在碼流中檢測起始碼,作爲一個NALU的起始標識,當檢測到下一個起始碼時,當前NALU結束。每個NALU單元由一個字節的NALU頭(NALU Header)和若干字節的載荷數據(RBSP)組成。其中NALU頭的格式如圖2所示:

0 1 2 3 4 5 6 7
F NRI TYPE

 

 

 

F:forbidden_zero_bit  佔1位,如果有語法衝突,則爲1。當網絡識別此單元存在比特錯誤時,可將其設爲1,以便接收方丟掉該        單 元。
NRI:nal_ref_idc. 佔2位,用來指示該NALU的重要性等級。值越大,表示當前NALU越重要。具體大於0時取何值,沒有具體規定。
Type:佔5位,指出NALU的類型,具體類型如下所示:

NALU類型
nal_unit_type NALU內容 C
0 未指定  
1 非IDR圖像的編碼slice 2,3,4
2 編碼slice數據劃分A 2
3 編碼slice數據劃分B 3
4 編碼slice數據劃分C 4
5 IDR圖像中的編碼slice 2,3
6 SEI(補充增強信息) 5
7 SPS(序列參數集) 0
8 PPS(圖像參數集) 1
9 接入單元定界符 6
10 序列結束 7
11 碼流結束 8
12 填充數據 9
13~23 保留  
24~31 未指定  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

需要特別指出的是,NRI值爲7和8的NALU分別爲序列參數集(SPS)和圖像參數集(PPS).

  • RTP簡介

RTP全名是Real-time Transport Protocol(實時傳輸協議),配套的相關協議RTCP(Real-time Transport Control Protocol,即實時傳輸控制協議),實時流傳輸協議RTP詳細說明了在互聯網上傳遞音頻和視頻的標準數據包格式,它與RTCP協議配合使用,本篇只講視頻H264的rtp封包,RTP實現IP網絡端到端實時的傳輸多媒體數據,並提供時間信息和流同步,具有低延時的特點。

  • RTP封包

  • RTP包頭header

每一個RTP數據包都由固定的包頭(header)和載荷(payload)兩部分組成,其中包頭前12字節的含義是固定的,而載荷則可以是音頻或者視頻數據。RTP的12字節固定包頭格式如下:

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 P X CC M 載荷類型(PT) 序號(sequence number)

                                                                                                時間戳(timestamp)

同步信源標識符(SSRC identifier)
特約信源標識符(CSRC identifiers)

 

 

 

 

 

 

各字段含義:
V:RTP協議版本號,佔2位,一般協議版本號爲2
P:填充標誌,佔1位,如果P = 1,則在該報文的尾部填充一個或多個額外的八位組,它們不是有效載荷的一部分
X:擴展標誌,佔1位,如果X = 1, 則在RTP報頭後跟有一個擴展報頭
CC:CSC計數器,佔4位,指示CSRC標識符的個數
M:佔1位,標記解釋由設置定義,目的在於允許重要事件在包流中標記出來,如不同的有效載荷有不同的含義,對於視頻,標記         一 幀的結束;對於音頻,標記會話的開始。
載荷類型(PT):佔7位,用來指出RTP負載的具體格式。rfc裏面對一些早期的格式定義了這個payload type,但是後來的h264並沒                            有分配,現在用96代替,因此現在96以上都不表示特定個的格式,具體表示什麼要用sdp或者其他協議來協商。
序列號(SN):佔16位,用於標識發送者所發送的RTP報文的序列號,每發送一個報文,序列號增1 ,序列號的初始值是隨機產生                        的,可以用於檢查丟包以及進行數據包排序。
時間戳Timestamp:佔32位,必須使用90KHz時鐘頻率
同步信源(SSRC)標識符:佔32位,指RTP包流的來源。該標識符是隨機產生的,
                                       參加同一視頻會議的兩個同步信源不能有相同的SSRC
特約信源(CSRC)標識符:佔32位,可以有0~15個。每個CSRC標識了包含在該RTP報文有效載荷中的所有特約信源。

  • RTP負載payload

       RTP的負載payload的數據就是H264的NALU,對於每個NALU,根據其包含的數據量的不同,其大小也有差異。在IP網絡中,當要傳輸的IP報文大小超過最大傳輸單元MTU(Maximum Transmission Unit)時就會產生IP分片情況。在以太網環境中可傳輸的最大IP報文(MTU)的大小爲1500字節。如果發送的IP數據包大於MTU,數據包就會被拆開來傳送。

       RTP負載的第一個字節的結構體如下,它和H264的NALU頭結構一致,可以把它認爲是RTP h264負載類型字節,完全是多增加的一個字節,不影響後面的NALU結構。

  • 圖1  Fu Indicator
    ​​​​
  •  

  • 封包

單一NAL單元模式
對於NALU的長度小於MTU大小的包,一般採用單一NAL單元模式,對於一個原始的H264NALU單元常由“起始碼”+“Nalu Header” + "Nalu Payload"三部分組成,其中起始碼是一個Nalu的開始,必須是“00 00 00 01”或“00 00 01”,Nalu頭僅爲一個字節,其後都是Nalu單元內容,打包時把起始碼去除掉,其他數據打包成payload即可。

例: 如有一個 H.264 的 NALU 是這樣的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
這是一個序列參數集 NAL 單元. [00 00 00 01] 是四個字節的開始碼, 67 是 NALU 頭, 42 開始的數據是 載荷數據內容.
封裝成 RTP 包將如下:
[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]
即只要去掉 4 個字節的開始碼就可以了.

FU-A打包方式
當NALU的長度超過MTU時,就必須對NALU單元進行分片封包,這裏只講一下FU-A的分片封包方式。FU-A的頭部由兩個字節組成,分別是Fu Indicator和Fu-A Header,再後面是負載。Fu Indicator見上圖1,Fu Header如下

Fu Header
0 1 2 3 4 5 6 7
S E R Type


 

 

 

S:1位,Start位,當被設置爲1時,表示NAL單元的開始。當後面的Fu載荷不是被分片Nal單元載荷的開始時,此位置0。
E:1位,End位,意義和Start位相反,當置1時,表示Nal單元的結束,當FU載荷不是Nal單元的最後一個分片時,此位置0。
R:1位,Reserved位,必須等於0,且接收者必須忽略它。
Type:5位,Nal單元荷載類型,定義見表《NALU類型》

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章