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