RTP协议
参考:
视音频数据处理入门:UDP-RTP协议解析
从零开始写一个RTSP服务器(三)RTP传输H.264
1. 概述
1.1 RTP协议
RTP(Real-time Transport Protocol,实时传输协议)是一种网络协议,用于在IP网络上传输实时数据,如音频、视频等。它的主要目的是提供一种可靠的、面向数据包的传输机制,以支持实时多媒体应用。
RTP协议的特点包括:
- 无连接
RTP协议本身不保证数据的可靠传输,它只是负责将数据包从发送端发送到接收端,而不关心数据包是否按顺序到达或者是丢失 - 面向数据包
RTP协议适用于传输数据包,而不是连续的数据流。这意味着它可以处理任意大小的数据包,而不需要预先建立连接 - 时间戳
每个RTP数据包都包含一个时间戳字段,表示该数据包的发送时间。这有助于接收端重新组装和播放数据包,以保持正确的播放顺序 - 序列号
每个RTP数据包都有一个序列号,用于标识数据包的顺序。接收端可以根据序列号对数据包进行排序,以确保它们按照正确的顺序被处理 - 同步源(SSRC)
每个RTP会话有唯一的同步源标识符(SSRC),用于区分不同的发送者。这有助于接收端识别并处理来自不同发送者的数据包 - 扩展头
RTP协议支持扩展头,允许在数据包中添加额外的信息,如编解码器信息、载荷类型等
RTP头的格式为

| 名称 | 表示内容 | 占用比特 | 备注 |
|---|---|---|---|
| V | 版本号 | 2 | 表示RTP的版本 |
| P | 填充标志 | 1 | 如果设置,表示在数据包尾部具有一定的填充字节 |
| X | 扩展标志 | 1 | 如果设置,表示在固定数据头部之后还有一个扩展头部 |
| CC | CSRC计数 | 4 | 表示CSRC(贡献源)标识符的数量 |
| M | 标记 | 1 | 用于特定的标识符,为1时表示一帧的结束 |
| PT | 有效载荷类型(payload type) | 7 | 表示数据包中的负载类型,例如H264格式,JPEG格式 |
| Sequence number | 序列号 | 16 | 标识数据包的计数,可用于检测是否存在丢失或错序 |
| timestamp | 时间戳 | 32 | 1.时间同步:接收端要知道每个数据包的发送时间,以便正确地播放音频或视频。通过使用时间戳,接收端可以准确地将数据包按照到达的顺序进行排序和播放 2.抖动控制:如果收到乱序的数据包,时间戳能够帮助接收端识别并处理这些乱序的数据包,从而减少播放时的延时 |
| SSRC | 同步源标识符 | 32 | 用于唯一地表示一个RTP会话中的发送端。每个RTP流都有一个唯一的SSRC值,从而区分不同的发送端,防止冲突 |
| CSRC | 贡献源标识符列表 | (0~15)*32 | 用于标识参与多传播的源。一个数据包可能由多个源发送,CSRC字段允许接收端知道有哪些源参与了该数据包的生成,也能够统计相关的信息,检查这个数据包的来源是否是合法的 |
RTP协议通常与RTCP(Real-time Transport Control Protocol,实时传输控制协议)一起使用。RTCP用于监控RTP会话的质量,收集统计信息,并提供反馈给发送端。RTCP报告包括发送方报告(SR)、接收方报告(RR)、源描述(SDES)和应用程序特定功能(APP)
1.2 RTP和UDP的关系
RTP和UDP(User Datagram Protocol,用户数据报协议)是两个不同的网络协议,但它们之间存在密切的关系。RTP负责定义音视频数据包的格式、顺序、时间戳等参数,以保证音视频数据在网络中的实时传输。RTP本身不提供任何传输可靠性,只负责数据的封装和传输。UDP是一种无连接的传输层协议,它提供了一种简单地、不可靠的数据传输服务。UDP协议将数据打包成数据报,通过IP网络进行传输。由于UDP没有建立连接的过程,所以它的传输速度比较快,但同时也无法保证数据传输的可靠性
RTP和UDP之间的关系在于,RTP通常使用UDP作为其底层传输协议。RTP数据包被封装在UDP数据报中进行传输,以利用UDP的高效传输特性。同时,RTP本身不关心数据传输的可靠性和顺序,这些由下层的UDP和IP协议来处理。借用一下其他文中的图片,流媒体协议栈如下所示

RTP之所以会使用UDP而不是TCP,是因为RTP主要用于实时音视频传输,这种应用场景对传输延迟非常敏感。TCP是一种面向连接的可靠性传输,它通过重传机制来保证数据的完整性和可靠性,但这也引入了额外的延迟,相对比而言,UDP速度更快,更适合音视频传输的需求。所以,RTP和UDP之间是互相配合的关系。
综上所述,RTP负责音视频数据的封装和传输,而UDP则提供了一种高效的传输服务。通过将RTP数据包封装在UDP数据包中,可以实现音视频数据在网络中的实时传输
2. RTP打包H264码流
在进行RTP打包H264码流时,因为是传输协议,需要考虑每个数据包的大小。在网络传输中,一般的最大传输单元(Maximum Transmission Unit,MTU)的大小是1500字节,TCP/IP协议栈(如IP头)占20字节,UDP头占8字节,RTP头占12字节,所以RTP数据包最大为1460字节,但是为了适应网络条件或避免分片,可能也会使用相对较小的数据包,例如1400字节。概括来说,RTP打包的格式如下
// 使用最大的RTP Payload情况,即RTP Payload=1460 Bytes
+------------+------------+------------+-------------+
| IP Header | UDP Header | RTP Header | RTP Payload |
+------------+------------+------------+-------------+
| 20 Bytes | 8 Bytes | 12 Bytes | 1460 Bytes |
+------------+------------+------------+-------------+
这里不记录IP Header和UDP Header的信息,仅考虑RTP的处理。其中,RTP Header就是前面记录的Header,RTP Payload就是具体的信息。这里会引入一个新的问题,传输的数据量(pkt_size)和载荷大小(rtp_payload)之间的关系:
(1)如果pkt_size等于设置的rtp_payload大小,则一个RTP包携带一份数据
(2)如果pkt_size大于了rtp_payload,需要将pkt分成片段来进行传输
(3)如果pkt_size小于了rtp_payload,可以将若干个pkt合并到一个RTP当中
2.1 RTP单一传输
RTP单一传输最为简单,其传输的格式为
+------------+------------+------------+--------------+
| IP Header | UDP Header | RTP Header | RTP Payload |
+------------+------------+------------+--------------+
| 20 Bytes | 8 Bytes | 12 Bytes | payload_size |
+------------+------------+------------+--------------+
对于将H264码流打包的情况,这里的RTP Payload就是H264码流的NALU。其中,RTP Payload的格式为
0 1 2 3
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
第一个字节描述了这个NALU的总体信息:
(1)F:forbidden_zero_bit,默认为0
(2)NRI: 表示NALU的重要程度,越大则越重要,最大为3
(3)type:表示NALU的类型
这里的type的描述类型包括
#define NAL_UNIT_TYPE_UNSPECIFIED 0 // Unspecified
#define NAL_UNIT_TYPE_CODED_SLICE_NON_IDR 1 // Coded slice of a non-IDR picture
#define NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_A 2 // Coded slice data partition A
#define NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_B 3 // Coded slice data partition B
#define NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_C 4 // Coded slice data partition C
#define NAL_UNIT_TYPE_CODED_SLICE_IDR 5 // Coded slice of an IDR picture
#define NAL_UNIT_TYPE_SEI 6 // Supplemental enhancement information (SEI)
#define NAL_UNIT_TYPE_SPS 7 // Sequence parameter set
#define NAL_UNIT_TYPE_PPS 8 // Picture parameter set
#define NAL_UNIT_TYPE_AUD 9 // Access unit delimiter
#define NAL_UNIT_TYPE_END_OF_SEQUENCE 10 // End of sequence
#define NAL_UNIT_TYPE_END_OF_STREAM 11 // End of stream
#define NAL_UNIT_TYPE_FILLER 12 // Filler data
#define NAL_UNIT_TYPE_SPS_EXT 13 // Sequence parameter set extension
// 14..18 // Reserved
#define NAL_UNIT_TYPE_CODED_SLICE_AUX 19 // Coded slice of an auxiliary coded picture without partitioning
// 20..23 // Reserved
// 24..31 // Unspecified
2.2 RTP分片传输
如果需要将pkt分成若干个片段进行传输,需要在RTP Header之后增加两个标识字段,分别是FU Indicator(Fragment Unit)和FU Header,其位置表示为
// 使用最大的RTP Payload情况,即RTP Payload=1460 Bytes
+------------+------------+------------+--------------+-----------+--------------+
| IP Header | UDP Header | RTP Header | FU Indicator | FU Header | RTP Payload |
+------------+------------+------------+--------------+----------

最低0.47元/天 解锁文章
21万+

被折叠的 条评论
为什么被折叠?



