在WebRTC GCC(Google Congestion Control)中,有一个叫做AlrDetector(应用受限区域探测器,Application limited region detector)的模块。该模块利用某段时间值,以及这段时间发送的字节数判断当前输出网络流量是否受限。这些限制主要跟应用程序本身输出网络流量的能力有关,例如编码器性能,不能编码出设置的目标码率。下面举个简单例子说明下。
假设我们经过带宽预测后,获取到一个目标码流target_bitrate_bps
,此时我们程序需要按照该码率大小进行数据发送,但是一切都不是那么完美,例如编码器。编码器由于各种问题,编码出的数据码率低于target_bitrate_bps
,使得数据发送码率低于要求,带宽利用率不足,发送码率占最大预算码率值比例低于某个值的话Alr(Application limited region)就会被触发了,恢复到某个值以上,Alr会停止。
下面说下AlrDetector的工作流程。
1)首先是在构造函数初始化相关参数配置,相关参数如下:
1 2 3 4 5 6 7 |
struct AlrDetectorConfig { // until BW adjustments of application limited region is fine tuned. double bandwidth_usage_ratio = 0.65; double start_budget_level_ratio = 0.80; double stop_budget_level_ratio = 0.50; std::unique_ptr<StructParametersParser> Parser(); }; |
IntervalBudget::can_build_up_underuse_
初始化为true
。IntervalBudget
根据输入的评估码率,计算当前还能发送多少数据。
2)设置带宽预测得到的码率:
1 2 3 |
void AlrDetector::SetEstimatedBitrate() ↓ void IntervalBudget::set_target_rate_kbps() |
3)发送数据时调用:
1 2 3 4 5 |
void AlrDetector::OnBytesSent() ↓ void IntervalBudget::UseBudget() ↓ void IntervalBudget::IncreaseBudget() |
通过IntervalBudget::budget_ratio
与start_budget_level_ratio
以及stop_budget_level_ratio
对比,设置AlrDetector的状态。
1 2 3 4 5 6 7 8 9 10 |
bool state_changed = false; if (alr_budget_.budget_ratio() > conf_.start_budget_level_ratio && !alr_started_time_ms_) { alr_started_time_ms_.emplace(rtc::TimeMillis()); state_changed = true; } else if (alr_budget_.budget_ratio() < conf_.stop_budget_level_ratio && alr_started_time_ms_) { state_changed = true; alr_started_time_ms_.reset(); } |
IntervalBudget::budget_ratio
表示剩余要发送的数据占最大预算发送数据max_bytes_in_budget_
的比例,定义如下:
1 2 3 4 5 |
double IntervalBudget::budget_ratio() const { if (max_bytes_in_budget_ == 0) return 0.0; return static_cast<double>(bytes_remaining_) / max_bytes_in_budget_; } |
max_bytes_in_budget_
按500ms时间窗口计算得到:
1 2 |
constexpr int64_t kWindowMs = 500; max_bytes_in_budget_ = (kWindowMs * target_rate_kbps_) / 8; |
可知如果IntervalBudget::budget_ratio
大于start_budget_level_ratio
,即剩余数据还有很多,发送码率低了,带宽没充分利用,Alr触发了,小于stop_budget_level_ratio
时,alr_started_time_ms_
重置,Alr停止。
4)通过获取AlrDetector::alr_started_time_ms_
判断当前Alr是否触发,调用函数如下:
1 |
absl::optional<int64_t> AlrDetector::GetApplicationLimitedRegionStartTime() |
文章评论
楼主,请问这个AlrDetector触发了有什么行为呢?
@whale 作为一种信号,调整码率时用到。带宽估计调整码率时,如果得到Increase的码率状态,此时本来需要向上调整码率的,但是此时处于alr状态,就跳过此次调整了。
应用层编码器数据码率 ---> gcc传输层速率 --->按组发包 。如果没有这个AlrDetector,其实也只是让gcc发送更频繁,每组包更多,发送不平滑、更具“突发性”,由于此时gcc测得的物理带宽可以满足这种“突发”速率,因此,不会造成网络拥塞。
所以,楼主,这个AlrDector似乎存在意义不大?
@whale 不知道你怎么得出
让gcc发送更频繁
这个结论@Jeff @whale 你应该是觉得alr不启用的话,gcc就可以肆意妄为?我读下来觉得alr的存在作用只是在发送码率(应用性能不足)远低于目标码率,没充分利用实际带宽时,起到减少网络调整运算。不知理解是否有出入
有个疑问alr触发时,那本次调整码率无效,还是按之前的值进行发送,如果下一次带宽反馈没来的话,等alr恢复时,这个调整码率是之前还是上次反馈的?
@5555 之前值