现在的位置: 首页 > 综合 > 正文

H264 Over RTP 之 宝典

2013年04月06日 ⁄ 综合 ⁄ 共 5447字 ⁄ 字号 评论关闭
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:     定义为0
NRI(nal_ref_idc):00 不是用来构造I帧预测的参考帧。
                             非00  用来保持参考帧的完整性。
(什么东西啊,反正我是不明白,也用不到,下次去做编解码算了,看了N多概念,都不清楚,郁啊。)
Type(nal_unit_type): 如下表
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

文章引用自:http://spaces.msn.com/ajonbin/blog/PersonalSpace.aspx

抱歉!评论已关闭.