H264 Payload Format over RTP/RTCP﹐很久以前做的了﹐ 都快忘了﹐趕快復習一下吧﹐ 不然又還給...應該不是老師了吧﹐嘿嘿。 RTP包頭還是貼一下吧﹐看起來方便﹕ 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 | | .... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 這個就不多說了吧﹕) 接下來的就是H264的頭了。 首先是NAL Unit Type﹐8個位元群組 +----------------------+ |0|1|2 |3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +----------------------+ F (1bit)﹕ 定義為0 NRI(nal_ref_idc, 2 bits)﹕00 不是用來構造I幀預測的參考幀。 非00 用來保持參考幀的完整性。 (什麼東西啊﹐反正我是不明白﹐也用不到﹐下次去做編解碼算了﹐ 看了N多概念﹐都不清楚﹐鬱啊。) Type(nal_unit_type, 5 bits)﹕ 如下表 Type | Packet Type | name --------------------------------------------------------- 0 | undefined - 1-23 | NAL unit | Single NAL unit packet 24 | STAP-A | Single-time aggregation packet 25 | STAP-B | Single-time aggregation packet 26 | MTAP16 | Multi-time aggregation packet 27 | MTAP24 | Multi-time aggregation packet 28 | FU-A | Fragmentation unit 29 | FU-B | Fragmentation unit 30-31| undefined -
敘述一下﹕ H264 over RTP基本上分三種型式﹕ 1. Single NAL unit packet 也就是實際的NAL型式﹐ 可以理解為一個包就是一幀H264數據﹐這個在實際中是比較多的。 2. Aggregation packet 一包數據中含有多個H264幀。還可以細分﹐下面講。 3. Fragmentation unit 一幀數據被分為多個RTP包﹐這也是很常見的﹐ 特別是對於關鍵幀。 細分一下Aggregation packet﹕ Aggregation packet 可以分為四種﹕ STAP-A 包內的幀含有相同的NALU-Time﹐沒有DON STAP-B 包內的幀含有相同的NALU-Time﹐有DON MTAP16 包內的幀含有不同的NALU-Time﹐timestamp offset = 16 MTAP24 包內的幀含有不同的NALU-Time﹐timestamp offset = 24 實際用到的比較多的是1-23﹐STAP-A(24)和FU-A(28)其他型式的 沒有碰到過﹐ 就沒有去研究了﹐當然我指的是用戶端。你要做發送端的話﹐ 你自己訂吧。 從RTP得到的數據是沒有NAL頭的﹐關於NAL頭在RFC3984和ITUTH264 檔案裏的意義好像不太一樣﹐當初就是這個混淆了﹐折騰了半天。 具體的忘了﹐我也懶得再去找了﹐下次再看到時候補上。實際應用就是 要加上個H264 STREAM 的頭 h264_stream_head = 0x00,0x00,0x00,0x01 4位元群組 隨後是NAL unit type ﹐這裏指的是H264定義的NAL type﹐有點小差別﹐ 特別是在FU的時候﹐下面會講。 Single NAL Unit Packet(1-23) 這個很簡單了﹐一個包就是一幀數據。 h264_stream_head + NAL_unit_type...直接送去解碼了。 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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ STAP-A(24) 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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 看這個結構應該很清楚了﹐先是16位的長度﹐就可以得到第一幀﹐ h264_stream_head + NALU 1 HDR...送去解碼。再算下一幀。注意﹐ 不一定是32bit對齊的。需要注意的這個NALU Size 是不包括他本身 這2個位元群組。 FU-A(28) 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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ FU Indicator +----------------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +----------------------+ FU Header +----------------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |S|E|R| Type | +----------------------+ S﹕1 表示是一幀的開始包 E﹕1 表示是一幀的結束包﹐和RTP marker位一致 R﹕0 必須 這裏要注意一下﹐NAL unit type 必須自己拼裝 FU Indicator前四位元群組+ FU Header後四位元群組。也就是type欄位 是 FU header裏的 nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f) 等幀收齊了﹐加上H264_streaming_head + nal_unit_type....送去解碼 有些已經記不清出了﹐都是從代碼裏推出來的﹐下次看的時候就該記下來。 寫的還真累啊﹐下班了﹐88 參考資料﹕ 1. RFC3984 -- RTP Payload Format for H.264 Video |
沒有留言:
張貼留言