流媒体传输协议之 RTP(下篇) (4)

有的 Translator 可能对收到的 RTCP 报文不做任何改动,只是简单的转发这个包。如果这个 Translator 改变了报文数据的 payload,它必须对 SR 或者 RR 做相关的改动。通常来说,Translator 不能将多个数据源的 SR 和 RR 合并,因为这样会导致 RTT 的计算出现问题(RTT 根据 LSR 和 DLSR 计算)。

SR 中的发送者信息: Translator 不会创建自己的发送者信息,它会将收到 SR 传给下家。其中 SSRC 不会发生任何改动,但是发送者信息有必要的话一定要做适当的改动。如果 Translator 改变了数据编码,那 "byte count" 字段就要更改。如果他将多个数据报文合并,那它需要修改 "sender's packet count" 字段。如果它改变了时间频率,那就需要修改 "RTP timestamp"。

SR/RR 中的接收者信息:SSRC 不会发生任何改动,如果 Translator 改变了序列号,那就需要修改 "extended last sequence number",在某些极端情况下,它可能完全没有接收反馈,或者根据接收到的 SR/RR 来构建自己的接收报告。一般情况下 Translator 是不需要自己的 SSRC 的,但是如果是为了表示自己的数据接收情况,它可能也会生成自己的 SSRC,并将这些 RTCP 报文发送过所有的连接者。

SDES:一般 Translator 收到 SDES 后会什么都不改就发给下家,但是也有可能为了节约带宽筛掉 CNAME 之外的信息的,如果 Translator 要发送自己的 RR 信息,那它一定要发送一个自己的 SDES 给所有连接者。

BYE:无改动转发,如果 Translator 有自己的 SSRC 也要发送自己的 BYE。

APP:无改动转发。

Mixer 处理 RTCP

因为 Mixer 会生成自己的数据流,所以他不会转发经过他的 SR 和 RR 而是为连接双方发送自己的 SR 和 RR 报文。

SR 的发送者信息:Mixer 不转发数据来源的发送信息。它会生成自己的发送者信息并把它发送给下家。

SR/RR 中的接收者信息:Mixer 会生成自己的接收信息,然后发送给所有数据来源,它绝对不能做接收报告的转发工作,或者把自己的接收信息发给错误的对象。

SDES:Mixers 通常会不做任何改动就转发 SDES 信息,但是也有可能为了节约带宽过滤除了 CNAME 之外的其他信息。Mixer 必须发送自己的 SDES 报文。通常,Mixer 会将多个收到的 SDES 打包一起发送。

BYE:Mixer 必须转发 BYE 报文。如果 Mixer 要退出时,它会将所有数据来源的 SSRC 放进 BYE 报文,也包括自己的 SSRC。

APP:视上层应用。

瀑布型 Mixer

一个 RTP Session 可能包含多个 Mixer 和 Translator,就像上图一样。如果 Mixer 是瀑布型的,就像 M2 和 M3,一个 Mixer 收到的数据可能是已经合并过的,它有自己的 CSRC 列表。那么第二个 Mixer 需要将之前的 CSRC 和自己接收的所有 SSRC 合并。就像图中 M3 的输出是 M3:89 (64,45)。

SSRC 的分配和使用

前面已经说过 SSRC 是一个随机的 32-bit 数,它需要在整个 Session 内保证唯一性。所以同一个网络下的参与者在刚加入 Session 时使用不同的 SSRC 至关重要。

我们不能简单的用本地的网络地址,因为可能不唯一。也不能不考虑初始状态而简单地调一个随机数函数。

碰撞的可能性

因为 SSRC 是随机选择的,这就可能多个数据源选用了相同的 SSRC。如果大家是同时加入 Session 的话,这个碰撞的几率就更高。如果 SSRC 的数量是 N,L 是 SSRC 的数据长度(这里是 32),那么碰撞的可能性是 1 - exp(-N2 / 2(L+1)),当 N=1000 时,碰撞率大概是 10**-4。

通常来说,实际的碰撞率会比上述的最坏情况要低。通常一个新节点加入时,其他节点已经有了自己的唯一 SSRC,这时候碰撞的概率只是生成的新 SSRC 在这些现有 SSRC 之中的可能性。这时候碰撞率是 N/2**L。当 N=1000 时,碰撞率大约是 2*10**-7。

因为新加入的节点会先接收一段时间的报文然后才发送自己的第一个报文,所以在它生成 SSRC 时可以避开已知的 SSRC,这也有效的降低了碰撞的几率。

碰撞的解决方案和循环的发现

通常来说 SSRC 碰撞的可能性很小,所有的 RTP 实现必须有发现冲突的机制,并在发现冲突时作出适当的处理。如果数据源发现了任何一个别的数据源和自己使用同一个 SSRC,它必须用原来的 SSRC 发送一个 BYE 报文,然后选用一个新的 SSRC。如果一个数据的接收者发现了多个数据源的 SSRC 碰撞了(通过传输地址或者 CNAME),那么它会只接收其中一个人的报文,丢弃另一个人的所有报文。

因为整个 Session 中的 SSRC 是唯一的,所以它也可以被用来发现环型报文。环形报文会导致数据的重复以及控制信息的重复。

Translator 可能会错误地将报文发送回该报文来的地方。

两个 Translator 错误地同时启动,它们两个都会转发同样的数据。

Mixer 可能会错误地将合并报文发送回这些报文来的地方。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxjzf.html