天天看點

H264碼流結構分析和rtp打包結構詳解

分類:

linux應用程式之---流媒體(18) 

H264碼流結構分析和rtp打包結構詳解
H264碼流結構分析和rtp打包結構詳解
H264碼流結構分析和rtp打包結構詳解

網絡抽象層單元類型 (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-23  NAL單元  單個 NAL 單元包

  24    STAP-A   單一時間的組合包

  25    STAP-B   單一時間的組合包

  26    MTAP16   多個時間的組合包

  27    MTAP24   多個時間的組合包

  28    FU-A     分片的單元

  29    FU-B     分片的單元

  30-31 沒有定義

h264僅用1-23,24以後的用在RTP H264負載類型頭中

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             |

      |                             ....                              |

      負載類型 Payload type(PT): 7bits

rfc裡面對一些早期的格式定義了這個payload type。但是後來的,如h264并沒有配置設定,那就用96來代替。是以現在96以上都不表示特定的格式,具體表示什麼要用sdp或者其他協定來協商。

      序列号 Sequence number(SN): 16bits

      時間戳 Timestamp: 32bits

上面介紹了NALU和RTP header的基本結構,下面介紹的全部都是RTP PayLoad的部分

Rtp負載第一個位元組的結構如下,它和H.264的NALU頭結構一緻,可以把它認為是RTP h264負載類型位元組,完全是多增加的一個位元組,不影響後面的NALU結構

這裡的Type類型除1-23外還可取以下值:

  25    STAP-B   單一時間的組合包

如果使用1-23就是:單一NAL單元模式

封包介紹:

單一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 包即可.

      |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 包中.

      |                          RTP Header                           |

      |STAP-A NAL HDR |         NALU 1 Size           | NALU 1 HDR    |

      |                         NALU 1 Data                           |

      :                                                               :

      +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |               | NALU 2 Size                   | NALU 2 HDR    |

      |                         NALU 2 Data                           |

這裡隻介紹STAP-A模式,如果是STAP-B的話會多加入一個DON域,另外還有MTAP16、MTAP24,具體不介紹,可以看rfc文檔,文章尾貼一個連結可以去看。

如有一個 H.264 的 NALU 是這樣的:

  [00 00 00 01 68 42 B0 12 58 6A D4 FF ... ]

  [ 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).

      | FU indicator  |   FU header   |                               |

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |

      |                         FU payload                            |

      Figure 14.  RTP payload format for FU-A

   The FU indicator octet has the following format:

   别被名字吓到這個格式就是上面提到的RTP h264負載類型,Type為FU-A

   The FU header has the following format:

      |S|E|R|  Type   |

        S bit為1表示分片的NAL開始,當它為1時,E不能為1

   E bit為1表示結束,當它為1,S不能為1

   R bit保留位

   Type就是NALU頭中的Type,取1-23的那個值

附:

一個翻譯過的rfc3984文檔,翻譯的有點亂,湊貨的看看

<a href="http://wenku.baidu.com/view/0f612e1ec5da50e2524d7f32.html" target="_blank">http://wenku.baidu.com/view/0f612e1ec5da50e2524d7f32.html</a>

繼續閱讀