WebRTC带宽估计后,得到的结果会存到TargetTransferRate
结构体中,然后回调给上层。TargetTransferRate
定义如下:
1 2 3 4 5 6 7 |
struct TargetTransferRate { Timestamp at_time = Timestamp::PlusInfinity(); // The estimate on which the target rate is based on. NetworkEstimate network_estimate; DataRate target_rate = DataRate::Zero(); DataRate stable_target_rate = DataRate::Zero(); }; |
可以看到该结构体有两个估计码率值,本文我们介绍下其中的stable_target_rate
,该值在后续的码率分配中有用到,配合target_rate
进行相关判断。
在GoogCcNetworkController
中,TargetTransferRate
结果值按如下得到:
1 2 3 4 5 |
TargetTransferRate target_rate_msg; target_rate_msg.target_rate = pushback_target_rate; target_rate_msg.stable_target_rate = std::min(bandwidth_estimation_->GetEstimatedLinkCapacity(), pushback_target_rate); |
其中pushback_target_rate
为我们实际的带宽估计值,stable_target_rate
取带宽估计值与EstimatedLinkCapacity
小的一个。
SendSideBandwidthEstimation
如下代码可知,LinkCapacity
通过LinkCapacityTracker(link_capacity_)
计算得到,接下来我们看看这个LinkCapacityTracker
究竟是什么东东。
1 2 3 |
DataRate SendSideBandwidthEstimation::GetEstimatedLinkCapacity() const { return link_capacity_.estimate(); } |
LinkCapacityTracker
LinkCapacityTracker
类比较简单,接口不多,这里我们介绍下主要的两个接口,通过这两个接口进行LinkCapacity
的更新。
UpdateDelayBasedEstimate
主要两个输入参数如下:
- at_time: 当前时间
- delay_based_bitrate:当前基于时延的带宽估计值
这里我们分析下该函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 |
// 得到一个新的基于时延的带宽估计值:delay_based_bitrate后触发 void LinkCapacityTracker::UpdateDelayBasedEstimate( Timestamp at_time, DataRate delay_based_bitrate) { if (delay_based_bitrate < last_delay_based_estimate_) { // 若比之前估计值小,取capacity_estimate_bps_与当前基于时延估计值小的一个 capacity_estimate_bps_ = std::min(capacity_estimate_bps_, delay_based_bitrate.bps<double>()); last_link_capacity_update_ = at_time; } last_delay_based_estimate_ = delay_based_bitrate; } |
OnRateUpdate
主要有如下三个输入参数:
- acknowledged:根据接收端反馈的信息计算的接收码率(通过Transport-CC报文,该报文详细分析可去我博客搜索下)
- target:当前综合时延以及丢包信息得到的带宽估计值
- at_time:当前时间
该函数具体分析如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 得到一个新的综合时延以及丢包的带宽估计值target后触发 void LinkCapacityTracker::OnRateUpdate(absl::optional<DataRate> acknowledged, DataRate target, Timestamp at_time) { if (!acknowledged) return; // 取带宽估计值以及实际接收码率小的,追求保守 DataRate acknowledged_target = std::min(*acknowledged, target); if (acknowledged_target.bps() > capacity_estimate_bps_) { TimeDelta delta = at_time - last_link_capacity_update_; double alpha = delta.IsFinite() ? exp(-(delta / tracking_rate.Get())) : 0; // 使用滑动平均进行数据平滑处理 capacity_estimate_bps_ = alpha * capacity_estimate_bps_ + (1 - alpha) * acknowledged_target.bps<double>(); } last_link_capacity_update_ = at_time; } |
通过前面两个函数,得到的capacity_estimate_bps_
即为我们前面说的稳定估计值stable_target_rate
。由前面分析可知,该stable_target_rate
综合了当前带宽估计值以及实际接收码率,从计算过程可知比较保守。从实际测试效果看,该估计值也正如其名,相对实际带宽估计值target_rate
会更平稳,值也会相对小些。
文章评论
OnRateUpdate中的target:当前综合时延以及丢包信息得到的带宽估计值,应该只是当前丢包信息得到的带宽估计值,不包括时延的
@xman 这是调用代码,其中GetUpperLimit()用到了基于时延的带宽估计,也就是delay_based_limit_
<code>void SendSideBandwidthEstimation::UpdateTargetBitrate(DataRate new_bitrate,
Timestamp at_time) {
new_bitrate = std::min(new_bitrate, GetUpperLimit());
if (new_bitrate < min_bitrate_configured_) {
MaybeLogLowBitrateWarning(new_bitrate, at_time);
new_bitrate = min_bitrate_configured_;
}
current_target_ = new_bitrate;
MaybeLogLossBasedEvent(at_time);
link_capacity_.OnRateUpdate(acknowledged_rate_, current_target_, at_time);
}</code>