1. 概括
RTP(Real-time Transport Protocol,实时传输协议)是一个网络传输协议。它为数据提供了具有实时特征的端对端传送服务。
随着信息化的发展,人们对于某些信息,更看重信息的实时性,而不是完整性,这就产生了流媒体技术。流媒体技术具有启动时延小,节省客户端空间等优势。流媒体技术的一种实现方法就是使用RTP协议进行网络传输,利用RTP协议所提供特性实现实时性。
2. RTP封装结构及方法
2.1 RTP报头
RTP报头固定报头具有12个字节,其结构如下图1所示。
图 1 RTP头
其中:
(1)V:版本号。本次版本号为2;
(2)P:填充标志。可直接置零。
(3)X:扩展标志。可直接置零。
(4)CC:CSRC计数。若无CSRC,则置零即可。
(5)M:标志位。标志位的具体解释可由具体协议规定。如可用于帧边界标志。
(6)PT:负载类型。对于H.264来说,该值为105。
(7)Sequence number:序列号。序列号用于对RTP包进行计数。每发送一个RTP包,序列号加1。序列号的初始值可以置为零,也可用随机数开始。初始值如果是随机的,用利于加密。
(8)timestamp:时间戳。时间戳的增量为采样频率/帧率。同一帧的时间戳应该是一样的。时间戳的初始值也可以从零开始,或以随机数开始。按RFC3984规定,采用90000HZ的时钟。所以如果帧率为15,则时间戳增量为6000。
(9)SSRC:同步源识别符。若只使用下个同步源,则SSRC应该一样。JM中直接将这四个字节置为0x12345678。
(10)CSRC:可无。
事实上,使用JM或JSVM视频编码测试模式输出的264流使用的是NALU封装。而NALU的结构是由起始码前缀、NALU头部和NALU负荷数据组成。其中起始码前缀可以是0x 00 00 01或0x 00 00 00 01。因此前缀可能是三字节或是四字节。NALU头部如图2所示。NALU头部由一个比特的F位、两个比特的NRI和五个比特的TYPE组成。其中,F位强制为0,TYPE类型为0到23的值。
图2 NALU头
另外,对于JM来说,其编码也可以输出RTP结构的文件。而且其RTP结构还包括8个字节的前缀,即四个字节的RTP大小和四个字节的识别符。如图3所示。RTP大小包括12个字节的RTP头 + RTP数据。
图3 示例:RTP起始码
通过上面的论述可知,对于H264码流,其RTP封装就是将原始的NALU起始码前缀替换成RTP起始码+RTP头部。注意,如果进行组合封装或拆包封装,RTP固定头部后面还会有一些指示组合或拆包的字节。
2.2 RTP封装方法
RTP有三种封装方法,即单包封装、组合封装和拆包封装。当数据包大小超过最大传输单元(MTU,一般为1500字节)时,可以对数据包进行拆包封装。如果数据包太小,还可以选择进行组合封装。RTP包的接收端只需要检测RTP头部12个字节之后的第一个字节便可知道该包是单包封装、组合封装还是拆分封装。当使用单包封装时,该字节只低五位为1-23的数值;当进行组合封装时,该五位为24-27的数值;当进行拆包封装时,为28或29。
0 没有定义
1-23 NAL单元 单个 NAL 单元包.
24 STAP-A 单一时间的组合包
25 STAP-B 单一时间的组合包
26 MTAP16 多个时间的组合包
27 MTAP24 多个时间的组合包
28 FU-A 分片的单元
29 FU-B 分片的单元
30-31 没有定义
(1)单包封装
当数据包大小小于MTU时,一般采用单包封装。如前所述,NALU单元由起始码前缀、NALU头部和NALU载荷组成。因此在进行单包封装时,只需要将NALU单元的起始码前缀去掉,加上RTP起始码和RTP头部。如待NALU单元如下所示:
【00 00 00 01】【67 42 A0 1E 23 56 。。。】
则单包封装后结构如下:
【4字节的RTP大小】【FF FF FF FF】【12字节的RTP头部】【67 42 A0 1E 23 56 。。。】
注意:现实的RTP封装是没有前面8个字节的。本人只是为了适应JM进行封装所以加上8个字节的起始码。
(2)拆包封装
拆包封装有两种拆包方法,即FU-A和FU-B。本人采用FU-A方法进行拆包封装。FU-A封装结构如图4所示。
图4 FU-A结构
其中FU indicator为FU-A封装指示字节。该字节结构如图5所示。FU header为FU头部,其结构如图6所示。
图5 FU indicator
FU indicator位用于标识该RTP包为拆包封装。由图5可见,其结构和NALU的头部结构相同。其中F为0,NRI和该包所荷载NALU头部中NRI相同,TYPE为28(若采用FU-B,则TYPE值为29)。
图6 FU header
FU header中,S位指示该RTP包是否是原NALU中的第一个分片,若是第一个分片,则置1;E位,若该分片是本次拆包的最后一个分片,则该位置1;R位保留,置0;TYPE和FU indicator中的TYPE相同。
(3)组合封装
组合封装有四种组合方式,本文不讨论。
3. RTP封装实现
3.1 封装程序流程图
4. RTP解封装实现
4.1 解封装程序流程图
5. 总结
愚见,望指正!
6. 参考文献
[1] Schuzrinne H, Casner S,Frederick R,et al.RFC3550 RTP: A transport protocol for real-time applications[S].IETF/STD 0064,2003.
[2] Wenger S.RFC 3984 RTP payload format for H.264 video[S].2005.
[3] 柳伟,陈旭,梁永生. H.264/SVC的RTP封装算法及其应用[J].计算机工程与应用.2010,46(19).