一,前言
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 版本,最新的代码虽然改动较大,但原理基本雷同。
评论