【流媒体】基于RTP协议的H264码流发送器和接收器

参考:
视音频数据处理入门:UDP-RTP协议解析
从零开始写一个RTSP服务器(三)RTP传输H.264

1. 概述

1.1 RTP协议

RTP(Real-time Transport Protocol,实时传输协议)是一种网络协议,用于在IP网络上传输实时数据,如音频、视频等。它的主要目的是提供一种可靠的、面向数据包的传输机制,以支持实时多媒体应用。

RTP协议的特点包括:

  1. 无连接
    RTP协议本身不保证数据的可靠传输,它只是负责将数据包从发送端发送到接收端,而不关心数据包是否按顺序到达或者是丢失
  2. 面向数据包
    RTP协议适用于传输数据包,而不是连续的数据流。这意味着它可以处理任意大小的数据包,而不需要预先建立连接
  3. 时间戳
    每个RTP数据包都包含一个时间戳字段,表示该数据包的发送时间。这有助于接收端重新组装和播放数据包,以保持正确的播放顺序
  4. 序列号
    每个RTP数据包都有一个序列号,用于标识数据包的顺序。接收端可以根据序列号对数据包进行排序,以确保它们按照正确的顺序被处理
  5. 同步源(SSRC)
    每个RTP会话有唯一的同步源标识符(SSRC),用于区分不同的发送者。这有助于接收端识别并处理来自不同发送者的数据包
  6. 扩展头
    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  |
+------------+------------+------------+--------------+----------
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值