WebRtc 中RateStatistics类

RateStatistics类位于rtc_base 目录下面,属于WebRtc 基础类之一。这个类主要功能是统计一段时间内的带宽的情况。由于很多地方用到这个带宽统计的功能,所以有很多地方调用到了RateStatistics。

RateStatistics 主要提供了四个公有函数:


  void Reset();

  void Update(size_t count, int64_t now_ms);

  absl::optional Rate(int64_t now_ms)const;

  bool SetWindowSize(int64_t window_size_ms, int64_t now_ms);


void RateStatistics::Reset() {

  accumulated_count_ = 0;

  num_samples_ = 0;

  oldest_time_ = - max_window_size_ms_;

  oldest_index_ = 0;

  current_window_size_ms_ = max_window_size_ms_;

  for(int64_t i =0; i < max_window_size_ms_; i++)

    buckets_[i] = Bucket();

}

Reset函数就是各种参数重置了


voidRateStatistics::Update(size_t count, int64_t now_ms) {

  if(now_ms < oldest_time_) {

    return;

  }

  EraseOld(now_ms);

  // First ever sample, reset window to start now.

  if (!IsInitialized())

    oldest_time_= now_ms;

  uint32_t now_offset =static_cast(now_ms -oldest_time_);

  RTC_DCHECK_LT(now_offset, max_window_size_ms_);

  uint32_t index =oldest_index_+ now_offset;

  if (index >= max_window_size_ms_)

    index -=max_window_size_ms_;

  buckets_[index].sum += count;

  ++buckets_[index].samples;

  accumulated_count_ += count;

  ++num_samples_;

}

Update函数实际上在进行添加的操作。在添加之前先删除旧的数据,删除旧的数据EraseOld,实际上是按照一定的规则删除的,如果没有达到条件是不会删除任何数据。
用当前的值,减去最早的记录值得到一个偏移量,偏移量加上最早的序号,得到的值就是桶(buckets)的索引序号。oldest_time_ 和oldest_index_在这个函数中只是使用,这两个值都是在删除旧数据和重置的时候进行修改(第一次插入数据除外)。


absl::optional<uint32_t> RateStatistics::Rate(int64_t now_ms) const {


  const_cast(this)->EraseOld(now_ms);

  int64_t active_window_size = now_ms -oldest_time_+1;

  if(num_samples_==0|| active_window_size <=1||

      (num_samples_<=1&& active_window_size< current_window_size_ms_)) {

    return absl::nullopt;

  }

  float scale =scale_/ active_window_size;

  return static_cast(accumulated_count_* scale +0.5f);

}

这个函数就是获取带宽值了。这里有一个空值的返回,当桶里面只有一个数据的时候,或者没有达到最大的窗口大小直接返回一个空值。其他情况才是对根据当前的时间,获取一段时间内(max_window_size_ms_)带宽值。


void RateStatistics::EraseOld(int64_t  now_ms) {

  if (!IsInitialized())

    return;

  // New oldest time that is included in data set.

  int64_t new_oldest_time = now_ms - current_window_size_ms_+1;

  // New oldest time is older than the current one, no need to cull data.

  if(new_oldest_time <=oldest_time_)

    return;

  // Loop over buckets and remove too old data points.

  while(num_samples_>0&&oldest_time_< new_oldest_time) {

    const Bucket& oldest_bucket = buckets_[oldest_index_];

    RTC_DCHECK_GE(accumulated_count_, oldest_bucket.sum);

    RTC_DCHECK_GE(num_samples_, oldest_bucket.samples);

    accumulated_count_-= oldest_bucket.sum;

    num_samples_-= oldest_bucket.samples;

    buckets_[oldest_index_] = Bucket();

    if (++oldest_index_ >= max_window_size_ms_)

      oldest_index_ = 0;

    ++oldest_time_;

  }

  oldest_time_= new_oldest_time;

}

删除旧数据的函数。最早的数据oldest_time_小于 now_ms - current_window_size_ms_+1的时候才会触发,这时候一般情况下num_samples_会大于0。然后循环删除最久的数据。


bool RateStatistics::SetWindowSize(int64_t window_size_ms, int64_t now_ms) {

  if(window_size_ms <=0 || window_size_ms >max_window_size_ms_)

    return false;

  current_window_size_ms_ = window_size_ms;

  EraseOld(now_ms);

  return true;

}

设置窗口大小的函数


bool RateStatistics::IsInitialized() const {

  return oldest_time_ != -max_window_size_ms_;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。