H264 Over RTP

转载注明出处:http://blog.sina.com.cn/s/blog_465bdf0b010002t1.html

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


你可能感兴趣的:(Stream,header,video,文档,h.264)