diff --git a/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc b/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc index fd54980d43..1236ea06e0 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc @@ -10,89 +10,52 @@ #include "modules/remote_bitrate_estimator/remote_rate_control.h" -#include -#include -#include -#if _WIN32 -#include -#endif +#include +#include +#include +#include #include "system_wrappers/interface/trace.h" -#ifdef MATLAB -extern MatlabEngine eng; // global variable defined elsewhere -#endif - namespace webrtc { const unsigned int kDefaultRttMs = 200; RemoteRateControl::RemoteRateControl() -: -_minConfiguredBitRate(30000), -_maxConfiguredBitRate(30000000), -_currentBitRate(_maxConfiguredBitRate), -_maxHoldRate(0), -_avgMaxBitRate(-1.0f), -_varMaxBitRate(0.4f), -_rcState(kRcHold), -_cameFromState(kRcDecrease), -_rcRegion(kRcMaxUnknown), -_lastBitRateChange(-1), -_currentInput(kBwNormal, 0, 1.0), -_updated(false), -_timeFirstIncomingEstimate(-1), -_initializedBitRate(false), -_avgChangePeriod(1000.0f), -_lastChangeMs(-1), -_beta(0.9f), -_rtt(kDefaultRttMs) -#ifdef MATLAB -,_plot1(NULL), -_plot2(NULL) -#endif + : min_configured_bit_rate_(30000), + max_configured_bit_rate_(30000000), + current_bit_rate_(max_configured_bit_rate_), + max_hold_rate_(0), + avg_max_bit_rate_(-1.0f), + var_max_bit_rate_(0.4f), + rate_control_state_(kRcHold), + came_from_state_(kRcDecrease), + rate_control_region_(kRcMaxUnknown), + last_bit_rate_change_(-1), + current_input_(kBwNormal, 0, 1.0), + updated_(false), + time_first_incoming_estimate_(-1), + initialized_bit_rate_(false), + avg_change_period_(1000.0f), + last_change_ms_(-1), + beta_(0.9f), + rtt_(kDefaultRttMs) { } -RemoteRateControl::~RemoteRateControl() -{ -#ifdef MATLAB - eng.DeletePlot(_plot1); - eng.DeletePlot(_plot2); -#endif -} - -void RemoteRateControl::Reset() -{ - _minConfiguredBitRate = 30000; - _maxConfiguredBitRate = 30000000; - _currentBitRate = _maxConfiguredBitRate; - _maxHoldRate = 0; - _avgMaxBitRate = -1.0f; - _varMaxBitRate = 0.4f; - _rcState = kRcHold; - _cameFromState = kRcHold; - _rcRegion = kRcMaxUnknown; - _lastBitRateChange = -1; - _avgChangePeriod = 1000.0f; - _lastChangeMs = -1; - _beta = 0.9f; - _currentInput._bwState = kBwNormal; - _currentInput._incomingBitRate = 0; - _currentInput._noiseVar = 1.0; - _updated = false; - _timeFirstIncomingEstimate = -1; - _initializedBitRate = false; +void RemoteRateControl::Reset() { + *this = RemoteRateControl(); + came_from_state_ = kRcHold; } bool RemoteRateControl::ValidEstimate() const { - return _initializedBitRate; + return initialized_bit_rate_; } -bool RemoteRateControl::TimeToReduceFurther( - int64_t time_now, unsigned int incoming_bitrate) const { - const int bitrate_reduction_interval = BWE_MAX(BWE_MIN(_rtt, 200), 10); - if (time_now - _lastBitRateChange >= bitrate_reduction_interval) { +bool RemoteRateControl::TimeToReduceFurther(int64_t time_now, + unsigned int incoming_bitrate) const { + const int bitrate_reduction_interval = std::max(std::min(rtt_, 200u), 10u); + if (time_now - last_bit_rate_change_ >= bitrate_reduction_interval) { return true; } if (ValidEstimate()) { @@ -103,405 +66,319 @@ bool RemoteRateControl::TimeToReduceFurther( return false; } -int32_t RemoteRateControl::SetConfiguredBitRates( - uint32_t minBitRateBps, uint32_t maxBitRateBps) -{ - if (minBitRateBps > maxBitRateBps) - { - return -1; - } - _minConfiguredBitRate = minBitRateBps; - _maxConfiguredBitRate = maxBitRateBps; - _currentBitRate = BWE_MIN(BWE_MAX(minBitRateBps, _currentBitRate), - maxBitRateBps); - return 0; +int32_t RemoteRateControl::SetConfiguredBitRates(uint32_t min_bit_rate_bps, + uint32_t max_bit_rate_bps) { + if (min_bit_rate_bps > max_bit_rate_bps) { + return -1; + } + min_configured_bit_rate_ = min_bit_rate_bps; + max_configured_bit_rate_ = max_bit_rate_bps; + current_bit_rate_ = std::min(std::max(min_bit_rate_bps, current_bit_rate_), + max_bit_rate_bps); + return 0; } uint32_t RemoteRateControl::LatestEstimate() const { - return _currentBitRate; + return current_bit_rate_; } -uint32_t RemoteRateControl::UpdateBandwidthEstimate(int64_t nowMS) -{ - _currentBitRate = ChangeBitRate(_currentBitRate, - _currentInput._incomingBitRate, - _currentInput._noiseVar, - nowMS); - return _currentBitRate; +uint32_t RemoteRateControl::UpdateBandwidthEstimate(int64_t now_ms) { + current_bit_rate_ = ChangeBitRate(current_bit_rate_, + current_input_._incomingBitRate, + current_input_._noiseVar, + now_ms); + return current_bit_rate_; } void RemoteRateControl::SetRtt(unsigned int rtt) { - _rtt = rtt; + rtt_ = rtt; } RateControlRegion RemoteRateControl::Update(const RateControlInput* input, - int64_t nowMS) -{ - assert(input); -#ifdef MATLAB - // Create plots - if (_plot1 == NULL) - { - _plot1 = eng.NewPlot(new MatlabPlot()); + int64_t now_ms) { + assert(input); - _plot1->AddTimeLine(30, "b", "current"); - _plot1->AddTimeLine(30, "r-", "avgMax"); - _plot1->AddTimeLine(30, "r--", "pStdMax"); - _plot1->AddTimeLine(30, "r--", "nStdMax"); - _plot1->AddTimeLine(30, "r+", "max"); - _plot1->AddTimeLine(30, "g", "incoming"); - _plot1->AddTimeLine(30, "b+", "recovery"); + // Set the initial bit rate value to what we're receiving the first half + // second. + if (!initialized_bit_rate_) { + if (time_first_incoming_estimate_ < 0) { + if (input->_incomingBitRate > 0) { + time_first_incoming_estimate_ = now_ms; + } + } else if (now_ms - time_first_incoming_estimate_ > 500 && + input->_incomingBitRate > 0) { + current_bit_rate_ = input->_incomingBitRate; + initialized_bit_rate_ = true; } - if (_plot2 == NULL) - { - _plot2 = eng.NewPlot(new MatlabPlot()); + } - _plot2->AddTimeLine(30, "b", "alpha"); - } -#endif - - // Set the initial bit rate value to what we're receiving the first half - // second. - if (!_initializedBitRate) - { - if (_timeFirstIncomingEstimate < 0) - { - if (input->_incomingBitRate > 0) - { - _timeFirstIncomingEstimate = nowMS; - } - } - else if (nowMS - _timeFirstIncomingEstimate > 500 && - input->_incomingBitRate > 0) - { - _currentBitRate = input->_incomingBitRate; - _initializedBitRate = true; - } - } - - if (_updated && _currentInput._bwState == kBwOverusing) - { - // Only update delay factor and incoming bit rate. We always want to react on an over-use. - _currentInput._noiseVar = input->_noiseVar; - _currentInput._incomingBitRate = input->_incomingBitRate; - return _rcRegion; - } - _updated = true; - _currentInput = *input; - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: Incoming rate = %u kbps", input->_incomingBitRate/1000); - return _rcRegion; + if (updated_ && current_input_._bwState == kBwOverusing) { + // Only update delay factor and incoming bit rate. We always want to react + // on an over-use. + current_input_._noiseVar = input->_noiseVar; + current_input_._incomingBitRate = input->_incomingBitRate; + return rate_control_region_; + } + updated_ = true; + current_input_ = *input; + WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: Incoming rate = %u kbps", + input->_incomingBitRate/1000); + return rate_control_region_; } -uint32_t RemoteRateControl::ChangeBitRate(uint32_t currentBitRate, - uint32_t incomingBitRate, - double noiseVar, - int64_t nowMS) -{ - if (!_updated) - { - return _currentBitRate; +uint32_t RemoteRateControl::ChangeBitRate(uint32_t current_bit_rate, + uint32_t incoming_bit_rate, + double noise_var, + int64_t now_ms) { + if (!updated_) { + return current_bit_rate_; + } + updated_ = false; + UpdateChangePeriod(now_ms); + ChangeState(current_input_, now_ms); + // calculated here because it's used in multiple places + const float incoming_bit_rate_kbps = incoming_bit_rate / 1000.0f; + // Calculate the max bit rate std dev given the normalized + // variance and the current incoming bit rate. + const float std_max_bit_rate = sqrt(var_max_bit_rate_ * avg_max_bit_rate_); + bool recovery = false; + switch (rate_control_state_) { + case kRcHold: { + max_hold_rate_ = std::max(max_hold_rate_, incoming_bit_rate); + break; } - _updated = false; - UpdateChangePeriod(nowMS); - ChangeState(_currentInput, nowMS); - // calculated here because it's used in multiple places - const float incomingBitRateKbps = incomingBitRate / 1000.0f; - // Calculate the max bit rate std dev given the normalized - // variance and the current incoming bit rate. - const float stdMaxBitRate = sqrt(_varMaxBitRate * _avgMaxBitRate); - bool recovery = false; - switch (_rcState) - { - case kRcHold: - { - _maxHoldRate = BWE_MAX(_maxHoldRate, incomingBitRate); - break; + case kRcIncrease: { + if (avg_max_bit_rate_ >= 0) { + if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 3 * std_max_bit_rate) { + ChangeRegion(kRcMaxUnknown); + avg_max_bit_rate_ = -1.0; + } else if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 2.5 * + std_max_bit_rate) { + ChangeRegion(kRcAboveMax); } - case kRcIncrease: - { - if (_avgMaxBitRate >= 0) - { - if (incomingBitRateKbps > _avgMaxBitRate + 3 * stdMaxBitRate) - { - ChangeRegion(kRcMaxUnknown); - _avgMaxBitRate = -1.0; - } - else if (incomingBitRateKbps > _avgMaxBitRate + 2.5 * stdMaxBitRate) - { - ChangeRegion(kRcAboveMax); - } - } - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "BWE: Response time: %f + %i + 10*33\n", - _avgChangePeriod, _rtt); - const uint32_t responseTime = static_cast(_avgChangePeriod + 0.5f) + _rtt + 300; - double alpha = RateIncreaseFactor(nowMS, _lastBitRateChange, - responseTime, noiseVar); + } + WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, + "BWE: Response time: %f + %i + 10*33\n", + avg_change_period_, rtt_); + const uint32_t response_time = static_cast(avg_change_period_ + + 0.5f) + rtt_ + 300; + double alpha = RateIncreaseFactor(now_ms, last_bit_rate_change_, + response_time, noise_var); - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "BWE: _avgChangePeriod = %f ms; RTT = %u ms", _avgChangePeriod, _rtt); + WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, + "BWE: avg_change_period_ = %f ms; RTT = %u ms", avg_change_period_, + rtt_); - currentBitRate = static_cast(currentBitRate * alpha) + 1000; - if (_maxHoldRate > 0 && _beta * _maxHoldRate > currentBitRate) - { - currentBitRate = static_cast(_beta * _maxHoldRate); - _avgMaxBitRate = _beta * _maxHoldRate / 1000.0f; - ChangeRegion(kRcNearMax); - recovery = true; -#ifdef MATLAB - _plot1->Append("recovery", _maxHoldRate/1000); -#endif - } - _maxHoldRate = 0; - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "BWE: Increase rate to currentBitRate = %u kbps", currentBitRate/1000); - _lastBitRateChange = nowMS; - break; + current_bit_rate = static_cast(current_bit_rate * alpha) + 1000; + if (max_hold_rate_ > 0 && beta_ * max_hold_rate_ > current_bit_rate) { + current_bit_rate = static_cast(beta_ * max_hold_rate_); + avg_max_bit_rate_ = beta_ * max_hold_rate_ / 1000.0f; + ChangeRegion(kRcNearMax); + recovery = true; + } + max_hold_rate_ = 0; + WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, + "BWE: Increase rate to current_bit_rate = %u kbps", + current_bit_rate / 1000); + last_bit_rate_change_ = now_ms; + break; + } + case kRcDecrease: { + if (incoming_bit_rate < min_configured_bit_rate_) { + current_bit_rate = min_configured_bit_rate_; + } else { + // Set bit rate to something slightly lower than max + // to get rid of any self-induced delay. + current_bit_rate = static_cast(beta_ * incoming_bit_rate + + 0.5); + if (current_bit_rate > current_bit_rate_) { + // Avoid increasing the rate when over-using. + if (rate_control_region_ != kRcMaxUnknown) { + current_bit_rate = static_cast(beta_ * avg_max_bit_rate_ * + 1000 + 0.5f); + } + current_bit_rate = std::min(current_bit_rate, current_bit_rate_); } - case kRcDecrease: - { - if (incomingBitRate < _minConfiguredBitRate) - { - currentBitRate = _minConfiguredBitRate; - } - else - { - // Set bit rate to something slightly lower than max - // to get rid of any self-induced delay. - currentBitRate = static_cast(_beta * incomingBitRate + 0.5); - if (currentBitRate > _currentBitRate) - { - // Avoid increasing the rate when over-using. - if (_rcRegion != kRcMaxUnknown) - { - currentBitRate = static_cast(_beta * _avgMaxBitRate * 1000 + 0.5f); - } - currentBitRate = BWE_MIN(currentBitRate, _currentBitRate); - } - ChangeRegion(kRcNearMax); + ChangeRegion(kRcNearMax); - if (incomingBitRateKbps < _avgMaxBitRate - 3 * stdMaxBitRate) - { - _avgMaxBitRate = -1.0f; - } - - UpdateMaxBitRateEstimate(incomingBitRateKbps); - -#ifdef MATLAB - _plot1->Append("max", incomingBitRateKbps); -#endif - - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: Decrease rate to currentBitRate = %u kbps", currentBitRate/1000); - } - // Stay on hold until the pipes are cleared. - ChangeState(kRcHold); - _lastBitRateChange = nowMS; - break; + if (incoming_bit_rate_kbps < avg_max_bit_rate_ - 3 * std_max_bit_rate) { + avg_max_bit_rate_ = -1.0f; } + + UpdateMaxBitRateEstimate(incoming_bit_rate_kbps); + + WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, + "BWE: Decrease rate to current_bit_rate = %u kbps", + current_bit_rate / 1000); + } + // Stay on hold until the pipes are cleared. + ChangeState(kRcHold); + last_bit_rate_change_ = now_ms; + break; } - if (!recovery && (incomingBitRate > 100000 || currentBitRate > 150000) && - currentBitRate > 1.5 * incomingBitRate) - { - // Allow changing the bit rate if we are operating at very low rates - // Don't change the bit rate if the send side is too far off - currentBitRate = _currentBitRate; - _lastBitRateChange = nowMS; - } -#ifdef MATLAB - if (_avgMaxBitRate >= 0.0f) - { - _plot1->Append("avgMax", _avgMaxBitRate); - _plot1->Append("pStdMax", _avgMaxBitRate + 3*stdMaxBitRate); - _plot1->Append("nStdMax", _avgMaxBitRate - 3*stdMaxBitRate); - } - _plot1->Append("incoming", incomingBitRate/1000); - _plot1->Append("current", currentBitRate/1000); - _plot1->Plot(); -#endif - return currentBitRate; + default: + assert(false); + } + if (!recovery && (incoming_bit_rate > 100000 || current_bit_rate > 150000) && + current_bit_rate > 1.5 * incoming_bit_rate) { + // Allow changing the bit rate if we are operating at very low rates + // Don't change the bit rate if the send side is too far off + current_bit_rate = current_bit_rate_; + last_bit_rate_change_ = now_ms; + } + return current_bit_rate; } -double RemoteRateControl::RateIncreaseFactor(int64_t nowMs, int64_t lastMs, uint32_t reactionTimeMs, double noiseVar) const -{ - // alpha = 1.02 + B ./ (1 + exp(b*(tr - (c1*s2 + c2)))) - // Parameters - const double B = 0.0407; - const double b = 0.0025; - const double c1 = -6700.0 / (33 * 33); - const double c2 = 800.0; - const double d = 0.85; +double RemoteRateControl::RateIncreaseFactor(int64_t now_ms, + int64_t last_ms, + uint32_t reaction_time_ms, + double noise_var) const { + // alpha = 1.02 + B ./ (1 + exp(b*(tr - (c1*s2 + c2)))) + // Parameters + const double B = 0.0407; + const double b = 0.0025; + const double c1 = -6700.0 / (33 * 33); + const double c2 = 800.0; + const double d = 0.85; - double alpha = 1.005 + B / (1 + exp( b * (d * reactionTimeMs - (c1 * noiseVar + c2)))); + double alpha = 1.005 + B / (1 + exp( b * (d * reaction_time_ms - + (c1 * noise_var + c2)))); - if (alpha < 1.005) - { - alpha = 1.005; - } - else if (alpha > 1.3) - { - alpha = 1.3; - } + if (alpha < 1.005) { + alpha = 1.005; + } else if (alpha > 1.3) { + alpha = 1.3; + } - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "BWE: alpha = %f", alpha); -#ifdef MATLAB - _plot2->Append("alpha", alpha); - _plot2->Plot(); -#endif + WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: alpha = %f", alpha); - if (lastMs > -1) - { - alpha = pow(alpha, (nowMs - lastMs) / 1000.0); - } + if (last_ms > -1) { + alpha = pow(alpha, (now_ms - last_ms) / 1000.0); + } - if (_rcRegion == kRcNearMax) - { - // We're close to our previous maximum. Try to stabilize the - // bit rate in this region, by increasing in smaller steps. - alpha = alpha - (alpha - 1.0) / 2.0; - } - else if (_rcRegion == kRcMaxUnknown) - { - alpha = alpha + (alpha - 1.0) * 2.0; - } + if (rate_control_region_ == kRcNearMax) { + // We're close to our previous maximum. Try to stabilize the + // bit rate in this region, by increasing in smaller steps. + alpha = alpha - (alpha - 1.0) / 2.0; + } else if (rate_control_region_ == kRcMaxUnknown) { + alpha = alpha + (alpha - 1.0) * 2.0; + } - return alpha; + return alpha; } -void RemoteRateControl::UpdateChangePeriod(int64_t nowMs) -{ - int64_t changePeriod = 0; - if (_lastChangeMs > -1) - { - changePeriod = nowMs - _lastChangeMs; - } - _lastChangeMs = nowMs; - _avgChangePeriod = 0.9f * _avgChangePeriod + 0.1f * changePeriod; +void RemoteRateControl::UpdateChangePeriod(int64_t now_ms) { + int64_t changePeriod = 0; + if (last_change_ms_ > -1) { + changePeriod = now_ms - last_change_ms_; + } + last_change_ms_ = now_ms; + avg_change_period_ = 0.9f * avg_change_period_ + 0.1f * changePeriod; } -void RemoteRateControl::UpdateMaxBitRateEstimate(float incomingBitRateKbps) -{ - const float alpha = 0.05f; - if (_avgMaxBitRate == -1.0f) - { - _avgMaxBitRate = incomingBitRateKbps; - } - else - { - _avgMaxBitRate = (1 - alpha) * _avgMaxBitRate + - alpha * incomingBitRateKbps; - } - // Estimate the max bit rate variance and normalize the variance - // with the average max bit rate. - const float norm = BWE_MAX(_avgMaxBitRate, 1.0f); - _varMaxBitRate = (1 - alpha) * _varMaxBitRate + - alpha * (_avgMaxBitRate - incomingBitRateKbps) * - (_avgMaxBitRate - incomingBitRateKbps) / - norm; - // 0.4 ~= 14 kbit/s at 500 kbit/s - if (_varMaxBitRate < 0.4f) - { - _varMaxBitRate = 0.4f; - } - // 2.5f ~= 35 kbit/s at 500 kbit/s - if (_varMaxBitRate > 2.5f) - { - _varMaxBitRate = 2.5f; - } +void RemoteRateControl::UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps) { + const float alpha = 0.05f; + if (avg_max_bit_rate_ == -1.0f) { + avg_max_bit_rate_ = incoming_bit_rate_kbps; + } else { + avg_max_bit_rate_ = (1 - alpha) * avg_max_bit_rate_ + + alpha * incoming_bit_rate_kbps; + } + // Estimate the max bit rate variance and normalize the variance + // with the average max bit rate. + const float norm = std::max(avg_max_bit_rate_, 1.0f); + var_max_bit_rate_ = (1 - alpha) * var_max_bit_rate_ + + alpha * (avg_max_bit_rate_ - incoming_bit_rate_kbps) * + (avg_max_bit_rate_ - incoming_bit_rate_kbps) / norm; + // 0.4 ~= 14 kbit/s at 500 kbit/s + if (var_max_bit_rate_ < 0.4f) { + var_max_bit_rate_ = 0.4f; + } + // 2.5f ~= 35 kbit/s at 500 kbit/s + if (var_max_bit_rate_ > 2.5f) { + var_max_bit_rate_ = 2.5f; + } } -void RemoteRateControl::ChangeState(const RateControlInput& input, int64_t nowMs) -{ - switch (_currentInput._bwState) - { +void RemoteRateControl::ChangeState(const RateControlInput& input, + int64_t now_ms) { + switch (current_input_._bwState) { case kBwNormal: - { - if (_rcState == kRcHold) - { - _lastBitRateChange = nowMs; - ChangeState(kRcIncrease); - } - break; - } + if (rate_control_state_ == kRcHold) { + last_bit_rate_change_ = now_ms; + ChangeState(kRcIncrease); + } + break; case kBwOverusing: - { - if (_rcState != kRcDecrease) - { - ChangeState(kRcDecrease); - } - break; - } + if (rate_control_state_ != kRcDecrease) { + ChangeState(kRcDecrease); + } + break; case kBwUnderusing: - { - ChangeState(kRcHold); - break; - } - } + ChangeState(kRcHold); + break; + default: + assert(false); + } } -void RemoteRateControl::ChangeRegion(RateControlRegion region) -{ - _rcRegion = region; - switch (_rcRegion) - { +void RemoteRateControl::ChangeRegion(RateControlRegion region) { + rate_control_region_ = region; + switch (rate_control_region_) { case kRcAboveMax: case kRcMaxUnknown: - { - _beta = 0.9f; - break; - } + beta_ = 0.9f; + break; case kRcNearMax: - { - _beta = 0.95f; - break; - } - } + beta_ = 0.95f; + break; + default: + assert(false); + } } -void RemoteRateControl::ChangeState(RateControlState newState) -{ - _cameFromState = _rcState; - _rcState = newState; - char state1[15]; - char state2[15]; - char state3[15]; - StateStr(_cameFromState, state1); - StateStr(_rcState, state2); - StateStr(_currentInput._bwState, state3); - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "\t%s => %s due to %s\n", state1, state2, state3); +void RemoteRateControl::ChangeState(RateControlState new_state) { + came_from_state_ = rate_control_state_; + rate_control_state_ = new_state; + char state1[15]; + char state2[15]; + char state3[15]; + StateStr(came_from_state_, state1); + StateStr(rate_control_state_, state2); + StateStr(current_input_._bwState, state3); + WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, + "\t%s => %s due to %s\n", state1, state2, state3); } -void RemoteRateControl::StateStr(RateControlState state, char* str) -{ - switch (state) - { +void RemoteRateControl::StateStr(RateControlState state, char* str) { + switch (state) { case kRcDecrease: - strncpy(str, "DECREASE", 9); - break; + strncpy(str, "DECREASE", 9); + break; case kRcHold: - strncpy(str, "HOLD", 5); - break; + strncpy(str, "HOLD", 5); + break; case kRcIncrease: - strncpy(str, "INCREASE", 9); - break; - } + strncpy(str, "INCREASE", 9); + break; + default: + assert(false); + } } -void RemoteRateControl::StateStr(BandwidthUsage state, char* str) -{ - switch (state) - { +void RemoteRateControl::StateStr(BandwidthUsage state, char* str) { + switch (state) { case kBwNormal: - strncpy(str, "NORMAL", 7); - break; + strncpy(str, "NORMAL", 7); + break; case kBwOverusing: - strncpy(str, "OVER USING", 11); - break; + strncpy(str, "OVER USING", 11); + break; case kBwUnderusing: - strncpy(str, "UNDER USING", 12); - break; - } + strncpy(str, "UNDER USING", 12); + break; + default: + assert(false); + } } - } // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h b/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h index 273305d002..efbebfb317 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h +++ b/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h @@ -12,77 +12,68 @@ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_REMOTE_RATE_CONTROL_H_ #include "modules/remote_bitrate_estimator/include/bwe_defines.h" -#include "typedefs.h" - -#ifdef MATLAB -#include "../test/BWEStandAlone/MatlabPlot.h" -#endif namespace webrtc { -class RemoteRateControl -{ -public: - RemoteRateControl(); - ~RemoteRateControl(); - int32_t SetConfiguredBitRates(uint32_t minBitRate, - uint32_t maxBitRate); - uint32_t LatestEstimate() const; - uint32_t UpdateBandwidthEstimate(int64_t nowMS); - void SetRtt(unsigned int rtt); - RateControlRegion Update(const RateControlInput* input, - int64_t nowMS); - void Reset(); - // Returns true if there is a valid estimate of the incoming bitrate, false - // otherwise. - bool ValidEstimate() const; - // Returns true if the bitrate estimate hasn't been changed for more than - // an RTT, or if the incoming_bitrate is more than 5% above the current - // estimate. Should be used to decide if we should reduce the rate further - // when over-using. - bool TimeToReduceFurther(int64_t time_now, - unsigned int incoming_bitrate) const; +class RemoteRateControl { + public: + RemoteRateControl(); + ~RemoteRateControl() {} -private: - uint32_t ChangeBitRate(uint32_t currentBitRate, - uint32_t incomingBitRate, - double delayFactor, - int64_t nowMS); - double RateIncreaseFactor(int64_t nowMs, - int64_t lastMs, - uint32_t reactionTimeMs, - double noiseVar) const; - void UpdateChangePeriod(int64_t nowMs); - void UpdateMaxBitRateEstimate(float incomingBitRateKbps); - void ChangeState(const RateControlInput& input, int64_t nowMs); - void ChangeState(RateControlState newState); - void ChangeRegion(RateControlRegion region); - static void StateStr(RateControlState state, char* str); - static void StateStr(BandwidthUsage state, char* str); + void Reset(); - uint32_t _minConfiguredBitRate; - uint32_t _maxConfiguredBitRate; - uint32_t _currentBitRate; - uint32_t _maxHoldRate; - float _avgMaxBitRate; - float _varMaxBitRate; - RateControlState _rcState; - RateControlState _cameFromState; - RateControlRegion _rcRegion; - int64_t _lastBitRateChange; - RateControlInput _currentInput; - bool _updated; - int64_t _timeFirstIncomingEstimate; - bool _initializedBitRate; + // Returns true if there is a valid estimate of the incoming bitrate, false + // otherwise. + bool ValidEstimate() const; - float _avgChangePeriod; - int64_t _lastChangeMs; - float _beta; - unsigned int _rtt; -#ifdef MATLAB - MatlabPlot *_plot1; - MatlabPlot *_plot2; -#endif + // Returns true if the bitrate estimate hasn't been changed for more than + // an RTT, or if the incoming_bitrate is more than 5% above the current + // estimate. Should be used to decide if we should reduce the rate further + // when over-using. + bool TimeToReduceFurther(int64_t time_now, + unsigned int incoming_bitrate) const; + + int32_t SetConfiguredBitRates(uint32_t min_bit_rate, uint32_t max_bit_rate); + uint32_t LatestEstimate() const; + uint32_t UpdateBandwidthEstimate(int64_t now_ms); + void SetRtt(unsigned int rtt); + RateControlRegion Update(const RateControlInput* input, int64_t now_ms); + + private: + uint32_t ChangeBitRate(uint32_t current_bit_rate, + uint32_t incoming_bit_rate, + double delay_factor, + int64_t now_ms); + double RateIncreaseFactor(int64_t now_ms, + int64_t last_ms, + uint32_t reaction_time_ms, + double noise_var) const; + void UpdateChangePeriod(int64_t now_ms); + void UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps); + void ChangeState(const RateControlInput& input, int64_t now_ms); + void ChangeState(RateControlState new_state); + void ChangeRegion(RateControlRegion region); + static void StateStr(RateControlState state, char* str); + static void StateStr(BandwidthUsage state, char* str); + + uint32_t min_configured_bit_rate_; + uint32_t max_configured_bit_rate_; + uint32_t current_bit_rate_; + uint32_t max_hold_rate_; + float avg_max_bit_rate_; + float var_max_bit_rate_; + RateControlState rate_control_state_; + RateControlState came_from_state_; + RateControlRegion rate_control_region_; + int64_t last_bit_rate_change_; + RateControlInput current_input_; + bool updated_; + int64_t time_first_incoming_estimate_; + bool initialized_bit_rate_; + float avg_change_period_; + int64_t last_change_ms_; + float beta_; + unsigned int rtt_; }; } // namespace webrtc