跳到主要内容

5. 发送多个媒体流的端点对 RTCP 的使用

RTCP 定义于 [RFC3550] 第 6 节. 该协议的描述是以 RTP 会话中"参与者"的行为来表述的, 其假设是每个端点都是一个具有单个 SSRC 的参与者. 然而, 为了在端点具有多个 SSRC 值的情况下正确运行, 实现必须 (MUST) 将每个 SSRC 视为 RTP 会话中的一个独立参与者, 这样具有多个 SSRC 的端点就计为多个参与者.

5.1. RTCP 报告要求​

具有多个 SSRC 的 RTP 端点必须 (MUST) 将每个 SSRC 视为 RTP 会话中的一个独立参与者. 每个 SSRC 将维护自己的 RTCP 相关状态信息, 因而将拥有自己的 RTCP 报告间隔, 以决定它何时发送 RTCP 报告. 如果未使用 [MULTI-STREAM-OPT] 中的机制, 则每个 SSRC 将针对所有其他 SSRC (包括位于同一端点的那些 SSRC) 发送 RTCP 报告.

如果端点有一些 SSRC 正在发送数据, 而另一些仅作为接收方, 那么它们将获得不同的 RTCP 带宽份额并计算出不同的基础 RTCP 报告间隔. 否则, 一个端点上的所有 SSRC 将计算出相同的基础 RTCP 报告间隔. 每个 SSRC 的实际报告间隔按通常方式随机化, 但报告可以按第 5.3 节所述进行聚合.

5.2. 初始报告间隔​

当参与者加入单播会话时, [RFC3550] 第 6.2 节的以下文字是相关的: "对于单播会话...发送初始复合 RTCP 包之前的延迟可以 (MAY) 为零." 基本假设是这在多个 SSRC 的情况下也应当适用. 然而, 当具有大量 SSRC 的端点 (或中间盒) 加入单播会话时必须谨慎, 因为立即发送许多 RTCP 报告会产生显著的流量突发, 导致瞬时拥塞以及因队列溢出而产生的丢包.

为确保 RTP 端点产生的初始流量突发不大于 TCP 连接会产生的流量突发, RTP 端点在加入 RTP 会话时, 无论该端点使用多少个 SSRC, 都不得 (MUST NOT) 发送超过四个初始延迟为零的复合 RTCP 包. 这些初始复合 RTCP 包中的每一个都可以 (MAY) 包含来自多个 SSRC 的聚合报告, 只要复合 RTCP 包的总大小不超过 MTU, 并且 avg_rtcp_size 按第 5.3.1 节的方式维护. 在初始复合 RTCP 包中聚合来自若干 SSRC 的报告, 可以使大量 SSRC 立即进行报告. 端点应当 (SHOULD) 优先报告那些可能最立即有用的 SSRC, 例如最初作为发送方的 SSRC.

需要报告的 SSRC 数量超过可立即发送的四个复合 RTCP 报告所能容纳的数量时, 该端点必须 (MUST) 稍后发送其余报告, 并遵循通常的 RTCP 定时规则 (包括定时器重新考虑). 这些报告可以 (MAY) 按第 5.3 节所述进行聚合.

注: 以上选择是为了匹配 TCP 的四个包的最大初始窗口 [RFC3390], 而不是正在实验中的更大的 TCP 初始窗口 [RFC6928]. 这样做的原因是希望保持保守, 因为在许多情况下 RTP 端点在发送这些初始 RTCP 包的同时也会开始发送 RTP 数据包.

5.3. 将报告聚合为复合 RTCP 包​

如第 5.1 节所述, 具有多个 SSRC 的端点在发送 RTCP 报告时, 必须将每个 SSRC 视为一个独立参与者. 这将导致每个 SSRC 在每个报告间隔内发送一个复合 RTCP 包. 由于这些包来自同一个端点, 人们有理由期望它们可以被聚合以减少开销. 事实上, [RFC3550] 第 6.1 节允许 RTP 转换器和混音器在类似情况下聚合包:

建议 (RECOMMENDED) 转换器和混音器在可行时将它们转发的来自多个源的各个 RTCP 包合并为一个复合包, 以分摊包开销 (见第 7 节). 图 1 展示了混音器可能产生的示例 RTCP 复合包. 如果复合包的总长度超过网络路径的 MTU, 则应 (SHOULD) 将其分割为多个较短的复合包, 并在底层协议的单独包中传输. 这不会损害 RTCP 带宽估计, 因为每个复合包至少代表一个不同的参与者. 注意每个复合包必须 (MUST) 以 SR 或 RR 包开头.

这允许 RTP 转换器和混音器生成复合 RTCP 包, 其中包含来自不同 SSRC 的多个发送方报告 (Sender Report, SR) 或接收方报告 (Receiver Report, RR) 包, 以及任何其他包类型. 对于这些 RTCP 包在复合包中出现的顺序没有限制, 只有通常的规则例外, 即复合 RTCP 包必须以 SR 或 RR 包开头. 由于这一规则, 正确实现的 RTP 端点将能够处理包含与多个 SSRC 相关的 RTCP 包的复合 RTCP 包.

因此, 使用多个 SSRC 的端点可以将其不同 SSRC 发送的 RTCP 包聚合为复合 RTCP 包, 前提是 1) 生成的复合 RTCP 包以 SR 或 RR 包开头, 2) 它们按第 5.3.1 节所述维护平均 RTCP 包大小, 3) 它们按第 5.3.2 节所述调度包的传输并管理聚合.

5.3.1. 维护 AVG_RTCP_SIZE​

[RFC3550] 中的 RTCP 调度算法基于每个 SSRC 工作. 每个 SSRC 在每个 RTCP 报告间隔内发送一个复合 RTCP 包. 当端点使用多个 SSRC 时, 最好将其各 SSRC 发送的复合 RTCP 包聚合起来, 通过形成更大的复合 RTCP 包来减少开销. 只要平均 RTCP 包大小的计算按如下方式更新, 这种聚合就可以按第 5.3.2 节所述进行.

RTP 会话中的参与者在每次发送或接收 RTCP 包时都会更新其对平均 RTCP 包大小 (avg_rtcp_size) 的估计 (见 [RFC3550] 第 6.3.3 节). 当发送或接收一个包含来自若干 SSRC 的 RTCP 包的复合 RTCP 包时, 对于其中被报告的每个 SSRC, 其 avg_rtcp_size 估计使用 div_packet_size 而不是实际包大小来更新:

avg_rtcp_size = (1/16) * div_packet_size + (15/16) * avg_rtcp_size

其中 div_packet_size 是 packet_size 除以该复合包中进行报告的 SSRC 数量. 复合包中进行报告的 SSRC 数量通过统计该复合 RTCP 包中作为 SR 或 RR RTCP 包来源的不同 SSRC 的数量来确定. 非复合 RTCP 包 (即不包含 SR 或 RR 包的 RTCP 包 [RFC5506]) 被视为报告单个 SSRC.

不遵循上述规则、而改用完整的 RTCP 复合包大小来计算 avg_rtcp_size 的参与者, 将得出一个过大的 RTCP 报告间隔, 其倍数与聚合到复合 RTCP 包中的 SSRC 数量以及被聚合的 SSRC 集合相对于参与者总数的大小成正比. 如果这一增大的 RTCP 报告间隔超过理解复合 RTCP、并聚合来自多个 SSRC 的报告的那些 SSRC 所选间隔的五倍, 就可能导致过早超时. 一个 1500 字节的 MTU 可以在一个复合 RTCP 包中容纳五个典型大小的报告, 因此如果端点聚合来自多个 SSRC 的 RTCP 报告, 这是一个切实的担忧.

上一段提出的问题通过本备忘录第 7.1.2 节所规定的超时行为修改而得到缓解. 这种缓解适用于 RTCP 带宽足够高、使得一个使用未考虑报告 SSRC 数量而计算出的 avg_rtcp_size 的端点能够以比大约每 5 秒更频繁的频率进行传输的情况. 不过请注意, 即使避免了其 SSRC 的过早超时, 未更新端点的 RTCP 报告仍然会受到负面影响. 如果与非更新端点的兼容性是一个考量, 那么聚合到单个复合 RTCP 包中的来自不同 SSRC 的报告数量应当 (SHOULD) 限制为两个报告, 或者根本不应使用聚合. 这将把未更新端点的 RTCP 报告间隔限制为不超过遵循本规范的端点所选 RTCP 报告间隔的两倍.

5.3.2. 聚合多个 SSRC 时的 RTCP 调度​

本节修订并扩展了 [RFC3550] 第 6.3 节中定义的行为, 以及在使用 RTP/AVPF 配置文件或 RTP/SAVPF 配置文件时 [RFC4585] 第 3.5.3 节中定义的行为, 这些行为涉及在多个报告 SSRC 将其 RTCP 包聚合到同一复合 RTCP 包中时调度和发送 RTCP 包所应采取的动作. 对 RTCP 调度规则的这些修改是必要的, 以维护重要的 RTCP 定时属性, 包括包间分布, 以及快速加入 (flash joins) 和会话成员关系其他变化期间的行为.

下文使用的变量 tn、tp、tc、T 和 Td 定义于 [RFC3550] 第 6.3 节. 变量 T_rr_interval 和 T_rr_last 定义于 [RFC4585].

每个端点必须 (MUST) 使用所使用 RTP 配置文件的常规 tn 计算, 为其每个 SSRC 独立调度 RTCP 传输. 每当某个 SSRC 的定时器 tn 到期时, 端点必须 (MUST) 执行 RTCP 定时器重新考虑, 并在适用时基于 T_rr_interval 执行抑制. 如果结果表明该 SSRC 要发送一个复合 RTCP 包, 且该传输不是早期 RTCP 包 [RFC4585], 那么端点应当 (SHOULD) 尝试在该复合 RTCP 包发送之前, 将计划在未来发送的其他 SSRC 的 RTCP 包聚合进去. 出于向后兼容原因而限制或不进行聚合的理由在第 5.3.1 节中讨论.

聚合过程如下. 端点选择在当前时间 tc 之后具有最小 tn 值的 SSRC, 并准备该 SSRC 在其定时器 tn 于 tc 到期时会发送的那些 RTCP 包. 如果在考虑路径 MTU 和先前已添加的 RTCP 包的情况下, 这些 RTCP 包能够放入正在生成的复合 RTCP 包中, 则将它们添加到该复合 RTCP 包; 否则将它们丢弃. 对每个 SSRC 按 tn 递增的顺序重复此过程, 直到该复合 RTCP 包已满或所有 SSRC 都已被聚合. 此时, 发送该复合 RTCP 包.

当发送该复合 RTCP 包时, 端点必须 (MUST) 为其中包含的每个 SSRC 更新 tp、tn 和 T_rr_last (如适用). 这些变量的更新方式如下:

  1. 对于在该复合 RTCP 包中进行报告的第一个 SSRC, 将该 SSRC 的有效传输时间 tt 设为 tc.
  2. 对于在该复合 RTCP 包中进行报告的每个额外 SSRC, 计算该 SSRC 在未被聚合进该复合 RTCP 包时所应有的传输时间. 其推导方法是取该 SSRC 的 tn, 然后执行重新考虑并更新 tn, 直到 tp + T <= tn. 完成后, 将该 SSRC 的有效传输时间 tt 设为计算出的 tn 值. 如果正在使用 RTP/AVPF 配置文件或 RTP/SAVPF 配置文件, 则在此计算中不得 (MUST NOT) 使用基于 T_rr_interval 的抑制.
  3. 基于该复合 RTCP 包中发送的所有 SSRC 的 tt 值, 计算该复合 RTCP 包的平均有效传输时间 tt_avg. 将该复合 RTCP 包中发送的每个 SSRC 的 tp 设为 tt_avg. 如果正在使用 RTP/AVPF 配置文件或 RTP/SAVPF 配置文件, 则将该复合 RTCP 包中发送的每个 SSRC 的 T_tt_last 设为 tt_avg.
  4. 对于该复合 RTCP 包中发送的每个 SSRC, 基于更新后的参数和通常的 RTCP 定时规则计算新的 tn 值, 并重新调度定时器.

在使用 RTP/AVPF 配置文件或 RTP/SAVPF 配置文件时, 上述机制仅在待发送的复合 RTCP 包不是早期 RTCP 包时才尝试聚合 RTCP 包, 因此 [RFC4585] 第 3.5.3 节中的算法将控制 RTCP 调度. 如果 T_rr_interval == 0, 或者 T_rr_interval != 0 且选择了该算法的选项 1、2a 或 2b, 则上述机制会更新必要的变量. 然而, 如果按该算法的选项 2c 抑制了传输, 则将 tp 更新为 tc, 因为未发生聚合.

反向重新考虑必须 (MUST) 遵循 [RFC3550] 第 6.3.4 节执行. 在某些情况下, 这可能导致反向重新考虑后的 tp 值大于 tc. 这不是问题, 并且具有如下期望的效果: 随着报告间隔按组规模的减小而成正比地缩短, tp 值 (以及 tn) 也被按比例拉向 tc.

上述算法已在仿真中 [Sim88] [Sim92] 被证明能够保持每个 SSRC 的 RTCP 包间传输时间分布, 并消耗与非聚合 RTCP 包相同的带宽量. 使用该算法时, 触发一次 RTCP 复合包传输的 SSRC 的实际传输间隔遵循常规传输规则. tp 值被设为领先 tc 的区间 [0, 1.5/1.21828*Td] 中的某个位置. 实际值是 tc 的一个实例与额外 SSRC 的随机化传输时间的平均值; 因此, 该区间的较低范围更可能出现. 这补偿了从聚合中包含的 N 个 SSRC 中挑选最短 tn 值否则会引入的偏差.

该算法还处理了能够包含在聚合包中的 SSRC 数量发生变化的情况. 一个先前被聚合但在包中放不下的 SSRC 仍会按正常规则调度自己的传输. 因此, 它将在适当的时候触发一次传输, 或者该 SSRC 将被包含在另一个聚合中. 该算法在 SSRC 组规模变化下的行为如下:

SSRC 数量正在增长的 RTP 会话: 当组规模增长时, Td 与组中新增 SSRC 的数量成正比地增长. 当由于 tn 定时器到期而执行重新考虑时, 该 SSRC 将重新考虑该传输, 并以一定概率重新调度 tn 定时器. 重新考虑算法的这一部分仅受上述算法的影响, 即上述算法具有位于未来的 tp 值, 而不是在更新 tp 时将其设为实际最后一次传输的时间.

SSRC 数量正在缩减的 RTP 会话: 当组规模缩减时, 反向重新考虑会将 tp 和 tn 值按离开会话的 SSRC 数量相对于它们离开时参与者总数的比例移向 tc. 将 tp 值设为相对于 tc 指向未来, 可能被认为会产生负面影响. 然而, 这样设置的原因是为了补偿从 N 个被聚合的 SSRC 中挑选最短 tn 所导致的偏差. 这种偏差在 SSRC 数量减少时依然存在. 反向重新考虑会补偿这种缩减, 与是否使用聚合无关. 移除某个 SSRC 时可能出现的负面影响是, 最有利的 tn 原本属于被移除的 SSRC. 其影响仅限于在最坏情况下将传输延迟一个报告间隔.

总之, 所进行的调研未发现对调度算法有显著的负面影响.

5.4. RTP/AVPF 或 RTP/SAVPF 反馈的使用​

本节讨论发送端点具有多个 SSRC 时 RTP/AVPF 反馈包的传输. 本节的指南也适用于使用 RTP/SAVPF 配置文件的端点.

5.4.1. 反馈包的 SSRC 选择​

当 RTP/AVPF 端点具有多个 SSRC 时, 它可以选择使用哪个 SSRC 作为其发送的 RTCP 反馈包的来源. 若干因素会影响这一选择:

  • 与特定媒体类型相关的 RTCP 反馈包应当 (SHOULD) 由接收该媒体类型的 SSRC 发送. 例如, 当音频和视频复用到单个 RTP 会话时, 端点将使用其音频 SSRC 来发送关于从其他参与者接收到的音频的反馈.
  • 作为关于端点所处理 RTP 数据的通知或指示的 RTCP 反馈包和 RTCP 编解码器控制消息, 必须 (MUST) 从用于该 RTP 数据的 SSRC 发送. 这包括与先前接收到的请求或命令相关的通知 [RFC4585][RFC5104].
  • 如果使用单独的 SSRC 来发送和接收媒体, 那么应当 (SHOULD) 使用相应的 SSRC 进行反馈, 因为它们具有不同的 RTCP 带宽份额. 这也可能影响关于该 SSRC 是否可以用于立即模式的考量.
  • 某些 RTCP 反馈包类型要求所使用的 SSRC 保持一致. 例如, 如果由某个 SSRC 设置了临时最大媒体流比特率请求 (Temporary Maximum Media Stream Bit Rate Request, TMMBR) 限制 [RFC5104], 则需要使用同一个 SSRC 来移除该限制.
  • 如果有若干 SSRC 都适合发送反馈, 那么可能希望使用一个允许将反馈作为早期 RTCP 包发送的 SSRC.

当 RTCP 反馈包作为聚合来自多个 SSRC 的报告的复合 RTCP 包的一部分发送时, 并不要求该复合包包含由该 RTCP 反馈包发送方生成的 SR 或 RR 包. 对于缩减大小 RTCP 包, 来自多个源的 RTCP 反馈包的聚合除了 [RFC5506] 第 4.2.2 节之外不受进一步限制.

5.4.2. RTCP 反馈包的调度​

当某个 SSRC 需要以早期模式发送反馈包时, 它必须 (MUST) 按 [RFC4585] 第 3.5 节的算法调度该包, 并作如下修改:

  • 为确定一个 RTP 会话被视为点对点会话还是多方会话, 端点必须 (MUST) 统计它所接收的 RTP 数据包的 SSRC 字段中列出的 SSRC 以及它所接收的 RTCP SR、RR、RTPFB 或 PSFB 包的"发送方 SSRC"字段中使用的不同 RTCP SDES CNAME 值的数量. 如果这些 SSRC 使用了不止一个 CNAME, 则该 RTP 会话被视为多方会话, 除非信令表明该会话应按点对点方式处理, 或者使用了 RTCP 报告组 [MULTI-STREAM-OPT]. 如果使用了 RTCP 报告组, 则当端点仅接收到一个报告组时该 RTP 会话被视为点对点会话, 而当接收到多个报告组, 或接收到报告组与不属于任何报告组的 SSRC 的组合时, 被视为多方会话. 端点不得 (MUST NOT) 基于所使用的连接类型 (单播或组播) 或所接收的 SSRC 数量来确定一个 RTP 会话是多方还是点对点.
  • 在检查是否已有包含反馈消息的计划复合 RTCP 包时 ([RFC4585] 第 3.5.2 节中的第 2 步), 该检查必须 (MUST) 考虑所有本地 SSRC.
  • 如果不允许某个 SSRC 发送早期 RTCP 包, 则该反馈消息可以 (MAY) 排队等待, 作为在该反馈消息的最大有效生存期 (T_max_fb_delay) 内可能发生的任何早期或常规计划传输的一部分发送. 这修改了 [RFC4585] 第 3.5.2 节第 4a 项中的行为.

上面的第一个要点规定了一条确定 RTP 会话应被视为点对点会话还是多方会话的规则. 该规则实现起来很直接, 但已知会将某些会话错误地归类为多方会话. 已知问题如下:

具有多个同步上下文的端点: 属于点对点会话的端点可能具有多个同步上下文, 例如由于将外部媒体源转发到交互式实时对话中. 在这种情况下, 该分类会将对端视为两个端点, 而实际的 RTP/RTCP 传输却处于一个端点的控制之下.

选择性转发中间盒: [RFC7667] 第 3.7 节所定义的选择性转发中间盒 (Selective Forwarding Middlebox, SFM) 对自身与每个对端端点之间的传输和配置具有单独的控制权. 它还完全控制在各条单独的链路上转发的 RTCP 包. 因此, 这类中间盒可以与 RTP 混音器相比拟: RTP 混音器使用自己的 SSRC 来混合或选择其转发的媒体, 按上述规则它会被归类为点对点 RTP 会话.

在上述情况下, 使用 RTCP 报告组 [MULTI-STREAM-OPT] 是非常合理的. 如果使用了该扩展, 端点可以仅使用单个报告组来表明众多 CNAME 实际上处于单个端点或中间盒的控制之下.

上述规则还会将某些端点连接到 RTP 混音器的会话归类为点对点. 例如, 对于所讨论的端点, 混音器可能充当通向基于任意源组播 (Any Source Multicast) 的 RTP 会话的网关. 然而在大多数情况下这是可以接受的, 因为 RTP 混音器在两个会话部分之间提供了隔离. 责任落在混音器身上, 使其在每个域中相应行事.

最后我们注意到, 可以定义信令机制, 以在上述规则会导致错误分类时覆盖这些规则.