19f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org/* 29f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 39f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org * 49f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org * Use of this source code is governed by a BSD-style license 59f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org * that can be found in the LICENSE file in the root of the source 69f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org * tree. An additional intellectual property rights grant can be found 79f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org * in the file PATENTS. All contributing project authors may 89f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org * be found in the AUTHORS file in the root of the source tree. 99f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org */ 109f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 119f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h" 129f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 139f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org#include <algorithm> 149f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org#include <cassert> 159f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org#include <cmath> 169f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1711324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer#include "webrtc/base/checks.h" 184fbd145dcefd23169a9b1612d5ca92dace8196d6stefan 19c62642c7a662a2a88293b82192e2240049f0cbb9stefan#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h" 204fbd145dcefd23169a9b1612d5ca92dace8196d6stefan#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" 219f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" 229f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 239f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgnamespace webrtc { 249f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 2516825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.orgstatic const int64_t kDefaultRttMs = 200; 269f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgstatic const int64_t kLogIntervalMs = 1000; 279f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgstatic const double kWithinIncomingBitrateHysteresis = 1.05; 28468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språngstatic const int64_t kMaxFeedbackIntervalMs = 1000; 299f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 304fbd145dcefd23169a9b1612d5ca92dace8196d6stefanAimdRateControl::AimdRateControl() 314fbd145dcefd23169a9b1612d5ca92dace8196d6stefan : min_configured_bitrate_bps_( 324fbd145dcefd23169a9b1612d5ca92dace8196d6stefan RemoteBitrateEstimator::kDefaultMinBitrateBps), 339f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org max_configured_bitrate_bps_(30000000), 349f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps_(max_configured_bitrate_bps_), 359f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org avg_max_bitrate_kbps_(-1.0f), 369f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org var_max_bitrate_kbps_(0.4f), 379f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org rate_control_state_(kRcHold), 389f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org rate_control_region_(kRcMaxUnknown), 399f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_last_bitrate_change_(-1), 409f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_input_(kBwNormal, 0, 1.0), 419f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org updated_(false), 429f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_first_incoming_estimate_(-1), 439f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org bitrate_is_initialized_(false), 44c62642c7a662a2a88293b82192e2240049f0cbb9stefan beta_(0.85f), 459f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org rtt_(kDefaultRttMs), 46c62642c7a662a2a88293b82192e2240049f0cbb9stefan time_of_last_log_(-1), 474fbd145dcefd23169a9b1612d5ca92dace8196d6stefan in_experiment_(AdaptiveThresholdExperimentIsEnabled()) {} 489f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 494fbd145dcefd23169a9b1612d5ca92dace8196d6stefanvoid AimdRateControl::SetMinBitrate(int min_bitrate_bps) { 504fbd145dcefd23169a9b1612d5ca92dace8196d6stefan min_configured_bitrate_bps_ = min_bitrate_bps; 514fbd145dcefd23169a9b1612d5ca92dace8196d6stefan current_bitrate_bps_ = std::max<int>(min_bitrate_bps, current_bitrate_bps_); 529f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 539f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 549f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgbool AimdRateControl::ValidEstimate() const { 559f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return bitrate_is_initialized_; 569f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 579f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 580b1534c52eab79372557a6d81aaf4dd9407f55d3pkasting@chromium.orgint64_t AimdRateControl::GetFeedbackInterval() const { 599f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Estimate how often we can send RTCP if we allocate up to 5% of bandwidth 609f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // to feedback. 610b1534c52eab79372557a6d81aaf4dd9407f55d3pkasting@chromium.org static const int kRtcpSize = 80; 620b1534c52eab79372557a6d81aaf4dd9407f55d3pkasting@chromium.org int64_t interval = static_cast<int64_t>( 630b1534c52eab79372557a6d81aaf4dd9407f55d3pkasting@chromium.org kRtcpSize * 8.0 * 1000.0 / (0.05 * current_bitrate_bps_) + 0.5); 640b1534c52eab79372557a6d81aaf4dd9407f55d3pkasting@chromium.org const int64_t kMinFeedbackIntervalMs = 200; 650b1534c52eab79372557a6d81aaf4dd9407f55d3pkasting@chromium.org return std::min(std::max(interval, kMinFeedbackIntervalMs), 660b1534c52eab79372557a6d81aaf4dd9407f55d3pkasting@chromium.org kMaxFeedbackIntervalMs); 679f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 689f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 699f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgbool AimdRateControl::TimeToReduceFurther(int64_t time_now, 709f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org uint32_t incoming_bitrate_bps) const { 7116825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org const int64_t bitrate_reduction_interval = 7216825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org std::max<int64_t>(std::min<int64_t>(rtt_, 200), 10); 739f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (time_now - time_last_bitrate_change_ >= bitrate_reduction_interval) { 749f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return true; 759f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 769f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (ValidEstimate()) { 779f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org const int threshold = static_cast<int>(kWithinIncomingBitrateHysteresis * 789f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org incoming_bitrate_bps); 799f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org const int bitrate_difference = LatestEstimate() - incoming_bitrate_bps; 809f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return bitrate_difference > threshold; 819f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 829f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return false; 839f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 849f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 859f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orguint32_t AimdRateControl::LatestEstimate() const { 869f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return current_bitrate_bps_; 879f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 889f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 899f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orguint32_t AimdRateControl::UpdateBandwidthEstimate(int64_t now_ms) { 909f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps_ = ChangeBitrate(current_bitrate_bps_, 918f09f170e650e14c4cd57c51be32a46e8cd1843bterelius current_input_.incoming_bitrate, now_ms); 929f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (now_ms - time_of_last_log_ > kLogIntervalMs) { 939f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_of_last_log_ = now_ms; 949f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 959f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return current_bitrate_bps_; 969f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 979f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 9816825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.orgvoid AimdRateControl::SetRtt(int64_t rtt) { 999f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org rtt_ = rtt; 1009f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 1019f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 102c62642c7a662a2a88293b82192e2240049f0cbb9stefanvoid AimdRateControl::Update(const RateControlInput* input, int64_t now_ms) { 1039f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org assert(input); 1049f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1059f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Set the initial bit rate value to what we're receiving the first half 1069f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // second. 1079f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (!bitrate_is_initialized_) { 10811324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer const int64_t kInitializationTimeMs = 5000; 10991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LE(kBitrateWindowMs, kInitializationTimeMs); 1109f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (time_first_incoming_estimate_ < 0) { 1118f09f170e650e14c4cd57c51be32a46e8cd1843bterelius if (input->incoming_bitrate > 0) { 1129f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_first_incoming_estimate_ = now_ms; 1139f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 11411324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer } else if (now_ms - time_first_incoming_estimate_ > kInitializationTimeMs && 1158f09f170e650e14c4cd57c51be32a46e8cd1843bterelius input->incoming_bitrate > 0) { 1168f09f170e650e14c4cd57c51be32a46e8cd1843bterelius current_bitrate_bps_ = input->incoming_bitrate; 1179f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org bitrate_is_initialized_ = true; 1189f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 1199f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 1209f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1218f09f170e650e14c4cd57c51be32a46e8cd1843bterelius if (updated_ && current_input_.bw_state == kBwOverusing) { 1229f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Only update delay factor and incoming bit rate. We always want to react 1239f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // on an over-use. 1248f09f170e650e14c4cd57c51be32a46e8cd1843bterelius current_input_.noise_var = input->noise_var; 1258f09f170e650e14c4cd57c51be32a46e8cd1843bterelius current_input_.incoming_bitrate = input->incoming_bitrate; 1269f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } else { 1279f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org updated_ = true; 1289f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_input_ = *input; 1299f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 1309f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 1319f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1329f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgvoid AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) { 1339f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org updated_ = true; 1349f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org bitrate_is_initialized_ = true; 1359f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps_ = ChangeBitrate(bitrate_bps, bitrate_bps, now_ms); 1369f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 1379f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1389f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orguint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps, 1399f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org uint32_t incoming_bitrate_bps, 1409f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org int64_t now_ms) { 1419f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (!updated_) { 1429f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return current_bitrate_bps_; 1439f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 14411324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer // An over-use should always trigger us to reduce the bitrate, even though 14511324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer // we have not yet established our first estimate. By acting on the over-use, 14611324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer // we will end up with a valid estimate. 1478f09f170e650e14c4cd57c51be32a46e8cd1843bterelius if (!bitrate_is_initialized_ && current_input_.bw_state != kBwOverusing) 14811324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer return current_bitrate_bps_; 1499f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org updated_ = false; 1509f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org ChangeState(current_input_, now_ms); 1519f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Calculated here because it's used in multiple places. 1529f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org const float incoming_bitrate_kbps = incoming_bitrate_bps / 1000.0f; 1539f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Calculate the max bit rate std dev given the normalized 1549f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // variance and the current incoming bit rate. 1559f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ * 1569f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org avg_max_bitrate_kbps_); 1579f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org switch (rate_control_state_) { 158c62642c7a662a2a88293b82192e2240049f0cbb9stefan case kRcHold: 1599f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org break; 160c62642c7a662a2a88293b82192e2240049f0cbb9stefan 161c62642c7a662a2a88293b82192e2240049f0cbb9stefan case kRcIncrease: 162c62642c7a662a2a88293b82192e2240049f0cbb9stefan if (avg_max_bitrate_kbps_ >= 0 && 163c62642c7a662a2a88293b82192e2240049f0cbb9stefan incoming_bitrate_kbps > 164c62642c7a662a2a88293b82192e2240049f0cbb9stefan avg_max_bitrate_kbps_ + 3 * std_max_bit_rate) { 165c62642c7a662a2a88293b82192e2240049f0cbb9stefan ChangeRegion(kRcMaxUnknown); 166c62642c7a662a2a88293b82192e2240049f0cbb9stefan avg_max_bitrate_kbps_ = -1.0; 1679f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 1689f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (rate_control_region_ == kRcNearMax) { 1699f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Approximate the over-use estimator delay to 100 ms. 17016825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org const int64_t response_time = rtt_ + 100; 1719f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org uint32_t additive_increase_bps = AdditiveRateIncrease( 1729f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org now_ms, time_last_bitrate_change_, response_time); 1739f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps += additive_increase_bps; 1749f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1759f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } else { 1769f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease( 1779f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org now_ms, time_last_bitrate_change_, current_bitrate_bps); 1789f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps += multiplicative_increase_bps; 1799f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 1809f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1819f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_last_bitrate_change_ = now_ms; 1829f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org break; 183c62642c7a662a2a88293b82192e2240049f0cbb9stefan 184c62642c7a662a2a88293b82192e2240049f0cbb9stefan case kRcDecrease: 18511324b95612876e3335b20c4188bc9790d0b8539Stefan Holmer bitrate_is_initialized_ = true; 1869f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (incoming_bitrate_bps < min_configured_bitrate_bps_) { 1879f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps = min_configured_bitrate_bps_; 1889f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } else { 1899f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Set bit rate to something slightly lower than max 1909f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // to get rid of any self-induced delay. 1919f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps = static_cast<uint32_t>(beta_ * 1929f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org incoming_bitrate_bps + 0.5); 1939f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (current_bitrate_bps > current_bitrate_bps_) { 1949f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Avoid increasing the rate when over-using. 1959f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (rate_control_region_ != kRcMaxUnknown) { 1969f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps = static_cast<uint32_t>( 1979f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org beta_ * avg_max_bitrate_kbps_ * 1000 + 0.5f); 1989f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 1999f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps = std::min(current_bitrate_bps, 2009f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps_); 2019f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2029f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org ChangeRegion(kRcNearMax); 2039f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 2049f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (incoming_bitrate_kbps < avg_max_bitrate_kbps_ - 2059f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 3 * std_max_bit_rate) { 2069f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org avg_max_bitrate_kbps_ = -1.0f; 2079f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2089f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 2099f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org UpdateMaxBitRateEstimate(incoming_bitrate_kbps); 2109f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2119f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Stay on hold until the pipes are cleared. 2129f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org ChangeState(kRcHold); 2139f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_last_bitrate_change_ = now_ms; 2149f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org break; 215c62642c7a662a2a88293b82192e2240049f0cbb9stefan 2169f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org default: 2179f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org assert(false); 2189f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 219c62642c7a662a2a88293b82192e2240049f0cbb9stefan if ((incoming_bitrate_bps > 100000 || current_bitrate_bps > 150000) && 2209f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps > 1.5 * incoming_bitrate_bps) { 2219f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Allow changing the bit rate if we are operating at very low rates 2229f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Don't change the bit rate if the send side is too far off 2239f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps = current_bitrate_bps_; 2249f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_last_bitrate_change_ = now_ms; 2259f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2269f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return current_bitrate_bps; 2279f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 2289f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 2299f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orguint32_t AimdRateControl::MultiplicativeRateIncrease( 2309f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org int64_t now_ms, int64_t last_ms, uint32_t current_bitrate_bps) const { 2319f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org double alpha = 1.08; 2329f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (last_ms > -1) { 2339f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org int time_since_last_update_ms = std::min(static_cast<int>(now_ms - last_ms), 2349f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1000); 2359f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org alpha = pow(alpha, time_since_last_update_ms / 1000.0); 2369f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2379f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org uint32_t multiplicative_increase_bps = std::max( 2389f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org current_bitrate_bps * (alpha - 1.0), 1000.0); 2399f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return multiplicative_increase_bps; 2409f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 2419f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 2429f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orguint32_t AimdRateControl::AdditiveRateIncrease( 24316825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t now_ms, int64_t last_ms, int64_t response_time_ms) const { 2449f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org assert(response_time_ms > 0); 2459f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org double beta = 0.0; 2469f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (last_ms > 0) { 247c62642c7a662a2a88293b82192e2240049f0cbb9stefan beta = std::min((now_ms - last_ms) / static_cast<double>(response_time_ms), 248c62642c7a662a2a88293b82192e2240049f0cbb9stefan 1.0); 249c62642c7a662a2a88293b82192e2240049f0cbb9stefan if (in_experiment_) 250c62642c7a662a2a88293b82192e2240049f0cbb9stefan beta /= 2.0; 2519f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2529f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0; 2539f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0)); 2549f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org double avg_packet_size_bits = bits_per_frame / packets_per_frame; 2559f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org uint32_t additive_increase_bps = std::max( 2569f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 1000.0, beta * avg_packet_size_bits); 2579f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org return additive_increase_bps; 2589f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 2599f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 2609f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgvoid AimdRateControl::UpdateMaxBitRateEstimate(float incoming_bitrate_kbps) { 2619f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org const float alpha = 0.05f; 2629f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (avg_max_bitrate_kbps_ == -1.0f) { 2639f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org avg_max_bitrate_kbps_ = incoming_bitrate_kbps; 2649f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } else { 2659f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org avg_max_bitrate_kbps_ = (1 - alpha) * avg_max_bitrate_kbps_ + 2669f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org alpha * incoming_bitrate_kbps; 2679f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2689f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // Estimate the max bit rate variance and normalize the variance 2699f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // with the average max bit rate. 2709f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org const float norm = std::max(avg_max_bitrate_kbps_, 1.0f); 2719f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org var_max_bitrate_kbps_ = (1 - alpha) * var_max_bitrate_kbps_ + 2729f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org alpha * (avg_max_bitrate_kbps_ - incoming_bitrate_kbps) * 2739f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org (avg_max_bitrate_kbps_ - incoming_bitrate_kbps) / norm; 2749f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // 0.4 ~= 14 kbit/s at 500 kbit/s 2759f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (var_max_bitrate_kbps_ < 0.4f) { 2769f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org var_max_bitrate_kbps_ = 0.4f; 2779f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2789f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org // 2.5f ~= 35 kbit/s at 500 kbit/s 2799f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (var_max_bitrate_kbps_ > 2.5f) { 2809f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org var_max_bitrate_kbps_ = 2.5f; 2819f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2829f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 2839f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 2849f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgvoid AimdRateControl::ChangeState(const RateControlInput& input, 2859f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org int64_t now_ms) { 2868f09f170e650e14c4cd57c51be32a46e8cd1843bterelius switch (current_input_.bw_state) { 2879f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org case kBwNormal: 2889f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (rate_control_state_ == kRcHold) { 2899f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org time_last_bitrate_change_ = now_ms; 2909f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org ChangeState(kRcIncrease); 2919f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2929f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org break; 2939f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org case kBwOverusing: 2949f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org if (rate_control_state_ != kRcDecrease) { 2959f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org ChangeState(kRcDecrease); 2969f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 2979f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org break; 2989f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org case kBwUnderusing: 2999f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org ChangeState(kRcHold); 3009f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org break; 3019f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org default: 3029f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org assert(false); 3039f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org } 3049f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 3059f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 3069f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgvoid AimdRateControl::ChangeRegion(RateControlRegion region) { 3079f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org rate_control_region_ = region; 3089f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 3099f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org 3109f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.orgvoid AimdRateControl::ChangeState(RateControlState new_state) { 3119f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org rate_control_state_ = new_state; 3129f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} 3139f79fe684a5d8c2dfb0db43a3715f32c5eebd94fpbos@webrtc.org} // namespace webrtc 314