AimdRateControl 控制码率如何增减,及其数值
-
根据网络状态,过载,欠载状态 更新内部码率控制状态机 增加码率,减少码率,保持码率
-
根据实际接受码率的变化波动情况,计算码率的如何进行增加,减少,及其改变的量
增加码率 : 前提假设码率正常变化符合正态分布,
(1.) 如何变化在3西格玛内,进行加性增加
(2.) 如何变化在3西格玛内,进行乘性增加减少码率 : 基本上就是当前码率的0.85
-
过载状态下,判断是否现在可以降帧率,有一个时间阈值 TimeToReduceFurther
一. 码率样点更新
void AimdRateControl::Update(const RateControlInput* input, int64_t now_ms) {
// 保证有足够时间数据再进行计算
...
//保存一下输入参数,网络状态,实质接收码率
//设置是否可以更新标志
if (updated_ && current_input_.bw_state == kBwOverusing) {
current_input_.noise_var = input->noise_var;
current_input_.incoming_bitrate = input->incoming_bitrate;
} else {
updated_ = true;
current_input_ = *input;
}
}
//进行码率更新动作,这类的主要函数
uint32_t AimdRateControl::ChangeBitrate(uint32_t new_bitrate_bps,
uint32_t incoming_bitrate_bps,
int64_t now_ms) {
//判断是否可以更新的updated_标志
...
//计算最近实际接收码率的标准差,用于码率增加时候计算
const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ * avg_max_bitrate_kbps_);
switch (rate_control_state_) {
case kRcHold:
break;
case kRcIncrease:
//增加码率
if (avg_max_bitrate_kbps_ >= 0 &&
incoming_bitrate_kbps > avg_max_bitrate_kbps_ + 3 * std_max_bit_rate) {
//接收码率突然增加挺多,超过标准差的3倍,设置乘性增加
// (x-u)/sigma < 3
// u=avg_max_bitrate_kbps_
// sigma=std_max_bit_rate
ChangeRegion(kRcMaxUnknown);
avg_max_bitrate_kbps_ = -1.0;
}
if (rate_control_region_ == kRcNearMax) {
//检测到接收码率慢慢的增减了,控制新码率加性增加
uint32_t additive_increase_bps =
AdditiveRateIncrease(now_ms, time_last_bitrate_change_);
new_bitrate_bps += additive_increase_bps;
} else {
//检测到接收码率突然大增情况下,控制新码率指数增加
uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease(
now_ms, time_last_bitrate_change_, new_bitrate_bps);
new_bitrate_bps += multiplicative_increase_bps;
}
time_last_bitrate_change_ = now_ms;
break;
case kRcDecrease:
//接收码率的beta_(0.85),减小码率,根据设置的码率标准使用不同的基准码率
new_bitrate_bps = static_cast<uint32_t>(beta_ * incoming_bitrate_bps + 0.5);
...
break;
default:
assert(false);
}
//返回码率,限制到一定的标准内
return ClampBitrate(new_bitrate_bps, incoming_bitrate_bps);
}
二 。 码率的变化大小计算方式
(1.) 加性增加的
int AimdRateControl::GetNearMaxIncreaseRateBps() const {
//平均一下 30fps情况下,每一帧数据的大小
double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0;
//每一帧数据平均拆包个数
double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0));
//每一个包的bit大小
double avg_packet_size_bits = bits_per_frame / packets_per_frame;
// Approximate the over-use estimator delay to 100 ms.
//一个包在网络上的传输时长,假设网络延迟了100ms
const int64_t response_time = in_experiment_ ? (rtt_ + 100) * 2 : rtt_ + 100;
//增加这一个包大小,码率会增加多少
constexpr double kMinIncreaseRateBps = 4000;
return static_cast<int>(std::max(
kMinIncreaseRateBps, (avg_packet_size_bits * 1000) / response_time));
}
//根据时长计算具体值 (now_ms - last_ms)/1000 转到单位s
uint32_t AimdRateControl::AdditiveRateIncrease(int64_t now_ms,
int64_t last_ms) const {
return static_cast<uint32_t>((now_ms - last_ms) *
GetNearMaxIncreaseRateBps() / 1000);
}
(2.) 乘性增加
//增加因子 1.08 ^ detalT
uint32_t AimdRateControl::MultiplicativeRateIncrease(
int64_t now_ms, int64_t last_ms, uint32_t current_bitrate_bps) const {
double alpha = 1.08;
if (last_ms > -1) {
int time_since_last_update_ms = std::min(static_cast<int>(now_ms - last_ms),
1000);
//指数增长
alpha = pow(alpha, time_since_last_update_ms / 1000.0);
}
uint32_t multiplicative_increase_bps = std::max(
current_bitrate_bps * (alpha - 1.0), 1000.0);
return multiplicative_increase_bps;
}
计算实质接受码率的波动方差 (标准化的)
void AimdRateControl::UpdateMaxBitRateEstimate(float incoming_bitrate_kbps) {
const float alpha = 0.05f;
//平滑的最近一段时间的平均码率
if (avg_max_bitrate_kbps_ == -1.0f) {
avg_max_bitrate_kbps_ = incoming_bitrate_kbps;
} else {
avg_max_bitrate_kbps_ = (1 - alpha) * avg_max_bitrate_kbps_ +
alpha * incoming_bitrate_kbps;
}
// Estimate the max bit rate variance and normalize the variance
// with the average max bit rate.
//平滑方差,并且通过 avg_max_bitrate_kbps_归一化
//就是码率的变化曲线,跟均值的相差度
const float norm = std::max(avg_max_bitrate_kbps_, 1.0f);
var_max_bitrate_kbps_ = (1 - alpha) * var_max_bitrate_kbps_ +
alpha * (avg_max_bitrate_kbps_ - incoming_bitrate_kbps) *
(avg_max_bitrate_kbps_ - incoming_bitrate_kbps) / norm;
//设置一个最小波动值,最大波动值
// 0.4 ~= 14 kbit/s at 500 kbit/s
if (var_max_bitrate_kbps_ < 0.4f) {
var_max_bitrate_kbps_ = 0.4f;
}
// 2.5f ~= 35 kbit/s at 500 kbit/s
if (var_max_bitrate_kbps_ > 2.5f) {
var_max_bitrate_kbps_ = 2.5f;
}
}