webrtc弱网-InterArrivalDelta类源码分析与算法原理
一、核心功能
InterArrivalDelta
是 WebRTC 中用于计算两个发送 burst(突发包组)之间的时间差和大小差的工具类。主要用于拥塞控制算法(如 Google Congestion Control, GCC)中,通过分析包组的发送时间差、到达时间差和包大小差,来估计网络延迟和带宽变化。
二、核心算法原理
该算法将连续到达的包按照发送时间分组(send_time_group
),每个组包含一定时间窗口内发送的包。当检测到新的组时,计算当前组与上一组之间的:
发送时间差(
send_time_delta
)到达时间差(
arrival_time_delta
)包大小差(
packet_size_delta
)
算法还具备以下能力:
识别并处理重排序包(reordered packets)
检测时钟偏移(clock offset)
识别突发传输(bursty traffic)并将其视为同一组
三、关键数据结构
1. SendTimeGroup
struct SendTimeGroup {size_t size; // 该组总包大小Timestamp first_send_time; // 组内第一个包的发送时间Timestamp send_time; // 组内最后一个包的发送时间(最大)Timestamp first_arrival; // 组内第一个包的到达时间Timestamp complete_time; // 组内最后一个包的到达时间Timestamp last_system_time; // 最后一个包的系统时间(用于时钟偏移检测) };
2. 类成员变量
TimeDelta send_time_group_length_; // 分组时间窗口长度 SendTimeGroup current_timestamp_group_; // 当前正在构建的组 SendTimeGroup prev_timestamp_group_; // 上一个完整的组 int num_consecutive_reordered_packets_; // 连续重排序包计数
四、核心方法详解
1. ComputeDeltas
bool ComputeDeltas(Timestamp send_time,Timestamp arrival_time,Timestamp system_time,size_t packet_size,TimeDelta* send_time_delta,TimeDelta* arrival_time_delta,int* packet_size_delta);
功能:处理每个包的到达事件,必要时计算并返回两个组之间的差值。
流程:
如果是第一个包,初始化当前组;
如果是重排序包,直接返回
false
;如果检测到新组,计算与上一组的差值;
检查时钟偏移和重排序情况,必要时重置;
更新当前组信息。
2. NewTimestampGroup
bool NewTimestampGroup(Timestamp arrival_time, Timestamp send_time) const;
功能:判断当前包是否属于新的发送组。
判断条件:
不属于当前组;
不属于突发传输(
BelongsToBurst
返回false
);发送时间与当前组第一个包的发送时间差超过
send_time_group_length_
。
3. BelongsToBurst
bool BelongsToBurst(Timestamp arrival_time, Timestamp send_time) const;
功能:判断当前包是否属于当前组的突发传输。
判断条件:
到达时间差小于
kBurstDeltaThreshold
(5ms);从第一个包到达至今小于
kMaxBurstDuration
(100ms);传播延迟为负(说明包比预期到达得早)。
4. Reset
void Reset();
功能:重置所有状态,用于处理异常情况(如时钟跳变、连续重排序)。
五、设计亮点
抗时钟偏移:通过比较系统时间差和到达时间差检测时钟跳变,并自动重置。
抗重排序:统计连续重排序包数量,超过阈值则重置。
突发识别:将短时间内密集到达的包视为同一组,避免过度分组。
模块化设计:与具体拥塞控制算法解耦,可复用于多种场景。
六、典型工作流程
初始化:设置
send_time_group_length_
(通常为 5ms);处理每个包:调用
ComputeDeltas
,传入发送时间、到达时间、系统时间、包大小;判断是否为新组:若是,计算与前一个组的差值;
输出差值:用于后续带宽估计;
异常处理:若检测到时钟偏移或连续重排序,重置状态;
持续更新:重复上述过程,持续监控网络状态。
注释精要
// 判断是否属于突发传输 bool InterArrivalDelta::BelongsToBurst(Timestamp arrival_time,Timestamp send_time) const {RTC_DCHECK(current_timestamp_group_.complete_time.IsFinite());TimeDelta arrival_time_delta =arrival_time - current_timestamp_group_.complete_time;TimeDelta send_time_delta = send_time - current_timestamp_group_.send_time;if (send_time_delta.IsZero())return true; // 发送时间相同,属于同一突发TimeDelta propagation_delta = arrival_time_delta - send_time_delta;// 若传播延迟为负,且到达时间差很小,且总突发时间在阈值内,则认为属于同一突发if (propagation_delta < TimeDelta::Zero() &&arrival_time_delta <= kBurstDeltaThreshold &&arrival_time - current_timestamp_group_.first_arrival < kMaxBurstDuration)return true;return false; }
InterArrivalDelta是WebRTC中用于分析网络包传输时序的核心工具类,主要功能是计算连续数据包组(burst)之间的发送时间差、到达时间差和包大小差。它通过智能分组机制处理包重排序、时钟偏移和突发流量,为拥塞控制算法提供关键的网络状态指标(如延迟变化和带宽波动),从而支撑动态调整发送速率,保障实时音视频传输的流畅性和稳定性。该模块是Google Congestion Control(GCC)算法的基础组件之一。