RateStatistics
用于webrtc的码率统计,
用法说明
- RateStatistics::RateStatistics(int64_t window_size_ms, float scale);
window_size_ms 统计窗口的大小,scale 缩放参数用于单位转换,比如byte转bit就是8000;
-
void RateStatistics::Update(size_t count, int64_t now_ms);每次数据来时进行更新,count是收到数据的大小,now_ms当前时刻;
-
rtc::Optional<uint32_t> RateStatistics::Rate(int64_t now_ms) const获取当前时间的码率;
算法说明
RateStatistics::RateStatistics(int64_t window_size_ms, float scale)
: buckets_(new Bucket[window_size_ms]()),
accumulated_count_(0),
num_samples_(0),
oldest_time_(-window_size_ms),
oldest_index_(0),
scale_(scale),
max_window_size_ms_(window_size_ms),
current_window_size_ms_(max_window_size_ms_) {}
window_size_ms初始化buckets_,如果是1秒就是1000ms,就是1000个bucket。
void RateStatistics::Update(size_t count, int64_t now_ms) {
if (now_ms < oldest_time_) {
// Too old data is ignored.
return;
}
//删除超出窗口老的数据
EraseOld(now_ms);
// First ever sample, reset window to start now.
if (!IsInitialized())
oldest_time_ = now_ms;
//更新数据
//根据当前时刻now_ms,计算相对window_size_ms_的偏移量,根据偏移量计算出index
uint32_t now_offset = static_cast<uint32_t>(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_;
}
收到数据时进行更新
rtc::Optional<uint32_t> RateStatistics::Rate(int64_t now_ms) const {
// Yeah, this const_cast ain't pretty, but the alternative is to declare most
// of the members as mutable...
const_cast<RateStatistics*>(this)->EraseOld(now_ms);
// If window is a single bucket or there is only one sample in a data set that
// has not grown to the full window size, treat this as rate unavailable.
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 rtc::Optional<uint32_t>();
}
float scale = scale_ / active_window_size;
return rtc::Optional<uint32_t>(
static_cast<uint32_t>(accumulated_count_ * scale + 0.5f));
}
获取码率: rate = scale*accumulated_count_/active_window_size