AcknowledgedBitrateEstimator是当前接收方吞吐量。与当前估计码率相差甚远的样本,或基于少数数据包的样本被赋予较小的权重,因为它们被认为更有可能是与拥塞无关的延迟峰值造成的。
模块主要是在时间窗内估计接收方码率estmate_bitrate,不在时间窗内的,沿用前一个估计值estmate_bitrate,初始时间窗为500ms,后续时间窗为150ms。模块还会通过贝叶斯估计算法对前一个估计值和当前样本的观测值重新计算估计最新值。
代码解读
void AcknowledgedBitrateEstimator::IncomingPacketFeedbackVector(//处理RTPFB反馈包中接收到的包
const std::vector<PacketResult>& packet_feedback_vector) {//packet_feedback_vector为接收方接收到的包信息队列
for (const auto& packet : packet_feedback_vector) {
if (alr_ended_time_ && packet.sent_packet.send_time > *alr_ended_time_) {//当alr处于不激活状态
bitrate_estimator_->ExpectFastRateChange();//通过将码率估计方差增加一个较高的值,原始方差=50,增加一个200的方差值,允许码率在接
//下来的几个样本中快速变化。
alr_ended_time_.reset();
}
DataSize acknowledged_estimate = packet.sent_packet.size;
acknowledged_estimate += packet.sent_packet.prior_unacked_data;//acknowledged_estimate 统计净荷
bitrate_estimator_->Update(packet.receive_time, acknowledged_estimate,//根据输入样本的接收时间和净荷估计码率值
in_alr_);
}
}
根据输入样本的接收时间和净荷估计码率值
void BitrateEstimator::Update(Timestamp at_time, DataSize amount, bool in_alr) {
int rate_window_ms = noninitial_window_ms_;//统计窗口noninitial_window_ms_=150ms
// 在开始时使用一个更大的窗口initial_window_ms_=500ms来获得一个更稳定的样本,我们可以用它来初始化估计值。
if (bitrate_estimate_kbps_ < 0.f)//初始时bitrate_estimate_kbps_=-1
rate_window_ms = initial_window_ms_;
float bitrate_sample_kbps =
UpdateWindow(at_time.ms(), amount.bytes(), rate_window_ms);//计算时间窗口内的码率=字节总数/时间窗
if (bitrate_sample_kbps < 0.0f)//没有达到窗口条件时,样本bitrate_sample_kbps=-1;
return;
if (bitrate_estimate_kbps_ < 0.0f) {
// 初始化码率估计值
bitrate_estimate_kbps_ = bitrate_sample_kbps;
return;
}
//将样本不确定性sample_uncertainty 定义为距离当前估价值有多远的函数。在uncertainty_symmetry_cap_ 较低的情况下,我们增加的不确定度要大于减少的不确定度。对于较高的值,我们接近对称。
float scale = uncertainty_scale_;//初始化uncertainty_scale_=10
if (in_alr && bitrate_sample_kbps < bitrate_estimate_kbps_) {
// Optionally use higher uncertainty for samples obtained during ALR.
scale = uncertainty_scale_in_alr_;
}
float sample_uncertainty =
scale * std::abs(bitrate_estimate_kbps_ - bitrate_sample_kbps) /
(bitrate_estimate_kbps_ +
std::min(bitrate_sample_kbps,
uncertainty_symmetry_cap_.Get().kbps<float>()));
float sample_var = sample_uncertainty * sample_uncertainty;
// 更新码率的贝叶斯估计,如果样本不确定性较大,则降低其权重。
//码率估计的不确定性随着比码率随时间变化的模型的每次更新而增加。
float pred_bitrate_estimate_var = bitrate_estimate_var_ + 5.f;
bitrate_estimate_kbps_ = (sample_var * bitrate_estimate_kbps_ +
pred_bitrate_estimate_var * bitrate_sample_kbps) /
(sample_var + pred_bitrate_estimate_var);
bitrate_estimate_kbps_ =
std::max(bitrate_estimate_kbps_, estimate_floor_.Get().kbps<float>());
bitrate_estimate_var_ = sample_var * pred_bitrate_estimate_var /
(sample_var + pred_bitrate_estimate_var);
MS_DEBUG_DEV(
"acknowledged_bitrate %" PRIu64", %f",
at_time.ms(), bitrate_estimate_kbps_ * 1000);
}
计算时间窗内的码率
float BitrateEstimator::UpdateWindow(int64_t now_ms,
int bytes,
int rate_window_ms) {
// Reset if time moves backwards.
if (now_ms < prev_time_ms_) {
prev_time_ms_ = -1;
sum_ = 0;
current_window_ms_ = 0;
}
if (prev_time_ms_ >= 0) {
current_window_ms_ += now_ms - prev_time_ms_;//统计时间间隔
// 如果前后两个包的接收时间超过时间窗,则清零字节统计
if (now_ms - prev_time_ms_ > rate_window_ms) {
sum_ = 0;
current_window_ms_ %= rate_window_ms;
}
}
prev_time_ms_ = now_ms;
float bitrate_sample = -1.0f;
if (current_window_ms_ >= rate_window_ms) {//超过时间窗时计算码率
bitrate_sample = 8.0f * sum_ / static_cast<float>(rate_window_ms);//8表示一个字节8个bit
current_window_ms_ -= rate_window_ms;
sum_ = 0;
}
sum_ += bytes;//统计时间窗内,接收到的总字节。
return bitrate_sample;
}
输出的码率值作为输入,用于在基于延时的码率估计中评估目标码率。
更多推荐
WebRtc码率控制模块之AcknowledgedBitrateEstimator
发布评论