5. 在单个端口上复用 RTP 和 RTCP
在单个端口上复用 RTP 和 RTCP 的过程取决于会话是单播会话还是多播会话. 对于多播会话, 该过程还取决于是使用 Any Source Multicast (ASM) 还是 Source-Specific Multicast (SSM).
5.1. 单播会话
对于单播会话, 为了简化 NAT 穿越, 可以在单个 UDP 端口上复用 RTP 和 RTCP 数据包, 前提是会话中使用的 RTP 负载类型按照第 4 节的规则选择, 并且复用已提前发出信号. 以下小节描述如何使用带 offer/answer 模型的 Session Initiation Protocol (SIP) 来发出这类复用会话信号.
5.1.1. SDP 信令
当使用 Session Description Protocol (SDP) [8] 按 offer/answer 模型 [9] 协商 RTP 会话时, "a=rtcp-mux" 属性 (见第 8 节) 表示希望把 RTP 和 RTCP 复用到单个端口上. 初始 SDP offer 必须在媒体级别包含此属性, 以请求在单个端口上复用 RTP 和 RTCP. 例如:
v=0
o=csp 1153134164 1153134164 IN IP6 2001:DB8::211:24ff:fea3:7a2e
s=-
c=IN IP6 2001:DB8::211:24ff:fea3:7a2e
t=1153134164 1153137764
m=audio 49170 RTP/AVP 97
a=rtpmap:97 iLBC/8000
a=rtcp-mux
此 offer 表示一个使用 RTP/AVP profile 和 iLBC 编码的单播 IP 语音会话. 它请求 answerer 将 RTP 和 RTCP 都发送到 IPv6 地址 2001:DB8::211:24ff:fea3:7a2e 上的端口 49170.
如果 answerer 希望把 RTP 和 RTCP 复用到单个端口上, 它必须在 answer 中包含媒体级别的 "a=rtcp-mux" 属性. answer 中使用的 RTP 负载类型必须符合第 4 节中的规则.
如果 answer 不包含 "a=rtcp-mux" 属性, offerer 禁止在单个端口上复用 RTP 和 RTCP 数据包. 相反, 它应当在按照通常端口选择规则分配的端口上发送和接收 RTCP (即端口对, 或者如果还包含 "a=rtcp:" 属性 [10], 则使用发出信号的端口). 当与不理解 "a=rtcp-mux" 属性的对等方通信时, 会出现这种情况.
当 SDP 以声明方式使用时, "a=rtcp-mux" 属性的存在表示发送方将在同一端口上复用 RTP 和 RTCP. 接收方必须准备在 RTP 端口上接收 RTCP 数据包, 并且任何资源预留都需要包含 RTCP 带宽.
5.1.2. 与 SIP 分叉的交互
使用带分叉代理的 SIP 时, 一个 INVITE 请求可能产生多个 200 (OK) 响应. 如果该 INVITE 中提供了 RTP 和 RTCP 复用, 就必须注意: 某些 answerer 可能支持复用 RTP 和 RTCP, 另一些则不支持. 这会要求 offerer 同时在 RTP 端口和通常的 RTCP 端口上监听 RTCP, 并在两个端口上发送 RTCP, 除非支持复用的呼叫分支被重新协商为使用单独的 RTP 和 RTCP 端口.
5.1.3. 与 ICE 的交互
在存在 Network Address Translation (NAT) 设备或其他中间盒时, 通常使用 Interactive Connectivity Establishment (ICE) [19] 方法来建立 RTP 会话. 如果 RTP 和 RTCP 在单独端口上发送, RTP 媒体流在 ICE 中包含两个组件 (一个用于 RTP, 一个用于 RTCP), 并对每个组件执行连通性检查. 如果 RTP 和 RTCP 要在同一端口上复用, 则可以避免其中一些连通性检查, 从而降低 ICE 开销.
如果希望同时使用 ICE 以及复用的 RTP 和 RTCP, 初始 offer 必须包含 "a=rtcp-mux" 属性以指示希望进行 RTP 和 RTCP 复用, 并且必须同时包含 RTP 和 RTCP 的 "a=candidate:" 行, 以及一条 "a=rtcp:" 行, 用于在 answerer 不支持 RTP 和 RTCP 复用时指示 RTCP 的回退端口. 对于希望进行 RTP 和 RTCP 复用的每个媒体, 都必须这样做.
如果 answerer 希望在单个端口上复用 RTP 和 RTCP, 它必须为每个希望使用 RTP 和 RTCP 复用的媒体生成包含 "a=rtcp-mux" 属性以及与 RTP 端口对应的单条 "a=candidate:" 行的 answer (即没有 RTCP candidate). 然后, answerer 针对该媒体执行连通性检查, 就好像 offer 只包含单个 RTP candidate 一样. 如果 answerer 不想在单个端口上复用 RTP 和 RTCP, 则禁止在其 answer 中包含 "a=rtcp-mux" 属性, 并且必须按通常方式对所有提供的 candidate 执行连通性检查.
收到 answer 后, offerer 会针对每个提供了复用的媒体检查是否存在 "a=rtcp-mux" 行. 如果存在, 则连通性检查会像只提供了单个 candidate (用于 RTP) 一样继续, 并在会话建立后使用复用. 如果不存在 "a=rtcp-mux" 行, 会话会使用 RTP 和 RTCP candidate 继续执行连通性检查, 最终建立 RTP 和 RTCP 位于单独端口上的会话 (如 "a=rtcp:" 属性所发出的信号).
5.1.4. 与头部压缩的交互
将 RTP 和 RTCP 数据包复用到单个端口上可能会负面影响头部压缩方案, 例如 Compressed RTP (CRTP) [20] 和 RObust Header Compression (ROHC) [21] [22]. 头部压缩利用连续数据包 RTP 头部中的变化模式, 发送一个指示来说明数据包按预期方式变化, 而不是每次都发送完整头部. 如果流具有一致行为, 这可以带来显著的带宽节省.
与 RTP 数据包复用的 RTCP 数据包可能扰乱头部之间的变化模式, 并可能显著降低头部压缩效率. 这种扰乱的程度取决于所用头部压缩算法以及流的分类方式. 设计良好的分类器应能使用负载类型字段, 将复用在同一端口上的 RTP 和 RTCP 分离到不同压缩上下文中, 从而使其对压缩率的影响较小. 仅根据 IP 地址和 UDP 端口分配压缩上下文的分类器表现不会很好. 预期头部压缩实现需要更新, 以便高效支持复用在同一端口上的 RTP 和 RTCP.
在某些环境中, 例如一些依赖头部压缩效率来使媒体适配有限容量信道的无线电话系统, RTP 和 RTCP 复用对头部压缩的影响可能尤其显著. 在这类环境中使用复用之前, 应仔细考虑复用 RTP 和 RTCP 的影响.
5.2. Any Source Multicast 会话
对于 Any Source Multicast (ASM) RTP 会话, NAT 穿越问题没有单播 RTP 会话那么严重, 并且由于能够支持第三方 RTCP-only 监视器, 使用 RTP 和 RTCP 单独端口的收益更大. 因此, 使用 ASM RTP 会话时, 不应把 RTP 和 RTCP 数据包复用到单个端口上, 而应使用单独端口和多播组.
5.3. Source-Specific Multicast 会话
运行在 Source-Specific Multicast (SSM) 之上的 RTP 会话会通过多播信道从源向接收方发送 RTCP 数据包, 但使用单独的单播反馈机制 [6] 从接收方向源发送 RTCP; 源随后要么把 RTCP 数据包反射给组, 要么发送聚合摘要报告.
按照 [6] 的术语, 我们在 SSM 会话中识别出三个 RTP/RTCP 流:
-
媒体发送方和分发源之间的 RTP 和 RTCP 流. 在许多场景中, 媒体发送方和分发源位于同一位置, 因而复用不是问题. 如果媒体发送方和分发源通过单播连接相连, 则本文第 5.1 节的规则适用于该连接. 如果媒体发送方和分发源通过 Any Source Multicast 连接相连, 则第 5.2 节的规则适用于该连接. 如果媒体发送方和分发源通过 Source-Specific Multicast 连接相连, 则可以在单个端口上复用 RTP 和 RTCP 数据包, 前提是已发出信号 (如果使用 SDP, 则使用
"a=rtcp-mux"). -
从分发源发送到接收方的 RTP 和 RTCP. 分发源可以把 RTP 和 RTCP 复用到单个端口上, 以缓解前向 SSM 路径上的 NAT 穿越问题, 但如果会话使用简单反馈模型, 这样做可能妨碍第三方监视设备. 使用 SDP 时, 应当使用
"a=rtcp-mux"属性发出复用信号. -
从接收方发送到分发源的 RTCP. 这是仅 RTCP 路径, 因而复用不是问题.
在 SSM 会话中把 RTP 和 RTCP 数据包复用到单个端口上, 可能会与第 5.1.4 节所述的头部压缩发生交互.