【网络通信 -- 直播】网络通信协议简介 -- RTP/RTCP
【1】RTP 协议
【1.1】RTP 协议的基本作用
RTP 协议,实时传输协议(the real-time transport protocol),位于 UDP 之上、应用层之下,应用层产生的实时数据首先被封装成 RTP 分组格式,然后再将 RTP 分组封装成 UDP 分组格式并通过传输层协议进行传输;由于 UDP 无法检测分组的丢失、错序,因此需要实时数据块携带时间戳以保持采样和播放之间的同步关系,同时需要对分组进行编号从而确定分组顺序,检测分组丢失;RTP 主要提供同步播放多媒体数据所需要的时间戳和序号;
【1.2】RTP 协议格式
RTP 分组由首部和净荷组成,净荷通常为数字化的多媒体数据,通过采样多媒体信号、量化采样信号并对量化后的采样数据进行编码得到;经过编码的数字化多媒体数据添加 RTP 首部后,发送给 UDP 层传输;
RTP 首部格式
RTP 首部各字段说明
字段 | 长度 | 说明 | 补充 |
版本字段(V) | 2 位 | RTP 的版本号 | |
填充位(P) | 1 位 | 净荷末端是否包含一个或多个填充字节 | 净荷长度必须是4字节的倍数,因此需要填充字节使得净荷长度满足4字节倍数的要求,净荷的最后一个字节给出填充字节数 |
扩展位(X) | 1 位 | RTP 首部扩展 | RTP 首部扩展是可选的,若扩展位置1,表明在固定首部之后紧跟着一个首部扩展 |
提供源计数器(CC) | 4 位 | RTP 首部中提供源标识符列表中的项数 | |
信标位(M) | 1 位 | 含义取决于携带净荷的类型 | 对于视频,标记一帧的结束;对于音频,标记会话的开始 |
净荷类型(PT) | 7 位 | RTP 净荷的格式 | 通常,单个 RTP 分组所包含的净荷只能用一种净荷格式对多媒体数据进行编码 |
序号 | 16 位 | 会话开始时,发送端生成随机数作为初始值,传送 RTP 分组时,每传送一组该字段增 1 | 在会话存在期间,顺序发送的一串 RTP 分组的序号是递增的,接收端可以根据序号检测是否存在分组丢失或错序 |
时间戳 | 32 位 | 净荷中第一个采样数据的采样时间,每一个采样数据的采样时间通过一个单调且线性递增的时钟获得 | 时钟频率取决于净荷数据的编码格式,相邻两个 RTP 分组的时间戳差值,取决于前一个 RTP 分组净荷中包含的采样数据数目 |
同步源标识符(SSRC) | 32 位 | 标明同步源,同步源是一个负责发送 RTP 分组并在 RTP 分组中设置序号和时间戳的实体 | 标识符是会话中全局惟一的,若 RTP 分组来自混合器则同步源标识符给出的是混合器的标识符 |
提供源标识符列表(CSRC) | 32 位 | 最多允许存在16个提供源标识符 | 若 RTP 分组来自混合器则提供源标识符列表给出进入混合器的各个信号的信号源标识符 |
语音和视频编码对应的净荷类型
净荷类型 | 编码类型 | 媒体类型 | 时钟频率(Hz) | 净荷类型 | 编码类型 | 媒体类型 | 时钟频率(Hz) |
0 | PCMU | 语音 | 8000 | 14 | MPA | 语音 | 90000 |
1 | 1016 | 语音 | 8000 | 15 | G728 | 语音 | 8000 |
2 | G726-32 | 语音 | 8000 | 16 | DVI4 | 语音 | 11025 |
3 | GSM | 语音 | 8000 | 17 | DVI4 | 语音 | 22050 |
4 | G723 | 语音 | 8000 | 18 | GF29 | 语音 | 8000 |
5 | DVI4 | 语音 | 8000 | 25 | CeIB | 视频 | 90000 |
6 | DVI4 | 语音 | 16000 | 26 | JPEG | 视频 | 90000 |
7 | LPC | 语音 | 8000 | 28 | Nv | 视频 | 90000 |
8 | PCMA | 语音 | 8000 | 31 | H.261 | 视频 | 90000 |
9 | G722 | 语音 | 8000 | 32 | MPV | 视频 | 90000 |
10 | L16 | 语音 | 44100 | 33 | MP2T | 语音/视频 | 90000 |
11 | L16 | 语音 | 44100 | 34 | H.263 | 视频 | 90000 |
12 | QCEIP | 语音 | 8000 |
RTP 首部扩展格式
RTP 首部扩展可以用于提供特定净荷格式要求提供的额外信息;
【1.3】RTP 混合器与转换器
混合器的作用是将来自不同信号源的多个媒体信息流组合成单一的 RTP 数据流;
如图,发送给某个终端的 RTP 分组流,不是来自其他终端的 RTP 分组流集合,而是综合了这些终端发送的多媒体数据后生成的 RTP 分组流,并且该 RTP 分组仅需 64kbit/s带宽;
转换器的作用是管理两个媒体数据格式或位速率不同的实体之间的通信;
如图,不同终端的净荷格式会经过转换器转换,但 RTP 分组的同步源标识符是发送端的标识并非转换器的标识符;
【2】RTCP 协议
RTCP,RTP 控制协议(the RTP control protocol),通过周期性交换会话两端实体的控制信息,为会话两端实体提供质量反馈信息,该反馈信息可以用于检测并解决实时传输中存在的问题,从而使得第三方得以监测会话质量和网络中发生的问题;
RTCP 分组的类型
类型 | 说明 | 补充 |
发送者报告(SR) | 会话参与者用其转发有关传输和接收的统计信息 | |
接收者报告(RR) | 只接收媒体数据流的会话参与者用其发送有关接收的统计信息 | |
源描述(SDES) | 包含一个或多个与某个特定会话参与者相关的描述信息 | 通常必须包含用于标识会话参与者的规范名字(CNAME),同一实体生成的多个 RTP 数据流具有相同的规范名字(CNAME);在接收端规范名字可用于关联这些 RTP 数据流以支持多个 RTP 数据流的同步播放;在特定会话内,规范名字(CNAME)必须是惟一的; |
BYE | 标识会话参与者退出某个会话 | |
APP | 传输有关特定媒体或应用的信息 | 传输内容没有特殊规定 |
通常,不同类型的 RTCP 分组会被组合成单个复合分组并统一发送;同时,RTCP 协议规定,每个 RTCP 复合分组必须包含 SR/RR 和 SDES 分组并以报告分组(SR/RR)作为复合分组的开始;原因,尽可能发送 SR/RR 分组以确保统计精确性;尽可能发送 SDES 分组可以使得新的会话参与者尽快获取各个媒体发送源的标识信息(如 CNAME),从而尽快地将接收到的媒体数据流与发送源联系起来;
【2.1】RTCP 发送者报告(SR)分组
只有发送并接收 RTP 分组的会话参与者才会使用发送者报告,发送者报告由首部信息、发送者信息、若干接收者报告块以及描述的扩展区组成;
字段 | 长度 | 说明 | 补充 |
版本(V) | 2 位 | 当前版本号 | |
填充位(P) | 1 位 | 指明分组末端是否存在填充字节 | 若 P 置 1 则表明分组末端存在填充字节,且分组末端的最后一个字节给定填充的字节数 |
接收报告数(RC) | 5 位 | 指明分组所包含的接收者报告块的数量 | 若某个会话参与者需要向其他会话参与者发送多于 31 的接收者报告块,可以在 RTP 复合分组中的 SR 分组后紧跟一个 RR 分组实现 |
净荷类型(PT) | 8 位 | 指明净荷类型 | SR 分组的净荷类型固定为 200 |
长度 | 16 位 | 指明 SR 分组的总长度 | |
发送者同步源标识符(SSRC) | 32 位 | 标识发送者的同步源标识符 | |
NTP 时间戳 | 64 位 | 网络时间协议(NTP)的时间戳 | 时间戳信息通过NTP从时间服务器获得,主时间服务器通常从一个或多个总时钟源获取时钟信息 |
RTP 时间戳 | 32 位 | 通过单调线性递增的时钟计数器获得,基本递增单位取决于净荷格式 | |
发送者分组计数器 | 32 位 | 给定发送者从会话开始到报告发送时,已经发送的 RTP 分组的数量 | 发送者分组计数器从会话开始不断累计发送者发送的 RTP 分组,只有当 SSRC 改变时,才会对发送者分组计数器清零 |
发送者字节计数器 | 32 位 | 给定发送者从会话开始到报告发送时,已经发送的字节数 | 发送者字节计数器从会话开始不断累计发送者发送的字节数,一旦发送者 SSRC 改变,则对发送者字节计数器清零 |
源标识符(SSRC_n) | 32 位 | 接收者报告块中数据所关联的会话参与者的同步源标识符 | |
分组丢失率 | 8 位 | 指明从前一个报告发送后到当前时段内 RTP 分组的丢失率 | |
丢失分组总数 | 24 位 | 自 RTP 会话开始以来,累计丢失的 RTP 分组数量 | |
扩展的最高序号 | 32 位 | 低 16 位指明接收到的最后一个 RTP 分组的序号,高 16 位指明序号循环次数 | 16 位 RTP 分组序号范围 0 ~ 65535,当序号为 65535 的 RTP 分组接收后,下一个 RTP 分组序号重新为 0;此时意味着循环了一次 |
间隔抖动 | 32 位 | 指明 RTP 分组到达间隔变化的一个估计值 | |
最新的发送者报告时间戳(LSR) | 32 位 | 接收到的来自 SSRC_n 所指定源终端的最后一个发送者报告中 64 位 NTP 时间戳的中间 32 位 | |
SR 最新间隔(DLSR) | 32 位 | 以 1/65536 秒为单位给定接收到 SSRC_n 所指定的源终端的最后一个发送者报告后到该接收者报告块发送时的时间间隔 |
注,RTCP 本身并不对用于描述的扩展区的内容进行定义;
【2.2】RTCP 接收者报告(RR)分组
由只接收 RTP 分组的会话参与者发送,由于发送接收者报告的会话参与者没有将 RTP 分组发送给其他会话参与者,因此接收者报告中没有列出有关发送者关于已发送 RTP 分组的一些统计信息;
字段 | 长度 | 说明 | 补充 |
版本(V) | 2 位 | 当前版本号 | |
填充位(P) | 1 位 | 指明分组末端是否存在填充字节 | 若 P 置 1 则表明分组末端存在填充字节,且分组末端的最后一个字节给定填充的字节数 |
接收报告数(RC) | 5 位 | 指明分组所包含的接收者报告块的数量 | 若某个会话参与者需要向其他会话参与者发送多于 31 的接收者报告块,可以在 RTP 复合分组中的 SR 分组后紧跟一个 RR 分组实现 |
净荷类型(PT) | 8 位 | 指明净荷类型 | SR 分组的净荷类型固定为 201 |
长度 | 16 位 | 指明 RR 分组的总长度 | |
发送者同步源标识符(SSRC) | 32 位 | 标识发送者的同步源标识符 | |
NTP 时间戳 | 64 位 | 网络时间协议(NTP)的时间戳 | 时间戳信息通过NTP从时间服务器获得,主时间服务器通常从一个或多个总时钟源获取时钟信息 |
RTP 时间戳 | 32 位 | 通过单调线性递增的时钟计数器获得,基本递增单位取决于净荷格式 | |
发送者分组计数器 | 32 位 | 给定发送者从会话开始到报告发送时,已经发送的 RTP 分组的数量 | 发送者分组计数器从会话开始不断累计发送者发送的 RTP 分组,只有当 SSRC 改变时,才会对发送者分组计数器清零 |
发送者字节计数器 | 32 位 | 给定发送者从会话开始到报告发送时,已经发送的字节数 | 发送者字节计数器从会话开始不断累计发送者发送的字节数,一旦发送者 SSRC 改变,则对发送者字节计数器清零 |
源标识符(SSRC_n) | 32 位 | 接收者报告块中数据所关联的会话参与者的同步源标识符 | |
分组丢失率 | 8 位 | 指明从前一个报告发送后到当前时段内 RTP 分组的丢失率 | |
丢失分组总数 | 24 位 | 自 RTP 会话开始以来,累计丢失的 RTP 分组数量 | |
扩展的最高序号 | 32 位 | 低 16 位指明接收到的最后一个 RTP 分组的序号,高 16 位指明序号循环次数 | 16 位 RTP 分组序号范围 0 ~ 65535,当序号为 65535 的 RTP 分组接收后,下一个 RTP 分组序号重新为 0;此时意味着循环了一次 |
间隔抖动 | 32 位 | 指明 RTP 分组到达间隔变化的一个估计值 | |
最新的发送者报告时间戳(LSR) | 32 位 | 接收到的来自 SSRC_n 所指定源终端的最后一个发送者报告中 64 位 NTP 时间戳的中间 32 位 | |
SR 最新间隔(DLSR) | 32 位 | 以 1/65536 秒为单位给定接收到 SSRC_n 所指定的源终端的最后一个发送者报告后到该接收者报告块发送时的时间间隔 |
【2.3】RTCP 源终端描述(SDES)分组
提供用于标识特定会话参与者的标识信息及其他相关信息,由分组首部以及零个或多个信息块组成;
字段 | 长度 | 说明 | 补充 |
版本(V) | 2 位 | 当前版本号 | |
填充位(P) | 1 位 | 指明分组末端是否存在填充字节 | 若 P 置 1 则表明分组末端存在填充字节,且分组末端的最后一个字节给定填充的字节数 |
源终端计数器(SC) | 5 位 | 指明 SDES 分组中信息块的数量 | SDEC 分组包含的信息块数量不能超过 31 |
净荷类型(PT) | 8 位 | 指明净荷类型 | SDES 分组的净荷类型固定为 202 |
长度 | 16 位 | 指明 SDES 分组的总长度 | |
SSRC/CSRC_n | 每一个信息块由一个同步源标识符(SSRC)或提供源标识符(CSRC),以及一系列源终端相关联的标识信息组成 | 源终端相关联的标识信息,称为 SDES 项,通常包含 E-mail地址、电话号码及姓名等;SDES分组中若存在信息块,则该信息块必须包含 CNAME SDES 项; |
注,在指定会话中,会话参与者的 CNAME 是不变且惟一的,CNAME 一般采用用户名@域名格式;虽然,通常情况下,会话参与者的 SCRC 也是不变且惟一的,但若会话过程中发生两个会话参与者取了相同的 SCRC 值或者源终端因为复位而重新对 SSRC 取值,会话参与者的 SSRC 将发生变化;
【2.4】BYE 分组
用于指明存在一个或多个源终端将退出会话,同时可以包含退出原因的文本信息;
字段 | 长度 | 说明 | 补充 |
版本(V) | 2 位 | 当前版本号 | |
填充位(P) | 1 位 | 指明分组末端是否存在填充字节 | 若 P 置 1 则表明分组末端存在填充字节,且分组末端的最后一个字节给定填充的字节数 |
源终端计数器(SC) | 5 位 | 指明分组中所包含的源终端描述符(SSRC / CSRC)的数量 | |
净荷类型(PT) | 8 位 | 指明净荷类型 | BYTE 分组的净荷类型固定为 203 |
长度 | 16 位 | 指明 BYTE 分组的总长度 | |
SSRC / CSRC | 指明将退出会话的源终端描述符 | ||
opt 可选信息 | 区域的第一个字节(8 位)作为长度给出文本信息区域的字节数 | 文本信息以字符串形式表示 |
【2.5】应用相关(APP)分组
RTP 控制分组中包含了应用相关的功能分组,使得增加用户特定应用所需要的功能提供了灵活性;
字段 | 长度 | 说明 | 补充 |
版本(V) | 2 位 | 当前版本号 | |
填充位(P) | 1 位 | 指明分组末端是否存在填充字节 | 若 P 置 1 则表明分组末端存在填充字节,且分组末端的最后一个字节给定填充的字节数 |
子类型(subtype) | 5 位 | 指明分组中所包含的数据类型 | |
净荷类型(PT) | 8 位 | 指明净荷类型 | APP 分组的净荷类型固定为 204 |
长度 | 16 位 | 指明 APP 分组的总长度 | |
名字(name) | 指明标明应用创建者的 ASCII 码 | ||
应用相关数据 |
【2.6】关键参数的计算方法
【2.6.1】往返时间
根据 RTCP 发送者报告(SR) 分组和接收者报告(RR) 分组可以计算分组的往返时间;
设会话参与者 A 在 T1 发送了 RTCP 发送者报告分组 A,会话参与者 B 在 T2 接收到了该发送者报告分组 A;会话参与者 B 在 T3 发送了接收者报告分组 B,会话参与者 A 在 T4 接收到了该接收者报告分组 B;
当会话参与者 B 接收到会话参与者 A 发送的发送者报告分组 A 时,可以从分组 NTP 时间戳字段中复制下会话参与者 A 发送分组的时间 T1,同时记录接收到该分组的时间 T2,当会话参与者 B 向会话参与者 A 发送接收者报告分组 B 时,LSR 时间戳字段中给定最后接收到的发送者报告分组(发送者报告分组 A)中 NTP 时间戳字段值中的中间 32 位,即 T1,DLSR 字段值给定从接收到最后一个发送者报告分组(发送者报告分组 A)到发送当前接收者报告分组之间的时间间隔,即 T3 - T2;
则往返时间计算公式如下
往返时间 = T4 - T3 + T2 - T1 = T4 - (T3 - T2) - T1 = T4 - DLSR - LSR;
【2.6.2】时延抖动
时延抖动的定义为分组传输时延差的平均值;相邻分组 i 与 j 其传输时延差为 ,其中 和 为分组 i 和 j 的发送时间, 和 为分组 i 和 j 的接收时间;时延抖动通过如下递归公式计算获取,
,,实际上, ;
当 取值较大时,当前时延抖动值主要取决于过去求得的时延抖动值;当 较小时,当前时延抖动主要取决于当前求得的相邻分组的传输时延差;
【2.6.3】RTCP 分组发送频率的确定标准
确定 RTCP 分组发送频率时,必须保证控制信息限制在一个较小的范围内,传输控制信息所使用的带宽只占会话带宽的一小部分;RTCP 分组发送频率计算方法的主要特征如下;
- 1. 所有发送者发送控制信息所占用的带宽综合可以占到会话带宽的 25%;
- 2. RTCP 分组发送间隔必须大于 5 秒;
- 3. 实际发送间隔为 RTCP 分组发送间隔乘以 0.5 ~ 1.5 之间的随机数,从而避免多个会话参与者同步发送 RTCP 分组;
- 4. 动态估计 RTCP 复合分组的平均长度,当 RTCP 复合分组的长度增大时,必须降低发送速率,以此限制控制信息所占用的会话带宽的比例;
参考致谢
本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。
【1】多媒体传输网络与VOIP系统设计
【2】RTP -- RFC3550