RTP 中的PT 负载类型 Payload type (PT) : 7 bits --发送H264视频,此值固定设成 96;
NALU是H264用于网络传输的单元类型,一个完整的NALU单元一般是以0x000001或者0x00000001开始,其后跟的则是NALU头和NALU的数据;我们在网络传输的时候,会去掉开始的0x000001或者0x00000001的标志;一般需要将这些标志替换为RTP payload的头部(1个字节,这个是名称我自己杜撰的哈);
其中NALU数据就是RBSP数据;
NALU头的定义格式为:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
其中:
F:必须为0;
NRI:nal重要性指示,标志该NAL单元的重要性,值越大,越重要,解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU;
Type:则是数据类型;
RTP payload头部定义和NALU类似;只是TYPE字段的定义如下:
0 没有定义
1-23 NAL单元 单个 NAL 单元包.
24 STAP-A 单一时间的组合包
25 STAP-B 单一时间的组合包
26 MTAP16 多个时间的组合包
27 MTAP24 多个时间的组合包
28 FU-A 分片的单元
29 FU-B 分片的单元
30-31 没有定义
以下分几种情况进行讨论:
1. 单个NAL单元包
这种一般适用于NAL包小于1460字节的情况,但不能太小,太小就需要合包,后面讨论;单个NAL单元包的rtp payload如下:
0 1 2 3 4 5 6 7 …… 31
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|NRI| type | |
+-+-+-+-+-+-+-| |
| Bytes 2..n of a Single NAL unit |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
也就是说,直接将NAL头部和NAL数据放到rtp payload的位置就行,因为此时的rtp payload的头部和NAL头部是一样的,所以只需要用其中一个;
2、多个NAL封装成一个单元包
这种一般是用于多个小的NAL包封装成一个大的NAL包,当然不超过1460字节;这种情况的rtp payload结构大致如下:
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Note:
STAP-A NAL HDR其实就是rtp payload的头部的一个字节,值应该是00011000b(STAP-A类型);
NALU size 占用两个字节;NALU 头部一个字节;注意,数据部分不是按32字节对齐的,同时NALU size不包含自身的2个字节;
3、一个NAL包拆分成多个NAL包
这种一般是一个NAL包超过了1460字节的情况,这种情况的payload结构如下:
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
NOTE:
其中的FU indicator对应rtp payload的头部,此处应该是0x00011100b(FU-A) ;
FU header定义如下:
FU Header
+----------------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+----------------------+
对于分片的第一个包,设置S为1;对于分片的最后一个包,设置E为1,R设置为0即可;Type字段对应的是NALU头部中的TYPE,可以用于区分帧类型;
注意,FU payload中并没有传送NALU的头部,NALU的头部需要根据FU indicator和FU header进行计算:nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f);