首页 > WebRTC > WebRTC研究:RTP中的序列号以及时间戳比较
2019
07-06

WebRTC研究:RTP中的序列号以及时间戳比较

在使用RTP协议时,如果需要网络对抗,保障QoS(Quality of Service,服务质量),我们需要通过序列号以及时间戳的比较,以进行丢包、乱序等处理。但是有个问题,比如一个RTP包,序列号为number1:5000,另一个RTP包序列号为number2:60000,可以说60000一定比5000大,是个更新的RTP包吗?
WebRTC研究:RTP中的序列号以及时间戳比较 - 第1张  | 剑痴乎

当然不是了,首先我们先重温下RTP数据包的结构。

RFC3550中RTP头部结构按如下定义:

可以看到,RTP序列号sequence number用两字节表示,时间戳timestamp用四字节表示。所以序列号以及时间戳就存在一个取值范围。由于是无符号数,所以序列号范围为:[0,2^16-1],时间戳范围为:[0,2^32-1]。当达到最大值时,将发生所谓的回绕。例如,序列号到了2^16-1,下个包序列号就将是0。所以我们不能直接根据数学意义上的大小进行序列号以及时间戳的比较。

在WebRTC中定义了一个大小比较算法,包含数字回绕处理,判断是否是更新的数字。下面说下算法原理:
1)假设有两个U类型的无符号整数:value, prev_value
2)定义一个常量kBreakpoint,为U类型取值范围的一半;
3)value > prev_value,满足value - prev_value = kBreakpoint时,value大于prev_value
4)valueprev_value不相等,满足(U)(valude - prev_value) < kBreakpoint时,value大于prev_value

总结起来就是valueprev_value不相等且之间的距离小于等于取值范围的一半,就可以说明value大于prev_value
在src\modules\include\module_common_types_public.h,相应代码如下:

顺便也说下如上函数的一个应用。在WebRTC丢包重传判断中(jitter_buffer模块),需要保存上一次收到的最新RTP序列号latest_received_sequence_number_,以便用于丢包判断,这个RTP包必须是新的数据,不能是重传的旧数据。所以每来一个RTP包时,可以将该RTP包序列号传入如上函数,与之前收到的最新RTP序列号进行对比,从而判断当前RTP包是不是最新的。相应代码如下:

最后编辑:
作者:Jeff
Avatar
管理员——代码为剑,如痴如醉

留下一个回复

你的email不会被公开。

This site uses Akismet to reduce spam. Learn how your comment data is processed.