本篇介绍RTP包封装格式
1.RTP包头格式
RTP包头占位12个字节,其字段组成如下图所示:
V字段:RTP协议版本号,占位2bit,当前协议为V=2;
P字段:填充字段,占位1bit,如果P=1,则表示此包的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
X字段:扩展字段,占位1bit,如果x=1,则表示RTP包头后面跟有一个扩展报头;
CC字段:CSRC计数器,占位4bit,表示CSRC标识符的个数;
M字段:标记,占位1bit,不同的载荷有不同的含义,M=1对于视频,标记一帧的结束;对于音频,标记会话的开始。
PT字段:有效载荷类型,占位7bit,用于说明RTP报文中有效载荷数据的类型,在流媒体中大部分用来区分音频和视频,便于客户端解析;
Sequence number字段:序列号,占位16bit,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。这个字段当下层的承载协议用UDP的时候,网络状况不好的时候可以用来检查丢包。同时出现网络抖动的情况可以用来对数据进行重新排序,序列号的初始值是随机的,同时音频包和视频包的sequence是分别记数的。
Timestamp字段:时间戳字段,占位32bit,必须使用90kHz 时钟频率。时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。
SSRC标识符:同步信源标识符,占位32bit,用于标志同步信源,该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。
CSRC标识符:特约信源标识符,每个CSRC标识符占位32bit,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源。
2.RTP封包NALU
NALU封包成RTP有三种方式:单一NAL单元模式,组合封包模式,分片封包模式;一般我们常用的就是单一NAL单元和分片封包模式两种。即我们所使用的RTP+H264一般都是一个RTP包中最多只有一个NALU包;在nal_unit_type的定义中(见附录7.3),0~23是给H264用的,24~31未使用,在rtp打包时,如果一个NALU放在一个RTP包里,可以使用NALU的nal_unit_type,但是当需要把多个NALU打包成一个RTP包,或者需要把一个NALU打包成多个RTP包时,就定义新的type来标识。
2.1 单一NALU模式
即RTP包仅由一个完整的NALU组成,在这种模式下,RTP NAL头类型字段和原始H264 ES流的NALU头类型字段是相同的;对于NALU长度小于MTU的包,一般都采用此种封包方式;在我们常见的安防行业码流中,一般都是SPS,PPS,SEI等数据可能会封成一个RTP包,I帧和P帧一般都会超过MTU而采用分片封包的方式;
对于一个原始的H.264 NAL单元常由[Start Code] [NALU Header] [NALU Payload] 三部分组成, 其中 Start Code 用于标示这是一个NALU 单元的开始,必须是 "00 00 00 01" 或 "00 00 01",NALU 头仅一个字节(指示此NALU的数据类型等信息,具体标示见附录7.3), 其后都是 NALU 单元内容负载,打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码(几种封包格式都要去除起始码), 把其他数据封包的 RTP 包即可;
2.2 组合封包模式
在NALU单元很小的时候,可以将多个NALU封装到一个RTP包里面进行传输,分别有4种组合方式: STAP-A, STAP-B, MTAP16, MTAP24;那么这里的类型值分别是 24, 25, 26 以及 27;我们主要介绍STAP-A,其封包格式如下所示:
[ RTP Header ] [78 (STAP-A头,占用1个字节)] [第一个NALU长度 (占用两个字节)] [ 67 42 A0 1E 23 56 0E 2F ] [第二个NALU长度 (占用两个字节)] [68 42 B0 12 58 6A D4 FF ... ]......
2.3 分片封包模式
当一个NALU长度超过了MTU时,就需要采用分片的方式进行RTP封包,将一个NALU分到多个RTP包中进行传输;存在两种分片类型 FU-A 和 FU-B;类型值分别是 28 和 29,我们常用FU-A,这里只对FU-A进行介绍;
RTP+FU-A分片封包的组合方式如下:
[RTP Header][FU indicator][FU header][payload]:其中RTP Header占12字节,FU indicator和FU header各占1个字节;
[FU indicator]有以下格式:
+------------------------+ Type占位后5位,表示此封包的类型域,其中type = 28表
|0|1|2|3|4|5|6|7| 示是FU-A分片(全部类型定义见附录7.3)
+-+-+-+-+-+-+-+-+++
|F|NRI| Type |
+------------------------+
[FU header]的格式如下:
+------------------------+ S:设置成1表示此FU-A分片包为NAL单元的起始包;其
|0|1|2|3|4|5|6|7| 他情况设置为0;
+-+-+-+-+-+-+-++-+-+ E:设置成1表示此FU-A分片为NAL单元的结束包;其余
|S|E|R| Type | 情况设置为0;
+------------------------+ R:保留位,必须为0;
原有的NAL的单元头与分片后的FU-A的单元头有如下关系:
原始的NAL头的前三位为FU indicator的前三位,原始的NAL头的后五位为FU header的后五位,FU indicator与FU header的剩余位数根据实际情况决定。