一,前言
ALR(Application limited region detector)该模块也属于 gcc 的一个子模块, 其大概原理就是 SentRate/EstimatedRate 的百分比与 kAlrStartUsagePercent(60)做比较,当小于该值认为网络受限,需要启动 probe 重新探测带宽,当大于 kAlrEndUsagePercent(70),认为网络恢复则不会进行启动下次 probe 探测。SentRate,EstimatedRate 后面会介绍。其实现代码见 AlrDetector::OnBytesSent
void AlrDetector::OnBytesSent(size_t bytes_sent, int64_t now_ms)
{
rate_.Update(bytes_sent, now_ms);
tb_util::Optional<uint32_t> rate = rate_.Rate(now_ms);
if (!rate)
return;
int percentage = static_cast<int>(*rate) * 100 / estimated_bitrate_bps_;
if (percentage < kAlrStartUsagePercent && !alr_started_time_ms_)
{
alr_started_time_ms_ = tb_util::Optional<int64_t>(now_ms);
}
else if (percentage > kAlrEndUsagePercent && alr_started_time_ms_)
{
alr_started_time_ms_ = tb_util::Optional<int64_t>();
}
}
复制代码
二,AlrDetector 简介
class AlrDetector
{
public:
AlrDetector();
~AlrDetector();
void OnBytesSent(size_t bytes_sent, int64_t now_ms);
// Set current estimated bandwidth.
void SetEstimatedBitrate(int bitrate_bps);
// Returns time in milliseconds when the current application-limited region
// started or empty result if the sender is currently not application-limited.
tb_util::Optional<int64_t> GetApplicationLimitedRegionStartTime() const;
private:
//500ms 的滑动窗口,负责实时统计发送出去的码率
RateStatistics rate_;
//gcc 评估出的带宽
int estimated_bitrate_bps_ = 0;
// 非0 ,启动probe 探测
tb_util::Optional<int64_t> alr_started_time_ms_;
};
复制代码
三,参数介绍
1) SentRate :已发送的数据的码率,当 PacedSender 开始定时发送数据时,数据发出后调用 AlrDetector::OnBytesSent 方法,AlrDetector 通过 RateStatistics 实时统计码率,这其中包括了 padding 包和媒体包。
2) EstimatedRate: gcc 评估出的码率,当 gcc 评估出的带宽发生变化,这个值会被更新流程如下
> CongestionController::MaybeTriggerOnNetworkChanged
> PacedSender::SetEstimatedBitrate
> AlrDetector::SetEstimatedBitrate
复制代码
四,ALR 触发
alr 的触发比较简单看下代码就应该知道了,当 alr_start_time 非 0,就开启一个新的 probe 探测流程
见函数 ProbeController::Process:
void ProbeController::Process() {
rtc::CritScope cs(&critsect_);
int64_t now_ms = clock_->TimeInMilliseconds();
if (now_ms - time_last_probing_initiated_ms_ >
kMaxWaitingTimeForProbingResultMs) {
mid_call_probing_waiting_for_result_ = false;
if (state_ == State::kWaitingForProbingResult) {
LOG(LS_INFO) << "kWaitingForProbingResult: timeout";
state_ = State::kProbingComplete;
min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled;
}
}
if (state_ != State::kProbingComplete || !enable_periodic_alr_probing_)
return;
rtc::Optional<int64_t> alr_start_time =
pacer_->GetApplicationLimitedRegionStartTime();
if (alr_start_time) {
int64_t next_probe_time_ms =
std::max(*alr_start_time, time_last_probing_initiated_ms_) +
kAlrPeriodicProbingIntervalMs;
if (now_ms >= next_probe_time_ms) {
InitiateProbing(now_ms, {estimated_bitrate_bps_ * 2}, true);
}
}
}
复制代码
备注: 以上代码基于 58 版本,最新的代码虽然改动较大,但原理基本雷同。
评论