一文详解 RTP/RTCP协议:流媒体数据传输的协议基石
该协议(RTP)是一种实时传输协议(RTP),由IETF制定并作为标准存在。其相关技术文档包括RFC3550(其中RFC1889已过期))。 RFC 3550不仅规范了该协议的运行方式,并且还制定了配套的实时传输控制协议(RTCP)。

RTP协议位于UDP协议之上,在流媒体领域发挥重要作用,并与RTCP协同工作,在流媒体数据传输方面有广泛应用。例如,在直播、远程摄像头流媒体播放、流媒体视频播放以及视频会议等多个应用场景中都可以见到它的身影。它定义了一组标准的数据包格式,在互联网上传输音频和视频信息。最初设计为一个多端广播通信方案,并现已被广泛应用于单播场景中。
RTCP主要用于向RTP网络反馈服务质量信息,并不直接参与多媒体数据的传输过程。它通过定期向参与的多媒体会话端点发送控制信息来评估网络性能指标如传递量和丢包率等关键参数。

例如一个视频会议:
在视频会议过程中音频与视频信息需各自独立地作为单独的 RTP session 进行传输;为此必须设置两个独立的RTP session来承载不同类型的媒体信息:一个用于视频信号传输、另一个专门用于音频信号传输;
此外为了实现有效的媒体分发还需要配置两组独立的UDP通道来分别传输 RTP媒体流 和 RTCP控制数据包;值得注意的是音频与视频信号之间并无直接的数据关联性;
对于 RTP媒体流 的传输,则采用 偶数端口;而对于 RTCP控制数据 的传输,则采用紧随其后的奇数端口(即RTP端口号加一);

一、RTP报文结构
RTP报文结构 如下图所示:

RTP媒体流的第一帧数据报文Wireshark抓包如下图所示:

Version字段(占2比特位)
用于标识采用的 RTP 版本。其中当前应用的是2版本号(早期版本则采用的是1)。
P (Padding):填充标志(占用一个比特位)。当该字段为真时,在报文末尾会添加一个或多个填充字节。这些填充字节不参与 payload 媒体流的内容。Padding 常用于加密算法中以提供固定长度的数据块需求,并可能在某些底层协议中用于一次性传输多个 RTP 数据包。
*X (Extension):扩展位(占据1比特位)。
当该字段的值为1时,在RTP固定头后面会紧跟一个扩展头。
CSRC (Contributing source id number):标识为4比特位的贡献源计数器(固定在头部CSRC列表的长度)
M (Marker):标记位(占1比特位)
标识数据帧的边界(开始与结束),每一帧数据的开始与结束,其对应的RTP数据流中该字段应该设置为1。
RTP数据帧的的第一个RTP数据报文标记为1,可以标识数据帧的开始,终端可以完整整个数据帧缓冲后,再进行播放,从而降低网络延时对用户影响。
RTP数据帧的最后一个RTP报文标记为1,可以使上层调用者或者Application得知,当前完整数据帧已接收完成,该帧媒体数据不会再有新数据,不必继续等待。
Marker标记位的作用在RFC3551 中有详细说明,摘录如下:
For applications which send either no packets or occasional comfort-noise packets during silence, the first packet of a talkspurt, that is, the first packet after a silence period during which packets have not been transmitted contiguously, SHOULD be distinguished by setting the marker bit in the RTP data header to one. The marker bit in all other packets is zero. The beginning of a talkspurt MAY be used to adjust the playout delay to reflect changing network delays.
Most of these video encodings also specify that the marker bit of the RTP header SHOULD be set to one in the last packet of a video frame and otherwise set to zero. Thus, it is not necessary to wait for a following packet with a different timestamp to detect that a new frame should be displayed.
PT (Payload type):表示数据包中所承载的具体媒体类型(占用7位二进制位)。
该字段可区分其承载的媒体类型(如音频、视频等)。
根据RFC3551标准,在RFC3551 Payload Type Definitions文档中详细说明了Payload type与不同媒体类型(如音频、视频等)之间的对应关系表。


SN (Sequence number)被定义为序列编号(占用16比特位)。* 当前时刻段内每隔一定时间就会触发一次任务执行操作。* 每当发送一个 RTP 数据包时,其对应的序列编号会递增。* 每个 RTP 数据包接收端能够通过该字段判断丢包事件并据此对收到的数据进行重新排序。* 为了提高抗干扰能力,在配置 SN 时建议采用随机初始化方式。

Timestamp字段为32位。
时间戳字段记录了RTP数据包首块数据的产生时刻。
其中初始值应为随机赋值。
该时间戳必须以恒定速率进行线性递增。
例如,在视频流中,假设第一个RTP报文的时间戳为20,则第二个RTP报文的时间戳应为40;第三个则为60。
此外,在某些情况下(如多个相关数据块同时生成),它们将具有相同的 timestamp字段。

SSRC(synchronization source identifier):数据的发送源(占32比特位)
SSRC 用来标识数据的发送源,该个身份标识是随机生成的。另外,同一个发送源不同的媒体类型,其对应的SSRC也不相同。例如同一个发送源,RTP视频媒体通道与RTP音频媒体通道,其对应的SSRC应不同。
RFC3550 A.6 Generating a Random 32-bit Identifier 给出了生成SSRC随机标识符的示例算法。

-
CSRC(contributing source identifiers)被定义为关键数据字段(提供详细信息),其中每个条目占用32位内存空间。 -
其中 CSRC (Contributing source identifiers count) 字段用于确定数据字段的数量。
-
特别地,在实际应用中需要注意的是当提供的关键数据条目数量超过15时。
-
Payload:多媒体数据
RTP通过网络传输多媒体数据,并包含语音信息和经过压缩的视频内容。
RFC 6184 RFC 6184 标准详细描述了如何将H.264编码的视频流加载到RTP框架中。
二、RTCP报文结构
按照RFC3550标准中所述,RTCP数据包涵盖了若干种类型。此外,在不同的RTCP报文类别下传递的方式也会有所差异。
| RTCP Packet Type | Value | 用途 |
|---|---|---|
| SR(Sender Report) | 200 | 发送端报告 |
| RR(Receiver Report) | 201 | 接收端报告 |
| Source Description | 202 | 源点描述 |
| BYE(Goodbye) | 203 | 结束传输 |
| APP | 204 | 特定应用 |
- 发送方报告报文(SR)的RTCP结构
- 接收方报告报文(RR)的RTCP格式
- 源描述信息(SDES)RTCP报文格式
- 结束确认RTCP报文格式
- 其中APP字段为可选类型;由于未捕获到相关数据包信息,在此不做进一步说明。
2.1 SR (Sender Report) 报文
SR (Sender Report) RTCP报文结构如下图所示:

SR (Sender Report) RTCP数据报文抓包如下图所示:

SR (Sender Report) 报文包含三个部分。
- 首段由
Header标识符构成(占用8个字节); - 次段包含
Sender Info模块及其相关信息(占用20个字节); - 最后一段可接收零至多个
Report Block文件。
A、第一部分 Header 头部
V (Version):编号(占用2比特位)。
该编号被用来表示使用的RTP版本(目前采用的是2,在第一个RTP草稿中使用过1)。
P (Padding)定义为占据单比特位的一个填充字段。
如果该值设为真,则RTCP报文位于末尾的部分将携带8字节的填充数据。
Padding字段可能在某些情况下被用于实现加密功能。
如需了解关于RTCP Padding字段的具体应用,请参考RFC 3550第9.1节。
RC (接收报告计数):接收报告数据块的数量(占5比特位)。
该 RTCP 包中的 Sender Report 数据块 数量可以为零。
PT (packet type):RTCP数据包类型(占8比特位)
当前数据包为SR (Sender Report) 200。根据RFC3550共包含以下几种:

length:长度字段占用16比特位。SVID(synchronization video identification):同步视频识别字段(占用32比特位)。
同步视频识别字段(SVID)用于标识视频信息来源并被用来确定解码器使用哪个媒体流实例进行解码。同一接收设备的不同媒体流实例对应于不同的SVID值。例如,在同样的接收设备上运行两个不同的语音编码器会生成两个不同的SVID值。
RFC3550 A.6 Generating a Random 32-bit Identifier给出了随机生成SVID示例算法。

B、第二部分 Sender Info 发送者信息
第二部分包含发送方相关信息。由20字节的数据构成,在每个发送方报告包中出现。它汇总了该发送方的数据传输情况。这些字段各自代表的意义如下:
其中timestamp MSW代表基于NTP协议中最高有效位的时戳(Most Significant Word),而timestamp LSW则代表最低有效位的时戳(Least Significant Word)。此报告生成的时间可参考RFC3550第4节的具体信息。
RTP timestamp:RTP 时间戳(占1比特位)
可用于媒体内与媒体见数据同步。
发送方的报文计数器(占32位)
在从启动发送RTP报文 至生成此 sender report 的这段时间内,该系统源报告记录了多少个 RTP 报文?一旦发送方更改其 SSRC 标识符值,则该计数值将被重置。
sender’s octet count:32 bit位组成的计数值
自开始传输 RTP 数据包至生成此 sender report 的时间范围内,在这段时间内该 SSRC 总共发送了多少字节(BYTE)的数据。如果发送者更改了 SSRC 标识符,则计数值将被重新初始化。
C、第三部分 Report Block接收报告块
第三部分可能包含零个或多个接收报告块,其数量取决于该发送者自上次报告以来所接收的其他源的数量.每个接收报告块会传递来自单个SSRC同步源的RTP数据包统计信息.

SSRC_n:SSRC信息(占32比特位)
这个信息块对应的 SSRC 标识。
fraction lost:数据包丢失比例(占8比特位)。在源SSRC_n发送的前一个SR或RR数据包之后,在这段时间内丢失的数据包数量占总发送量的比例。
整体过程中的丢包总量(占比24%)
从数据接收开始到当前为止,在RTCP/UDP协议下运行过程中累计丢失的数据包总数为来自源SSRC_n的RTP数据包数量。
最大接收报文序列号扩展字段具有32位长度。其中:
最低有效位存储的是最新的RTP报文序列号,
最高有效位则记录了该序列号在循环中的出现次数。
interarrival jitter 的数值精度为 32 bits。
RTP 数据包到达时间间隔中的抖动现象。
其中 Si 和 Ri 分别表示第 i 包的时间戳计数值和接收时刻计数值。
根据上述定义可知:
D(i, j) = (Rj - Ri) - (Sj - Si)
= (Rj - Sj) - (Ri - Si)
值得注意的是,在计算两个相邻包之间的时间差时,
我们应考虑累积效应。
通过递推的方式计算累积抖动度量 J(i),其更新公式为:
J(i) = J(i-1) × (15/16) + |D(i-1,i)| / 16
其中 D(k, l)(k < l ≤ N)
表示第 k 包与第 l 包之间的累计时间差,
而 J(N)
则反映了所有包之间的时间差综合影响。
LSR (last SR timestamp):32 bits
该 SSRC 最后一个 RTCP 报文(SR)中带的 NTP 时间。
DLSR (time delay since the last SR): a 32-bit precision
2.2 RR (Receiver Report) 报文
RR (Receiver Report) RTCP报文结构如下图所示:

RR (Receiver Report) RTCP数据报文抓包如下图所示:

具体差异内容
- a、在Header字段中采用201字段值来表示响应报文。
- b、响应报文字段中不包含与源报告相关的第二部分信息(发送方信息)。
RR (Receiver Report) 报文共包含两个部分。
在Header字段中,与SMR不同的是RMR字段。其特点在于采用编码方式标识RMR报文。
第二部分涵盖零个及以上的Report Block接受报告块:
报文格式遵循以下模式:" SR (Sender Report) Report Block 接受报告块 "
2.3 SDES (Source Description) 报文
SDES (Source Description) RTCP报文结构如下图所示:

SDES (Source Description) RTCP数据报文抓包如下图所示:

SDES 包含参与对话各方的身份标识信息, 包括用户名、电子邮箱地址以及电话号码等, SDES (Source Description) 报文由两部分组成
在Header字段中,SDES报文中字段号202用于标识Source Description类型报文。
- 第二部分由零个或多个
Chunk数据块构成:
每个Chunk数据块都对应一个 SSRC 或 CSRC。每个 SSRC/CSRC 包含多个描述字段。例如用户名、邮箱和电话等信息。
A、第一部分 Header 头部
V字段(Version)标识版本号(占用2位二进制位)。该字段用于标识使用的RTP版本号码(当前采用的是2号版本;第一个RTP草稿采用的是1号版本)。
P (Padding):占位符(占用一个比特位)。
当该bit设为1时,则会在RTCP报尾附加8字节的数据。
而该bit标记字段可能在某些加密机制中被采用。
有关详细实现,请参阅RFC3550 9.1。
SC (source count) 表示报告数据块的数量(占用5比特位)。
其中包含的 SSRC/CSRC data blocks 数量可以为零。
其中PT代表RTCP数据包类型(占用8比特位)。当前的数据包为SDES(源描述)类型的编号202。参照RFC3550,该标准共包含以下几种情况:

length:报文长度(占16比特位)。
B、Chunk数据块
每个Chunk数据块中都有多个具体信息,并且这些具体信息均是以32位为单位进行对齐。该数据块主要涵盖以下几类特征类型。
| Type | Value | 用途 |
|---|---|---|
| CNAME | 1 | 终端标识,CNAME标识在RTP连接的所有参加者中应是唯一且不变的 |
| NAME | 2 | 用户名称,用于描述源的用户 |
| 3 | 电子邮件地址,用于描述源的邮件地址,格式如 xiaxveliang@163.com | |
| xveliang | 4 | 描述源的电话号码 |
| LOC | 5 | 描述源的地理位置 |
| TOOL | 6 | 描述应用或工具的名称,表示产生流的应用的名称与版本,如"videotool 1.0" |
| NOTE | 7 | 描述源当前状态的过渡信息 |
| PRIV | 8 | 描述针对源的扩展项 |
在这些Type类别中,在SDES数据包中不可或缺的是CNAME类。对于其他类型的源描述数据,则可以根据特定的应用需求来选择是否采用。
本节仅讨论CNAME类型的DNS操作报文格式,请参考 RFC3550 供进一步了解。
CNAME报文结构如下图所示:

CNAME报文抓包如下图所示:

Type:字段类型,在此位置表示CNAME类别(值为1);Length:用于描述"User Android Domain Name"信息的长度(抓包结果表明length=21);Text:用于描述CNAME的信息。
CNAME 类型具有如下属性:
在任意一个 RTP 会话期间内使用的 CNAME 标识符必须是独一无二且恒定不变的。
CNAME 作为 SSRC 发送源标识符与目标地址之间的绑定信息,在不同的 RTP 会话中被使用。
如前所述,在终端重新启动时,由于终端系统会随机分配新的 SSRC 标识符(如前所述),这可能会导致原有绑定失效。因此必须包含一个不变的 CNAME 项来提供不同 SSRC 标识符之间的有效绑定关系。
根据 RFC3550 规定了 CNAME 的生成规则。
2.4 BYE (Goodbye)报文
BYE 代表离开,并可标明脱离的原因;其用于表明一个或多个媒体源已停止处于活跃状态。
BYE (Goodbye) RTCP报文结构如下图所示:

BYE (Goodbye) RTCP数据报文抓包如下图所示:

参考:
RFC3550 RTP/RTCP:
https://datatracker.ietf.org/doc/html/rfc3550
基于RFC 3547标准实现的RTP最小控制机制可参考IETF文档中的相关 RFC 内容
该文档描述了RTPPayloadFormat在H.264中的应用;可参考以下链接获取详细信息:[https://datatracker.ietf.org/doc/html/rfc6184]
(维基百科 RTP 协议)是一种用于多媒体流控制的协议
该协议是一种用于实时通信的关键技术
RTP、RTSP及H.264数据包分析:
RTP、RTSP及H.264数据包分析:
该资源标题为《RTCP协议解析与代码实现》,其具体链接为《RTCP协议解析与代码实现》一文的在线链接
