webrtc-InterArrival

本文介绍了一种计算网络中数据包传输时间延迟的方法,包括发送端时间戳差、接收端接收时间差及传输字节大小差。该方法通过分析数据包的时间戳和接收时间,识别网络设备的包聚合行为,并据此调整计算逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了计算2帧/组数据之间的传输时间延迟(发送端时间戳差,接收端接收时间差),传输字节大小差
可能网络设备会把多个包聚合到一起进行发送的问题

  1. 构造

     // timestamp_group_length_ticks:时间戳间隔少于这个值,表示是一组数据
     // timestamp_to_ms_coeff: 时间戳到ms的转化系数
     // enable_burst_grouping: 是否根据接收时间进行分组,一些网络设备会聚合一坨数据,到达时间片后一起发送出去
     InterArrival(uint32_t timestamp_group_length_ticks,
                    double timestamp_to_ms_coeff,
                    bool enable_burst_grouping);
    
  2. 计算出发送时间差(timestamp_delta),接收时间差(arrival_time_delta_ms),传输字节大小差(packet_size_delta)

    主要使用下面2个成员变量进行计算

    1. 当前的聚合包信息
      TimestampGroup current_timestamp_group_;
    2. 上一次的聚合包信息
      TimestampGroup prev_timestamp_group_;

	//timestamp:当前包时间戳
	//arrival_time_ms:接收时间
	//system_time_ms:当前时间
	//packet_size:数据包大小
	//如果成功计算出结果则返回true
	bool ComputeDeltas(uint32_t timestamp,
	                 int64_t arrival_time_ms,
	                 int64_t system_time_ms,
	                 size_t packet_size,
	                 uint32_t* timestamp_delta,
	                 int64_t* arrival_time_delta_ms,
	                 int* packet_size_delta){
	bool calculated_deltas = false;
	if (current_timestamp_group_.IsFirstPacket()) {
	  //第一个包,更新当前组的开始时间错,和最近的时间错
	  current_timestamp_group_.timestamp = timestamp;
	  current_timestamp_group_.first_timestamp = timestamp;
	} else if (!PacketInOrder(timestamp)) {
      //是否顺序的包,timestamp递增的
	  return false;
	} else if (NewTimestampGroup(arrival_time_ms, timestamp)){
      //一组新的数据    
	  if (prev_timestamp_group_.complete_time_ms >= 0) {
          //发送时间差
		  *timestamp_delta=current_timestamp_group_.timestamp-prev_timestamp_group_.timestamp;
          //接收时间差
		  *arrival_time_delta_ms=current_timestamp_group_.complete_time_ms-prev_timestamp_group_.complete_time_ms;		
          //
		  int64_t system_time_delta_ms =current_timestamp_group_.last_system_time_ms-prev_timestamp_group_.last_system_time_ms;
		  if (*arrival_time_delta_ms - system_time_delta_ms >=kArrivalTimeOffsetThresholdMs) {
			  //数据异常了,重置一下 ,正常情况下system_time_delta_ms和*arrival_time_delta_ms基本一致的			    
		    Reset();
		    return false;
		  }

		  if (*arrival_time_delta_ms < 0) {
			  //异常,
			  //  当前包的到达时间还比上一个包的到达时间早,连续出现多次以后重置
              num_consecutive_reordered_packets_++;
		      return false;
		  } else {
		      num_consecutive_reordered_packets_ = 0;
		  }
		  
		  *packet_size_delta = static_cast<int>(current_timestamp_group_.size) -
		      static_cast<int>(prev_timestamp_group_.size);
		  calculated_deltas = true;
		}
        
        //使用新的group
		prev_timestamp_group_ = current_timestamp_group_;
		current_timestamp_group_.first_timestamp = timestamp;
		current_timestamp_group_.timestamp = timestamp;
		current_timestamp_group_.size = 0;
	} else {
        //更新时间戳到这组数据中的最近时间戳上
		current_timestamp_group_.timestamp = LatestTimestamp(
		    current_timestamp_group_.timestamp, timestamp);
	}

	// 累加当前组数据的大小,最后的到达时间,当前的系统时间
	current_timestamp_group_.size += packet_size;
	current_timestamp_group_.complete_time_ms = arrival_time_ms;
	current_timestamp_group_.last_system_time_ms = system_time_ms;
	
	return calculated_deltas;
}

3.判断是否一个新的group

	bool NewTimestampGroup(int64_t arrival_time_ms, uint32_t timestamp) const {
	  if (current_timestamp_group_.IsFirstPacket()){
	    //第一包数据,肯定不是新的group
	    return false;
	  } else if (BelongsToBurst(arrival_time_ms, timestamp)) {
	    //如果更上一帧数据可能被网络设备聚合过
	    return false;
	  } else {	  
		//时间戳相差比较大的情况下判断为另一组
	    uint32_t timestamp_diff = timestamp -current_timestamp_group_.first_timestamp;
	    return timestamp_diff > kTimestampGroupLengthTicks;
	  }
	}
  1. 是否被网络设备聚合过了

     bool InterArrival::BelongsToBurst(int64_t arrival_time_ms,
                                       uint32_t timestamp) const {
       if (!burst_grouping_) {
         return false;
       }
     
       //
       // 计算跟上一次的到达时间差值(接收时间差) d1
       assert(current_timestamp_group_.complete_time_ms >= 0);
       int64_t arrival_time_delta_ms = arrival_time_ms -
           current_timestamp_group_.complete_time_ms;
     
       //
       //计算跟上一次的时间戳差值(发送时间差)   d2
       uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp;
       int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5;
       if (ts_delta_ms == 0)
         return true;
     
       //
       // 计算一下传输影响的相对差值    d1-d2  理论上如果没有网络影响  d1-d2>=0
       int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms;
     
       //
       //  如果差值< 0 并且接收间隔<kBurstDeltaThresholdMs则可以认定为同一个聚合
       //  可能无线设备,路由器进行了聚合
       return propagation_delta_ms < 0 && arrival_time_delta_ms <= kBurstDeltaThresholdMs;
     }   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值