1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11d5d709e492b5592114ecc197516a453acfee46dfpbos@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> 143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <math.h> 153f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <string.h> 163f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org 175f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org#include <algorithm> 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19d5d709e492b5592114ecc197516a453acfee46dfpbos@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 222a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org 232a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.orgconst unsigned int kDefaultRttMs = 200; 242a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org 25c49a3fafdc740b3790caac63b9dc267fa3393931henrik.lundin@webrtc.orgRemoteRateControl::RemoteRateControl(uint32_t min_bitrate_bps) 26c49a3fafdc740b3790caac63b9dc267fa3393931henrik.lundin@webrtc.org : min_configured_bit_rate_(min_bitrate_bps), 275f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org max_configured_bit_rate_(30000000), 285f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate_(max_configured_bit_rate_), 295f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org max_hold_rate_(0), 305f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org avg_max_bit_rate_(-1.0f), 315f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org var_max_bit_rate_(0.4f), 325f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org rate_control_state_(kRcHold), 335f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org came_from_state_(kRcDecrease), 345f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org rate_control_region_(kRcMaxUnknown), 355f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org last_bit_rate_change_(-1), 365f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_input_(kBwNormal, 0, 1.0), 375f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org updated_(false), 385f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org time_first_incoming_estimate_(-1), 395f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org initialized_bit_rate_(false), 405f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org avg_change_period_(1000.0f), 415f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org last_change_ms_(-1), 425f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org beta_(0.9f), 435f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org rtt_(kDefaultRttMs) 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 475f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgvoid RemoteRateControl::Reset() { 48c49a3fafdc740b3790caac63b9dc267fa3393931henrik.lundin@webrtc.org *this = RemoteRateControl(min_configured_bit_rate_); 495f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org came_from_state_ = kRcHold; 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool RemoteRateControl::ValidEstimate() const { 535f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return initialized_bit_rate_; 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 565f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgbool RemoteRateControl::TimeToReduceFurther(int64_t time_now, 575f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org unsigned int incoming_bitrate) const { 585f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const int bitrate_reduction_interval = std::max(std::min(rtt_, 200u), 10u); 595f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (time_now - last_bit_rate_change_ >= bitrate_reduction_interval) { 602a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org return true; 612a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org } 622a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org if (ValidEstimate()) { 632a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org const int threshold = static_cast<int>(1.05 * incoming_bitrate); 642a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org const int bitrate_difference = LatestEstimate() - incoming_bitrate; 652a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org return bitrate_difference > threshold; 662a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org } 672a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org return false; 682a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org} 692a5dbce193b4ee594f0bb66c4f1a2bb24f31e621stefan@webrtc.org 705f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgint32_t RemoteRateControl::SetConfiguredBitRates(uint32_t min_bit_rate_bps, 715f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org uint32_t max_bit_rate_bps) { 725f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (min_bit_rate_bps > max_bit_rate_bps) { 735f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return -1; 745f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 755f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org min_configured_bit_rate_ = min_bit_rate_bps; 765f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org max_configured_bit_rate_ = max_bit_rate_bps; 775f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate_ = std::min(std::max(min_bit_rate_bps, current_bit_rate_), 785f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org max_bit_rate_bps); 795f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return 0; 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 8263a1ebd1cc2015b9aff6a1369530b852e75f6234pbos@webrtc.orguint32_t RemoteRateControl::LatestEstimate() const { 835f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return current_bit_rate_; 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 865f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orguint32_t RemoteRateControl::UpdateBandwidthEstimate(int64_t now_ms) { 875f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate_ = ChangeBitRate(current_bit_rate_, 885f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_input_._incomingBitRate, 895f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_input_._noiseVar, 905f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org now_ms); 915f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return current_bit_rate_; 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid RemoteRateControl::SetRtt(unsigned int rtt) { 955f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org rtt_ = rtt; 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRateControlRegion RemoteRateControl::Update(const RateControlInput* input, 995f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org int64_t now_ms) { 1005f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org assert(input); 1015f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 1025f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Set the initial bit rate value to what we're receiving the first half 1035f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // second. 1045f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (!initialized_bit_rate_) { 1055f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (time_first_incoming_estimate_ < 0) { 1065f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (input->_incomingBitRate > 0) { 1075f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org time_first_incoming_estimate_ = now_ms; 1085f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1095f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } else if (now_ms - time_first_incoming_estimate_ > 500 && 1105f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org input->_incomingBitRate > 0) { 1115f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate_ = input->_incomingBitRate; 1125f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org initialized_bit_rate_ = true; 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1145f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1165f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (updated_ && current_input_._bwState == kBwOverusing) { 1175f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Only update delay factor and incoming bit rate. We always want to react 1185f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // on an over-use. 1195f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_input_._noiseVar = input->_noiseVar; 1205f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_input_._incomingBitRate = input->_incomingBitRate; 1215f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return rate_control_region_; 1225f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1235f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org updated_ = true; 1245f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_input_ = *input; 1255f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return rate_control_region_; 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1285f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orguint32_t RemoteRateControl::ChangeBitRate(uint32_t current_bit_rate, 1295f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org uint32_t incoming_bit_rate, 1305f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org double noise_var, 1315f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org int64_t now_ms) { 1325f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (!updated_) { 1335f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return current_bit_rate_; 1345f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1355f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org updated_ = false; 1365f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org UpdateChangePeriod(now_ms); 1375f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeState(current_input_, now_ms); 1385f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // calculated here because it's used in multiple places 1395f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const float incoming_bit_rate_kbps = incoming_bit_rate / 1000.0f; 1405f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Calculate the max bit rate std dev given the normalized 1415f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // variance and the current incoming bit rate. 1425f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const float std_max_bit_rate = sqrt(var_max_bit_rate_ * avg_max_bit_rate_); 1435f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org bool recovery = false; 1445f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org switch (rate_control_state_) { 1455f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org case kRcHold: { 1465f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org max_hold_rate_ = std::max(max_hold_rate_, incoming_bit_rate); 1475f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1495f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org case kRcIncrease: { 1505f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (avg_max_bit_rate_ >= 0) { 1515f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 3 * std_max_bit_rate) { 1525f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeRegion(kRcMaxUnknown); 1535f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org avg_max_bit_rate_ = -1.0; 1545f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } else if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 2.5 * 1555f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org std_max_bit_rate) { 1565f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeRegion(kRcAboveMax); 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1585f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1595f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const uint32_t response_time = static_cast<uint32_t>(avg_change_period_ + 1605f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 0.5f) + rtt_ + 300; 1615f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org double alpha = RateIncreaseFactor(now_ms, last_bit_rate_change_, 1625f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org response_time, noise_var); 1635f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 1645f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate = static_cast<uint32_t>(current_bit_rate * alpha) + 1000; 1655f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (max_hold_rate_ > 0 && beta_ * max_hold_rate_ > current_bit_rate) { 1665f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate = static_cast<uint32_t>(beta_ * max_hold_rate_); 1675f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org avg_max_bit_rate_ = beta_ * max_hold_rate_ / 1000.0f; 1685f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeRegion(kRcNearMax); 1695f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org recovery = true; 1705f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1715f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org max_hold_rate_ = 0; 1725f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org last_bit_rate_change_ = now_ms; 1735f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 1745f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1755f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org case kRcDecrease: { 1765f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (incoming_bit_rate < min_configured_bit_rate_) { 1775f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate = min_configured_bit_rate_; 1785f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } else { 1795f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Set bit rate to something slightly lower than max 1805f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // to get rid of any self-induced delay. 1815f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate = static_cast<uint32_t>(beta_ * incoming_bit_rate + 1825f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 0.5); 1835f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (current_bit_rate > current_bit_rate_) { 1845f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Avoid increasing the rate when over-using. 1855f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (rate_control_region_ != kRcMaxUnknown) { 1865f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate = static_cast<uint32_t>(beta_ * avg_max_bit_rate_ * 1875f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 1000 + 0.5f); 1885f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1895f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate = std::min(current_bit_rate, current_bit_rate_); 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1915f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeRegion(kRcNearMax); 1925f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 1935f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (incoming_bit_rate_kbps < avg_max_bit_rate_ - 3 * std_max_bit_rate) { 1945f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org avg_max_bit_rate_ = -1.0f; 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1965f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 1975f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org UpdateMaxBitRateEstimate(incoming_bit_rate_kbps); 1985f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 1995f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Stay on hold until the pipes are cleared. 2005f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeState(kRcHold); 2015f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org last_bit_rate_change_ = now_ms; 2025f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2045f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org default: 2055f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org assert(false); 2065f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 2075f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (!recovery && (incoming_bit_rate > 100000 || current_bit_rate > 150000) && 2085f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate > 1.5 * incoming_bit_rate) { 2095f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Allow changing the bit rate if we are operating at very low rates 2105f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Don't change the bit rate if the send side is too far off 2115f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org current_bit_rate = current_bit_rate_; 2125f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org last_bit_rate_change_ = now_ms; 2135f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 2145f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return current_bit_rate; 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2175f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgdouble RemoteRateControl::RateIncreaseFactor(int64_t now_ms, 2185f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org int64_t last_ms, 2195f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org uint32_t reaction_time_ms, 2205f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org double noise_var) const { 2215f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // alpha = 1.02 + B ./ (1 + exp(b*(tr - (c1*s2 + c2)))) 2225f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Parameters 2235f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const double B = 0.0407; 2245f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const double b = 0.0025; 2255f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const double c1 = -6700.0 / (33 * 33); 2265f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const double c2 = 800.0; 2275f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const double d = 0.85; 2285f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 2295f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org double alpha = 1.005 + B / (1 + exp( b * (d * reaction_time_ms - 2305f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org (c1 * noise_var + c2)))); 2315f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org 2325f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (alpha < 1.005) { 2335f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org alpha = 1.005; 2345f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } else if (alpha > 1.3) { 2355f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org alpha = 1.3; 2365f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2385f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (last_ms > -1) { 2395f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org alpha = pow(alpha, (now_ms - last_ms) / 1000.0); 2405f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2425f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (rate_control_region_ == kRcNearMax) { 2435f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // We're close to our previous maximum. Try to stabilize the 2445f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // bit rate in this region, by increasing in smaller steps. 2455f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org alpha = alpha - (alpha - 1.0) / 2.0; 2465f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } else if (rate_control_region_ == kRcMaxUnknown) { 2475f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org alpha = alpha + (alpha - 1.0) * 2.0; 2485f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2505f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org return alpha; 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2535f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgvoid RemoteRateControl::UpdateChangePeriod(int64_t now_ms) { 254b7716d8746900180a583dba863c2cea7e4e0959csolenberg@webrtc.org int64_t change_period = 0; 2555f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (last_change_ms_ > -1) { 256b7716d8746900180a583dba863c2cea7e4e0959csolenberg@webrtc.org change_period = now_ms - last_change_ms_; 2575f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 2585f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org last_change_ms_ = now_ms; 259b7716d8746900180a583dba863c2cea7e4e0959csolenberg@webrtc.org avg_change_period_ = 0.9f * avg_change_period_ + 0.1f * change_period; 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2625f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgvoid RemoteRateControl::UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps) { 2635f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const float alpha = 0.05f; 2645f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (avg_max_bit_rate_ == -1.0f) { 2655f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org avg_max_bit_rate_ = incoming_bit_rate_kbps; 2665f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } else { 2675f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org avg_max_bit_rate_ = (1 - alpha) * avg_max_bit_rate_ + 2685f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org alpha * incoming_bit_rate_kbps; 2695f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 2705f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // Estimate the max bit rate variance and normalize the variance 2715f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // with the average max bit rate. 2725f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org const float norm = std::max(avg_max_bit_rate_, 1.0f); 2735f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org var_max_bit_rate_ = (1 - alpha) * var_max_bit_rate_ + 274b7716d8746900180a583dba863c2cea7e4e0959csolenberg@webrtc.org alpha * (avg_max_bit_rate_ - incoming_bit_rate_kbps) * 275b7716d8746900180a583dba863c2cea7e4e0959csolenberg@webrtc.org (avg_max_bit_rate_ - incoming_bit_rate_kbps) / norm; 2765f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // 0.4 ~= 14 kbit/s at 500 kbit/s 2775f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (var_max_bit_rate_ < 0.4f) { 2785f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org var_max_bit_rate_ = 0.4f; 2795f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 2805f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org // 2.5f ~= 35 kbit/s at 500 kbit/s 2815f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (var_max_bit_rate_ > 2.5f) { 2825f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org var_max_bit_rate_ = 2.5f; 2835f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2865f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgvoid RemoteRateControl::ChangeState(const RateControlInput& input, 2875f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org int64_t now_ms) { 2885f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org switch (current_input_._bwState) { 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kBwNormal: 2905f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (rate_control_state_ == kRcHold) { 2915f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org last_bit_rate_change_ = now_ms; 2925f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeState(kRcIncrease); 2935f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 2945f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kBwOverusing: 2965f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org if (rate_control_state_ != kRcDecrease) { 2975f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeState(kRcDecrease); 2985f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 2995f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kBwUnderusing: 3015f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org ChangeState(kRcHold); 3025f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 3035f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org default: 3045f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org assert(false); 3055f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3085f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgvoid RemoteRateControl::ChangeRegion(RateControlRegion region) { 3095f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org rate_control_region_ = region; 3105f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org switch (rate_control_region_) { 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kRcAboveMax: 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kRcMaxUnknown: 3135f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org beta_ = 0.9f; 3145f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kRcNearMax: 3165f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org beta_ = 0.95f; 3175f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org break; 3185f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org default: 3195f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org assert(false); 3205f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org } 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3235f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.orgvoid RemoteRateControl::ChangeState(RateControlState new_state) { 3245f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org came_from_state_ = rate_control_state_; 3255f09bcca21a6077d146ec20655311acc033de803solenberg@webrtc.org rate_control_state_ = new_state; 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 3273b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org} // namespace webrtc 328