diff --git a/src/modules/remote_bitrate_estimator/OWNERS b/src/modules/remote_bitrate_estimator/OWNERS deleted file mode 100644 index b705ede2a..000000000 --- a/src/modules/remote_bitrate_estimator/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -pwestin@webrtc.org -stefan@webrtc.org -henrik.lundin@webrtc.org -mflodman@webrtc.org -asapersson@webrtc.org \ No newline at end of file diff --git a/src/modules/remote_bitrate_estimator/bitrate_estimator.cc b/src/modules/remote_bitrate_estimator/bitrate_estimator.cc deleted file mode 100644 index 84c287cf7..000000000 --- a/src/modules/remote_bitrate_estimator/bitrate_estimator.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "bitrate_estimator.h" - -namespace webrtc { - -enum { kBitrateAverageWindow = 2000 }; - -BitRateStats::BitRateStats() - :_dataSamples(), _accumulatedBytes(0) -{ -} - -BitRateStats::~BitRateStats() -{ - while (_dataSamples.size() > 0) - { - delete _dataSamples.front(); - _dataSamples.pop_front(); - } -} - -void BitRateStats::Init() -{ - _accumulatedBytes = 0; - while (_dataSamples.size() > 0) - { - delete _dataSamples.front(); - _dataSamples.pop_front(); - } -} - -void BitRateStats::Update(WebRtc_UWord32 packetSizeBytes, WebRtc_Word64 nowMs) -{ - // Find an empty slot for storing the new sample and at the same time - // accumulate the history. - _dataSamples.push_back(new DataTimeSizeTuple(packetSizeBytes, nowMs)); - _accumulatedBytes += packetSizeBytes; - EraseOld(nowMs); -} - -void BitRateStats::EraseOld(WebRtc_Word64 nowMs) -{ - while (_dataSamples.size() > 0) - { - if (nowMs - _dataSamples.front()->_timeCompleteMs > - kBitrateAverageWindow) - { - // Delete old sample - _accumulatedBytes -= _dataSamples.front()->_sizeBytes; - delete _dataSamples.front(); - _dataSamples.pop_front(); - } - else - { - break; - } - } -} - -WebRtc_UWord32 BitRateStats::BitRate(WebRtc_Word64 nowMs) -{ - // Calculate the average bit rate the past BITRATE_AVERAGE_WINDOW ms. - // Removes any old samples from the list. - EraseOld(nowMs); - WebRtc_Word64 timeOldest = nowMs; - if (_dataSamples.size() > 0) - { - timeOldest = _dataSamples.front()->_timeCompleteMs; - } - // Update average bit rate - float denom = static_cast(nowMs - timeOldest); - if (nowMs == timeOldest) - { - // Calculate with a one second window when we haven't - // received more than one packet. - denom = 1000.0; - } - return static_cast(_accumulatedBytes * 8.0f * 1000.0f / - denom + 0.5f); -} - -} // namespace webrtc diff --git a/src/modules/remote_bitrate_estimator/bitrate_estimator.h b/src/modules/remote_bitrate_estimator/bitrate_estimator.h deleted file mode 100644 index a3622a75c..000000000 --- a/src/modules/remote_bitrate_estimator/bitrate_estimator.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_BITRATE_ESTIMATOR_H_ -#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_BITRATE_ESTIMATOR_H_ - -#include - -#include "typedefs.h" - -namespace webrtc { - -class BitRateStats -{ -public: - BitRateStats(); - ~BitRateStats(); - - void Init(); - void Update(WebRtc_UWord32 packetSizeBytes, WebRtc_Word64 nowMs); - WebRtc_UWord32 BitRate(WebRtc_Word64 nowMs); - -private: - struct DataTimeSizeTuple - { - DataTimeSizeTuple(uint32_t sizeBytes, int64_t timeCompleteMs) - : - _sizeBytes(sizeBytes), - _timeCompleteMs(timeCompleteMs) {} - - WebRtc_UWord32 _sizeBytes; - WebRtc_Word64 _timeCompleteMs; - }; - - void EraseOld(WebRtc_Word64 nowMs); - - std::list _dataSamples; - WebRtc_UWord32 _accumulatedBytes; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_BITRATE_ESTIMATOR_H_ diff --git a/src/modules/remote_bitrate_estimator/include/bwe_defines.h b/src/modules/remote_bitrate_estimator/include/bwe_defines.h deleted file mode 100644 index 173a28432..000000000 --- a/src/modules/remote_bitrate_estimator/include/bwe_defines.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_BWE_DEFINES_H_ -#define WEBRTC_MODULES_RTP_RTCP_SOURCE_BWE_DEFINES_H_ - -#include "typedefs.h" - -#define BWE_MAX(a,b) ((a)>(b)?(a):(b)) -#define BWE_MIN(a,b) ((a)<(b)?(a):(b)) - -namespace webrtc { -enum BandwidthUsage -{ - kBwNormal, - kBwOverusing, - kBwUnderUsing -}; - -enum RateControlState -{ - kRcHold, - kRcIncrease, - kRcDecrease -}; - -enum RateControlRegion -{ - kRcNearMax, - kRcAboveMax, - kRcMaxUnknown -}; - -class RateControlInput -{ -public: - RateControlInput(BandwidthUsage bwState, - WebRtc_UWord32 incomingBitRate, - double noiseVar) - : _bwState(bwState), - _incomingBitRate(incomingBitRate), - _noiseVar(noiseVar) {} - - BandwidthUsage _bwState; - WebRtc_UWord32 _incomingBitRate; - double _noiseVar; -}; -} //namespace webrtc - -#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_BWE_DEFINES_H_ diff --git a/src/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h b/src/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h deleted file mode 100644 index 76a958354..000000000 --- a/src/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_MOCK_MOCK_REMOTE_BITRATE_ESTIMATOR_H_ -#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_MOCK_MOCK_REMOTE_BITRATE_ESTIMATOR_H_ - -#include - -#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" - -namespace webrtc { - -class MockRemoteBitrateObserver : public RemoteBitrateObserver { - public: - MOCK_METHOD2(OnReceiveBitrateChanged, - void(unsigned int ssrc, unsigned int bitrate)); -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_MOCK_MOCK_REMOTE_BITRATE_ESTIMATOR_H_ diff --git a/src/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h b/src/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h deleted file mode 100644 index 990b383b3..000000000 --- a/src/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// RemoteBitrateEstimator -// This class estimates the incoming bitrate capacity. - -#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_REMOTE_BITRATE_ESTIMATOR_H_ -#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_REMOTE_BITRATE_ESTIMATOR_H_ - -#include - -#include "modules/remote_bitrate_estimator/bitrate_estimator.h" -#include "modules/remote_bitrate_estimator/overuse_detector.h" -#include "modules/remote_bitrate_estimator/remote_rate_control.h" -#include "system_wrappers/interface/critical_section_wrapper.h" -#include "system_wrappers/interface/scoped_ptr.h" -#include "typedefs.h" - -namespace webrtc { - -// RemoteBitrateObserver is used to signal changes in bitrate estimates for -// the incoming stream. -class RemoteBitrateObserver { - public: - // Called when a receive channel has a new bitrate estimate for the incoming - // stream. - virtual void OnReceiveBitrateChanged(unsigned int ssrc, - unsigned int bitrate) = 0; - - virtual ~RemoteBitrateObserver() {} -}; - -class RemoteBitrateEstimator { - public: - explicit RemoteBitrateEstimator(RemoteBitrateObserver* observer); - - // Called for each incoming packet. If this is a new SSRC, a new - // BitrateControl will be created. - void IncomingPacket(unsigned int ssrc, - int packet_size, - int64_t arrival_time, - uint32_t rtp_timestamp, - int64_t packet_send_time); - - // Triggers a new estimate calculation for the stream identified by |ssrc|. - void UpdateEstimate(unsigned int ssrc, int64_t time_now); - - // Set the current round-trip time experienced by the stream identified by - // |ssrc|. - void SetRtt(unsigned int ssrc); - - // Removes all data for |ssrc|. - void RemoveStream(unsigned int ssrc); - - // Returns true if a valid estimate exists for a stream identified by |ssrc| - // and sets |bitrate_bps| to the estimated bitrate in bits per second. - bool LatestEstimate(unsigned int ssrc, unsigned int* bitrate_bps) const; - - private: - struct BitrateControls { - RemoteRateControl remote_rate; - OverUseDetector overuse_detector; - BitRateStats incoming_bitrate; - }; - - typedef std::map SsrcBitrateControlsMap; - - SsrcBitrateControlsMap bitrate_controls_; - RemoteBitrateObserver* observer_; - scoped_ptr crit_sect_; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_REMOTE_BITRATE_ESTIMATOR_H_ diff --git a/src/modules/remote_bitrate_estimator/overuse_detector.cc b/src/modules/remote_bitrate_estimator/overuse_detector.cc deleted file mode 100644 index 8947839c7..000000000 --- a/src/modules/remote_bitrate_estimator/overuse_detector.cc +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include // abs -#if _WIN32 -#include -#endif - -#include "modules/remote_bitrate_estimator/overuse_detector.h" -#include "modules/remote_bitrate_estimator/remote_rate_control.h" -#include "modules/rtp_rtcp/source/rtp_utility.h" -#include "system_wrappers/interface/trace.h" - -#ifdef WEBRTC_BWE_MATLAB -extern MatlabEngine eng; // global variable defined elsewhere -#endif - -#define INIT_CAPACITY_SLOPE 8.0/512.0 -#define DETECTOR_THRESHOLD 25.0 -#define OVER_USING_TIME_THRESHOLD 100 -#define MIN_FRAME_PERIOD_HISTORY_LEN 60 - -namespace webrtc { -OverUseDetector::OverUseDetector() - : firstPacket_(true), - currentFrame_(), - prevFrame_(), - numOfDeltas_(0), - slope_(INIT_CAPACITY_SLOPE), - offset_(0), - E_(), - processNoise_(), - avgNoise_(0.0), - varNoise_(500), - threshold_(DETECTOR_THRESHOLD), - tsDeltaHist_(), - prevOffset_(0.0), - timeOverUsing_(-1), - overUseCounter_(0), -#ifndef WEBRTC_BWE_MATLAB - hypothesis_(kBwNormal) { -#else - plot1_(NULL), - plot2_(NULL), - plot3_(NULL), - plot4_(NULL) { -#endif - E_[0][0] = 100; - E_[1][1] = 1e-1; - E_[0][1] = E_[1][0] = 0; - processNoise_[0] = 1e-10; - processNoise_[1] = 1e-2; -} - -OverUseDetector::~OverUseDetector() { -#ifdef WEBRTC_BWE_MATLAB - if (plot1_) { - eng.DeletePlot(plot1_); - plot1_ = NULL; - } - if (plot2_) { - eng.DeletePlot(plot2_); - plot2_ = NULL; - } - if (plot3_) { - eng.DeletePlot(plot3_); - plot3_ = NULL; - } - if (plot4_) { - eng.DeletePlot(plot4_); - plot4_ = NULL; - } -#endif - - tsDeltaHist_.clear(); -} - -void OverUseDetector::Reset() { - firstPacket_ = true; - currentFrame_.size_ = 0; - currentFrame_.completeTimeMs_ = -1; - currentFrame_.timestamp_ = -1; - prevFrame_.size_ = 0; - prevFrame_.completeTimeMs_ = -1; - prevFrame_.timestamp_ = -1; - numOfDeltas_ = 0; - slope_ = INIT_CAPACITY_SLOPE; - offset_ = 0; - E_[0][0] = 100; - E_[1][1] = 1e-1; - E_[0][1] = E_[1][0] = 0; - processNoise_[0] = 1e-10; - processNoise_[1] = 1e-2; - avgNoise_ = 0.0; - varNoise_ = 500; - threshold_ = DETECTOR_THRESHOLD; - prevOffset_ = 0.0; - timeOverUsing_ = -1; - overUseCounter_ = 0; - hypothesis_ = kBwNormal; - tsDeltaHist_.clear(); -} - -void OverUseDetector::Update(WebRtc_UWord16 packetSize, - WebRtc_UWord32 timestamp, - const WebRtc_Word64 nowMS) { -#ifdef WEBRTC_BWE_MATLAB - // Create plots - const WebRtc_Word64 startTimeMs = nowMS; - if (plot1_ == NULL) { - plot1_ = eng.NewPlot(new MatlabPlot()); - plot1_->AddLine(1000, "b.", "scatter"); - } - if (plot2_ == NULL) { - plot2_ = eng.NewPlot(new MatlabPlot()); - plot2_->AddTimeLine(30, "b", "offset", startTimeMs); - plot2_->AddTimeLine(30, "r--", "limitPos", startTimeMs); - plot2_->AddTimeLine(30, "k.", "trigger", startTimeMs); - plot2_->AddTimeLine(30, "ko", "detection", startTimeMs); - // plot2_->AddTimeLine(30, "g", "slowMean", startTimeMs); - } - if (plot3_ == NULL) { - plot3_ = eng.NewPlot(new MatlabPlot()); - plot3_->AddTimeLine(30, "b", "noiseVar", startTimeMs); - } - if (plot4_ == NULL) { - plot4_ = eng.NewPlot(new MatlabPlot()); - // plot4_->AddTimeLine(60, "b", "p11", startTimeMs); - // plot4_->AddTimeLine(60, "r", "p12", startTimeMs); - plot4_->AddTimeLine(60, "g", "p22", startTimeMs); - // plot4_->AddTimeLine(60, "g--", "p22_hat", startTimeMs); - // plot4_->AddTimeLine(30, "b.-", "deltaFs", startTimeMs); - } - -#endif - - bool wrapped = false; - bool completeFrame = false; - if (currentFrame_.timestamp_ == -1) { - currentFrame_.timestamp_ = timestamp; - } else if (OldTimestamp( - timestamp, - static_cast(currentFrame_.timestamp_), - &wrapped)) { - // Don't update with old data - return; - } else if (timestamp != currentFrame_.timestamp_) { - // First packet of a later frame, the previous frame sample is ready - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "Frame complete at %I64i", currentFrame_.completeTimeMs_); - if (prevFrame_.completeTimeMs_ >= 0) { // This is our second frame - WebRtc_Word64 tDelta = 0; - double tsDelta = 0; - // Check for wrap - OldTimestamp( - static_cast(prevFrame_.timestamp_), - static_cast(currentFrame_.timestamp_), - &wrapped); - CompensatedTimeDelta(currentFrame_, prevFrame_, tDelta, tsDelta, - wrapped); - UpdateKalman(tDelta, tsDelta, currentFrame_.size_, - prevFrame_.size_); - } - // The new timestamp is now the current frame, - // and the old timestamp becomes the previous frame. - prevFrame_ = currentFrame_; - currentFrame_.timestamp_ = timestamp; - currentFrame_.size_ = 0; - currentFrame_.completeTimeMs_ = -1; - completeFrame = true; - } - // Accumulate the frame size - currentFrame_.size_ += packetSize; - currentFrame_.completeTimeMs_ = nowMS; -} - -BandwidthUsage OverUseDetector::State() const { - return hypothesis_; -} - -double OverUseDetector::NoiseVar() const { - return varNoise_; -} - -void OverUseDetector::SetRateControlRegion(RateControlRegion region) { - switch (region) { - case kRcMaxUnknown: { - threshold_ = DETECTOR_THRESHOLD; - break; - } - case kRcAboveMax: - case kRcNearMax: { - threshold_ = DETECTOR_THRESHOLD / 2; - break; - } - } -} - -void OverUseDetector::CompensatedTimeDelta(const FrameSample& currentFrame, - const FrameSample& prevFrame, - WebRtc_Word64& tDelta, - double& tsDelta, - bool wrapped) { - numOfDeltas_++; - if (numOfDeltas_ > 1000) { - numOfDeltas_ = 1000; - } - // Add wrap-around compensation - WebRtc_Word64 wrapCompensation = 0; - if (wrapped) { - wrapCompensation = static_cast(1)<<32; - } - tsDelta = (currentFrame.timestamp_ - + wrapCompensation - - prevFrame.timestamp_) / 90.0; - tDelta = currentFrame.completeTimeMs_ - prevFrame.completeTimeMs_; - assert(tsDelta > 0); -} - -double OverUseDetector::CurrentDrift() { - return 1.0; -} - -void OverUseDetector::UpdateKalman(WebRtc_Word64 tDelta, - double tsDelta, - WebRtc_UWord32 frameSize, - WebRtc_UWord32 prevFrameSize) { - const double minFramePeriod = UpdateMinFramePeriod(tsDelta); - const double drift = CurrentDrift(); - // Compensate for drift - const double tTsDelta = tDelta - tsDelta / drift; - double fsDelta = static_cast(frameSize) - prevFrameSize; - - // Update the Kalman filter - const double scaleFactor = minFramePeriod / (1000.0 / 30.0); - E_[0][0] += processNoise_[0] * scaleFactor; - E_[1][1] += processNoise_[1] * scaleFactor; - - if ((hypothesis_ == kBwOverusing && offset_ < prevOffset_) || - (hypothesis_ == kBwUnderUsing && offset_ > prevOffset_)) { - E_[1][1] += 10 * processNoise_[1] * scaleFactor; - } - - const double h[2] = {fsDelta, 1.0}; - const double Eh[2] = {E_[0][0]*h[0] + E_[0][1]*h[1], - E_[1][0]*h[0] + E_[1][1]*h[1]}; - - const double residual = tTsDelta - slope_*h[0] - offset_; - - const bool stableState = - (BWE_MIN(numOfDeltas_, 60) * abs(offset_) < threshold_); - // We try to filter out very late frames. For instance periodic key - // frames doesn't fit the Gaussian model well. - if (abs(residual) < 3 * sqrt(varNoise_)) { - UpdateNoiseEstimate(residual, minFramePeriod, stableState); - } else { - UpdateNoiseEstimate(3 * sqrt(varNoise_), minFramePeriod, stableState); - } - - const double denom = varNoise_ + h[0]*Eh[0] + h[1]*Eh[1]; - - const double K[2] = {Eh[0] / denom, - Eh[1] / denom}; - - const double IKh[2][2] = {{1.0 - K[0]*h[0], -K[0]*h[1]}, - {-K[1]*h[0], 1.0 - K[1]*h[1]}}; - const double e00 = E_[0][0]; - const double e01 = E_[0][1]; - - // Update state - E_[0][0] = e00 * IKh[0][0] + E_[1][0] * IKh[0][1]; - E_[0][1] = e01 * IKh[0][0] + E_[1][1] * IKh[0][1]; - E_[1][0] = e00 * IKh[1][0] + E_[1][0] * IKh[1][1]; - E_[1][1] = e01 * IKh[1][0] + E_[1][1] * IKh[1][1]; - - // Covariance matrix, must be positive semi-definite - assert(E_[0][0] + E_[1][1] >= 0 && - E_[0][0] * E_[1][1] - E_[0][1] * E_[1][0] >= 0 && - E_[0][0] >= 0); - -#ifdef WEBRTC_BWE_MATLAB - // plot4_->Append("p11",E_[0][0]); - // plot4_->Append("p12",E_[0][1]); - plot4_->Append("p22", E_[1][1]); - // plot4_->Append("p22_hat", 0.5*(processNoise_[1] + - // sqrt(processNoise_[1]*(processNoise_[1] + 4*varNoise_)))); - // plot4_->Append("deltaFs", fsDelta); - plot4_->Plot(); -#endif - slope_ = slope_ + K[0] * residual; - prevOffset_ = offset_; - offset_ = offset_ + K[1] * residual; - - Detect(tsDelta); - -#ifdef WEBRTC_BWE_MATLAB - plot1_->Append("scatter", - static_cast(currentFrame_.size_) - prevFrame_.size_, - static_cast(tDelta-tsDelta)); - plot1_->MakeTrend("scatter", "slope", slope_, offset_, "k-"); - plot1_->MakeTrend("scatter", "thresholdPos", - slope_, offset_ + 2 * sqrt(varNoise_), "r-"); - plot1_->MakeTrend("scatter", "thresholdNeg", - slope_, offset_ - 2 * sqrt(varNoise_), "r-"); - plot1_->Plot(); - - plot2_->Append("offset", offset_); - plot2_->Append("limitPos", threshold_/BWE_MIN(numOfDeltas_, 60)); - plot2_->Plot(); - - plot3_->Append("noiseVar", varNoise_); - plot3_->Plot(); -#endif -} - -double OverUseDetector::UpdateMinFramePeriod(double tsDelta) { - double minFramePeriod = tsDelta; - if (tsDeltaHist_.size() >= MIN_FRAME_PERIOD_HISTORY_LEN) { - std::list::iterator firstItem = tsDeltaHist_.begin(); - tsDeltaHist_.erase(firstItem); - } - std::list::iterator it = tsDeltaHist_.begin(); - for (; it != tsDeltaHist_.end(); it++) { - minFramePeriod = BWE_MIN(*it, minFramePeriod); - } - tsDeltaHist_.push_back(tsDelta); - return minFramePeriod; -} - -void OverUseDetector::UpdateNoiseEstimate(double residual, - double tsDelta, - bool stableState) { - if (!stableState) { - return; - } - // Faster filter during startup to faster adapt to the jitter level - // of the network alpha is tuned for 30 frames per second, but - double alpha = 0.01; - if (numOfDeltas_ > 10*30) { - alpha = 0.002; - } - // Only update the noise estimate if we're not over-using - // beta is a function of alpha and the time delta since - // the previous update. - const double beta = pow(1 - alpha, tsDelta * 30.0 / 1000.0); - avgNoise_ = beta * avgNoise_ - + (1 - beta) * residual; - varNoise_ = beta * varNoise_ - + (1 - beta) * (avgNoise_ - residual) * (avgNoise_ - residual); - if (varNoise_ < 1e-7) { - varNoise_ = 1e-7; - } -} - -BandwidthUsage OverUseDetector::Detect(double tsDelta) { - if (numOfDeltas_ < 2) { - return kBwNormal; - } - const double T = BWE_MIN(numOfDeltas_, 60) * offset_; - if (abs(T) > threshold_) { - if (offset_ > 0) { - if (timeOverUsing_ == -1) { - // Initialize the timer. Assume that we've been - // over-using half of the time since the previous - // sample. - timeOverUsing_ = tsDelta / 2; - } else { - // Increment timer - timeOverUsing_ += tsDelta; - } - overUseCounter_++; - if (timeOverUsing_ > OVER_USING_TIME_THRESHOLD - && overUseCounter_ > 1) { - if (offset_ >= prevOffset_) { -#ifdef _DEBUG - if (hypothesis_ != kBwOverusing) { - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwOverusing"); - } -#endif - timeOverUsing_ = 0; - overUseCounter_ = 0; - hypothesis_ = kBwOverusing; -#ifdef WEBRTC_BWE_MATLAB - plot2_->Append("detection", offset_); // plot it later -#endif - } - } -#ifdef WEBRTC_BWE_MATLAB - plot2_->Append("trigger", offset_); // plot it later -#endif - } else { -#ifdef _DEBUG - if (hypothesis_ != kBwUnderUsing) { - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwUnderUsing"); - } -#endif - timeOverUsing_ = -1; - overUseCounter_ = 0; - hypothesis_ = kBwUnderUsing; - } - } else { -#ifdef _DEBUG - if (hypothesis_ != kBwNormal) { - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwNormal"); - } -#endif - timeOverUsing_ = -1; - overUseCounter_ = 0; - hypothesis_ = kBwNormal; - } - return hypothesis_; -} - -bool OverUseDetector::OldTimestamp(uint32_t newTimestamp, - uint32_t existingTimestamp, - bool* wrapped) { - bool tmpWrapped = - (newTimestamp < 0x0000ffff && existingTimestamp > 0xffff0000) || - (newTimestamp > 0xffff0000 && existingTimestamp < 0x0000ffff); - *wrapped = tmpWrapped; - if (existingTimestamp > newTimestamp && !tmpWrapped) { - return true; - } else if (existingTimestamp <= newTimestamp && !tmpWrapped) { - return false; - } else if (existingTimestamp < newTimestamp && tmpWrapped) { - return true; - } else { - return false; - } -} - -} // namespace webrtc diff --git a/src/modules/remote_bitrate_estimator/overuse_detector.h b/src/modules/remote_bitrate_estimator/overuse_detector.h deleted file mode 100644 index e4b4c68eb..000000000 --- a/src/modules/remote_bitrate_estimator/overuse_detector.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_OVERUSE_DETECTOR_H_ -#define WEBRTC_MODULES_RTP_RTCP_SOURCE_OVERUSE_DETECTOR_H_ - -#include - -#include "modules/interface/module_common_types.h" -#include "modules/remote_bitrate_estimator/include/bwe_defines.h" -#include "typedefs.h" // NOLINT(build/include) - -#ifdef WEBRTC_BWE_MATLAB -#include "../test/BWEStandAlone/MatlabPlot.h" -#endif - -namespace webrtc { -enum RateControlRegion; - -class OverUseDetector { - public: - OverUseDetector(); - ~OverUseDetector(); - void Update(const WebRtc_UWord16 packetSize, - const WebRtc_UWord32 timestamp, - const WebRtc_Word64 nowMS); - BandwidthUsage State() const; - void Reset(); - double NoiseVar() const; - void SetRateControlRegion(RateControlRegion region); - - private: - struct FrameSample { - FrameSample() : size_(0), completeTimeMs_(-1), timestamp_(-1) {} - - WebRtc_UWord32 size_; - WebRtc_Word64 completeTimeMs_; - WebRtc_Word64 timestamp_; - }; - - static bool OldTimestamp(uint32_t newTimestamp, - uint32_t existingTimestamp, - bool* wrapped); - - void CompensatedTimeDelta(const FrameSample& currentFrame, - const FrameSample& prevFrame, - WebRtc_Word64& tDelta, - double& tsDelta, - bool wrapped); - void UpdateKalman(WebRtc_Word64 tDelta, - double tsDelta, - WebRtc_UWord32 frameSize, - WebRtc_UWord32 prevFrameSize); - double UpdateMinFramePeriod(double tsDelta); - void UpdateNoiseEstimate(double residual, double tsDelta, bool stableState); - BandwidthUsage Detect(double tsDelta); - double CurrentDrift(); - - bool firstPacket_; - FrameSample currentFrame_; - FrameSample prevFrame_; - WebRtc_UWord16 numOfDeltas_; - double slope_; - double offset_; - double E_[2][2]; - double processNoise_[2]; - double avgNoise_; - double varNoise_; - double threshold_; - std::list tsDeltaHist_; - double prevOffset_; - double timeOverUsing_; - WebRtc_UWord16 overUseCounter_; - BandwidthUsage hypothesis_; - -#ifdef WEBRTC_BWE_MATLAB - MatlabPlot* plot1_; - MatlabPlot* plot2_; - MatlabPlot* plot3_; - MatlabPlot* plot4_; -#endif -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_OVERUSE_DETECTOR_H_ diff --git a/src/modules/remote_bitrate_estimator/remote_bitrate_estimator.cc b/src/modules/remote_bitrate_estimator/remote_bitrate_estimator.cc deleted file mode 100644 index a0239f8d2..000000000 --- a/src/modules/remote_bitrate_estimator/remote_bitrate_estimator.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" - -#include "system_wrappers/interface/tick_util.h" - -namespace webrtc { - -RemoteBitrateEstimator::RemoteBitrateEstimator( - RemoteBitrateObserver* observer) - : observer_(observer), - crit_sect_(CriticalSectionWrapper::CreateCriticalSection()) { - assert(observer_); -} - -void RemoteBitrateEstimator::IncomingPacket(unsigned int ssrc, - int packet_size, - int64_t arrival_time, - uint32_t rtp_timestamp, - int64_t packet_send_time) { - CriticalSectionScoped cs(crit_sect_.get()); - SsrcBitrateControlsMap::iterator it = bitrate_controls_.find(ssrc); - if (it == bitrate_controls_.end()) { - // This is a new SSRC. Adding to map. - // TODO(holmer): If the channel changes SSRC the old SSRC will still be - // around in this map until the channel is deleted. This is OK since the - // callback will no longer be called for the old SSRC. This will be - // automatically cleaned up when we have one RemoteBitrateEstimator per REMB - // group. - bitrate_controls_[ssrc] = BitrateControls(); - it = bitrate_controls_.find(ssrc); - } - OverUseDetector* overuse_detector = - &bitrate_controls_[ssrc].overuse_detector; - bitrate_controls_[ssrc].incoming_bitrate.Update(packet_size, arrival_time); - const BandwidthUsage prior_state = overuse_detector->State(); - overuse_detector->Update(packet_size, rtp_timestamp, arrival_time); - if (prior_state != overuse_detector->State() && - overuse_detector->State() == kBwOverusing) { - // The first overuse should immediately trigger a new estimate. - UpdateEstimate(ssrc, arrival_time); - } -} - -void RemoteBitrateEstimator::UpdateEstimate(unsigned int ssrc, - int64_t time_now) { - CriticalSectionScoped cs(crit_sect_.get()); - SsrcBitrateControlsMap::iterator it = bitrate_controls_.find(ssrc); - if (it == bitrate_controls_.end()) { - return; - } - OverUseDetector* overuse_detector = &it->second.overuse_detector; - RemoteRateControl* remote_rate = &it->second.remote_rate; - const RateControlInput input(overuse_detector->State(), - it->second.incoming_bitrate.BitRate(time_now), - overuse_detector->NoiseVar()); - const RateControlRegion region = remote_rate->Update(&input, time_now); - unsigned int target_bitrate = remote_rate->UpdateBandwidthEstimate(time_now); - if (remote_rate->ValidEstimate()) { - observer_->OnReceiveBitrateChanged(ssrc, target_bitrate); - } - overuse_detector->SetRateControlRegion(region); -} - -void RemoteBitrateEstimator::SetRtt(unsigned int rtt) { - CriticalSectionScoped cs(crit_sect_.get()); - for (SsrcBitrateControlsMap::iterator it = bitrate_controls_.begin(); - it != bitrate_controls_.end(); ++it) { - it->second.remote_rate.SetRtt(rtt); - } -} - -void RemoteBitrateEstimator::RemoveStream(unsigned int ssrc) { - CriticalSectionScoped cs(crit_sect_.get()); - // Ignoring the return value which is the number of elements erased. - bitrate_controls_.erase(ssrc); -} - -bool RemoteBitrateEstimator::LatestEstimate(unsigned int ssrc, - unsigned int* bitrate_bps) const { - CriticalSectionScoped cs(crit_sect_.get()); - assert(bitrate_bps != NULL); - SsrcBitrateControlsMap::const_iterator it = bitrate_controls_.find(ssrc); - if (it == bitrate_controls_.end()) { - return false; - } - if (!it->second.remote_rate.ValidEstimate()) { - return false; - } - *bitrate_bps = it->second.remote_rate.LatestEstimate(); - return true; -} - -} // namespace webrtc diff --git a/src/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi b/src/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi deleted file mode 100644 index 7b652a4ad..000000000 --- a/src/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -{ - 'targets': [ - { - 'target_name': 'remote_bitrate_estimator', - 'type': '<(library)', - 'dependencies': [ - # system_wrappers - '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', - ], - 'include_dirs': [ - 'include', - '../rtp_rtcp/interface', - '../interface', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'include', - ], - }, - 'sources': [ - # interface - 'include/bwe_defines.h', - 'include/remote_bitrate_estimator.h', - - # source - 'bitrate_estimator.cc', - 'bitrate_estimator.h', - 'overuse_detector.cc', - 'overuse_detector.h', - 'remote_bitrate_estimator.cc', - 'remote_rate_control.cc', - 'remote_rate_control.h', - ], # source - }, - ], # targets - 'conditions': [ - ['include_tests==1', { - 'targets': [ - { - 'target_name': 'remote_bitrate_estimator_unittests', - 'type': 'executable', - 'dependencies': [ - 'remote_bitrate_estimator', - '<(webrtc_root)/../testing/gmock.gyp:gmock', - '<(webrtc_root)/../testing/gtest.gyp:gtest', - '<(webrtc_root)/../test/test.gyp:test_support_main', - ], - 'sources': [ - 'include/mock/mock_remote_bitrate_estimator.h', - 'bitrate_estimator_unittest.cc', - 'remote_bitrate_estimator_unittest.cc', - ], - }, - ], # targets - }], # build_with_chromium - ], # conditions -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest.cc b/src/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest.cc deleted file mode 100644 index b2a424fea..000000000 --- a/src/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest.cc +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -// This file includes unit tests for RemoteBitrateEstimator. - -#include -#include - -#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" -#include "system_wrappers/interface/scoped_ptr.h" - -namespace webrtc { - -enum { kMtu = 1200 }; - -class TestBitrateObserver : public RemoteBitrateObserver { - public: - TestBitrateObserver() : updated_(false), latest_bitrate_(0) {} - - void OnReceiveBitrateChanged(unsigned int ssrc, unsigned int bitrate) { - latest_bitrate_ = bitrate; - updated_ = true; - } - - bool updated() { - bool updated = updated_; - updated_ = false; - return updated; - } - - unsigned int latest_bitrate() const { - return latest_bitrate_; - } - - private: - bool updated_; - unsigned int latest_bitrate_; -}; - -class StreamGenerator { - public: - struct Packet { - int64_t send_time; - int64_t arrival_time; - uint32_t rtp_timestamp; - unsigned int size; - }; - - typedef std::list PacketList; - - StreamGenerator(int fps, int bitrate_bps, int capacity, int64_t time_now) - : fps_(fps), - bitrate_bps_(bitrate_bps), - capacity_(capacity), - time_now_(time_now), - prev_arrival_time_(time_now), - rtp_timestamp_offset_(0xFFFFF000) {} - - void SetCapacity(int capacity_bps) { - ASSERT_GT(capacity_bps, 0); - capacity_ = capacity_bps; - } - - void SetBitrate(int bitrate_bps) { - ASSERT_GE(bitrate_bps, 0); - bitrate_bps_ = bitrate_bps; - } - - void SetRtpTimestampOffset(uint32_t offset) { - rtp_timestamp_offset_ = offset; - } - - void GenerateFrame(PacketList* packets) { - ASSERT_FALSE(packets == NULL); - ASSERT_TRUE(packets->empty()); - ASSERT_GT(fps_, 0); - int bits_per_frame = bitrate_bps_ / fps_; - int n_packets = std::max(bits_per_frame / (8 * kMtu), 1); - int packet_size = bits_per_frame / (8 * n_packets); - ASSERT_GE(n_packets, 0); - for (int i = 0; i < n_packets; ++i) { - Packet* packet = new Packet; - packet->send_time = time_now_ + kSendSideOffsetMs; - ASSERT_GT(capacity_, 0); - packet->arrival_time = std::max( - prev_arrival_time_ + 8 * 1000 * packet_size / capacity_, - time_now_); - packet->size = packet_size; - packet->rtp_timestamp = rtp_timestamp_offset_ + 90 * packet->send_time; - prev_arrival_time_ = packet->arrival_time; - packets->push_back(packet); - } - time_now_ = time_now_ + 1000 / fps_; - } - - int64_t TimeNow() const { - return time_now_; - } - - private: - enum { kSendSideOffsetMs = 1000 }; - - int fps_; - int bitrate_bps_; - int capacity_; - int64_t time_now_; - int64_t prev_arrival_time_; - uint32_t rtp_timestamp_offset_; -}; - -class RemoteBitrateEstimatorTest : public ::testing::Test { - protected: - virtual void SetUp() { - bitrate_observer_.reset(new TestBitrateObserver); - bitrate_estimator_.reset(new RemoteBitrateEstimator( - bitrate_observer_.get())); - // Framerate: 30 fps; Start bitrate: 300 kbps; Link capacity: 1000 kbps, - // Start time: 0. - stream_generator_.reset(new StreamGenerator(30, 3e5, 1e6, 0)); - } - - // Generates a frame of packets belonging to a stream at a given bitrate and - // with a given ssrc. The stream is pushed through a very simple simulated - // network, and is then given to the receive-side bandwidth estimator. - void GenerateAndProcessFrame(unsigned int ssrc, unsigned int bitrate_bps) { - stream_generator_->SetBitrate(bitrate_bps); - StreamGenerator::PacketList packets; - stream_generator_->GenerateFrame(&packets); - int64_t last_arrival_time = -1; - bool prev_was_decrease = false; - while (!packets.empty()) { - StreamGenerator::Packet* packet = packets.front(); - bitrate_estimator_->IncomingPacket(ssrc, - packet->size, - packet->arrival_time, - packet->rtp_timestamp, - -1); - if (bitrate_observer_->updated()) { - // Verify that new estimates only are triggered by an overuse and a - // rate decrease. - EXPECT_LE(bitrate_observer_->latest_bitrate(), bitrate_bps); - EXPECT_FALSE(prev_was_decrease); - prev_was_decrease = true; - } else { - prev_was_decrease = false; - } - last_arrival_time = packet->arrival_time; - delete packet; - packets.pop_front(); - } - EXPECT_GT(last_arrival_time, -1); - bitrate_estimator_->UpdateEstimate(ssrc, last_arrival_time); - } - - // Run the bandwidth estimator with a stream of |number_of_frames| frames. - // Can for instance be used to run the estimator for some time to get it - // into a steady state. - unsigned int SteadyStateRun(unsigned int ssrc, - int number_of_frames, - unsigned int start_bitrate, - unsigned int min_bitrate, - unsigned int max_bitrate) { - unsigned int bitrate_bps = start_bitrate; - bool bitrate_update_seen = false; - // Produce |number_of_frames| frames and give them to the estimator. - for (int i = 0; i < number_of_frames; ++i) { - GenerateAndProcessFrame(ssrc, bitrate_bps); - if (bitrate_observer_->updated()) { - EXPECT_LT(bitrate_observer_->latest_bitrate(), max_bitrate); - EXPECT_GT(bitrate_observer_->latest_bitrate(), min_bitrate); - bitrate_bps = bitrate_observer_->latest_bitrate(); - bitrate_update_seen = true; - } - } - EXPECT_TRUE(bitrate_update_seen); - return bitrate_bps; - } - - scoped_ptr bitrate_estimator_; - scoped_ptr bitrate_observer_; - scoped_ptr stream_generator_; -}; - -TEST_F(RemoteBitrateEstimatorTest, TestInitialBehavior) { - unsigned int bitrate_bps = 0; - unsigned int ssrc = 0; - int64_t time_now = 0; - uint32_t timestamp = 0; - EXPECT_FALSE(bitrate_estimator_->LatestEstimate(ssrc, &bitrate_bps)); - bitrate_estimator_->UpdateEstimate(ssrc, time_now); - EXPECT_FALSE(bitrate_estimator_->LatestEstimate(ssrc, &bitrate_bps)); - EXPECT_FALSE(bitrate_observer_->updated()); - // Inserting a packet. Still no valid estimate. We need to wait 1 second. - bitrate_estimator_->IncomingPacket(ssrc, kMtu, time_now, - timestamp, -1); - bitrate_estimator_->UpdateEstimate(ssrc, time_now); - EXPECT_FALSE(bitrate_estimator_->LatestEstimate(ssrc, &bitrate_bps)); - EXPECT_FALSE(bitrate_observer_->updated()); - // Waiting more than one second gives us a valid estimate. - time_now += 1001; - bitrate_estimator_->UpdateEstimate(ssrc, time_now); - EXPECT_TRUE(bitrate_estimator_->LatestEstimate(ssrc, &bitrate_bps)); - EXPECT_EQ(bitrate_bps, 10734u); - EXPECT_TRUE(bitrate_observer_->updated()); - EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps); -} - -// Make sure we initially increase the bitrate as expected. -TEST_F(RemoteBitrateEstimatorTest, TestRateIncreaseRtpTimestamps) { - const int kExpectedIterations = 323; - unsigned int bitrate_bps = 30000; - unsigned int ssrc = 0; - int iterations = 0; - // Feed the estimator with a stream of packets and verify that it reaches - // 500 kbps at the expected time. - while (bitrate_bps < 5e5) { - GenerateAndProcessFrame(ssrc, bitrate_bps); - if (bitrate_observer_->updated()) { - EXPECT_GT(bitrate_observer_->latest_bitrate(), bitrate_bps); - bitrate_bps = bitrate_observer_->latest_bitrate(); - } - ++iterations; - ASSERT_LE(iterations, kExpectedIterations); - } - ASSERT_EQ(iterations, kExpectedIterations); -} - -// Verify that the time it takes for the estimator to reduce the bitrate when -// the capacity is tightened stays the same. -TEST_F(RemoteBitrateEstimatorTest, TestCapacityDropRtpTimestamps) { - const unsigned int kSsrc = 0; - const int kNumberOfFrames= 1000; - const int kStartBitrate = 900e3; - const int kMinExpectedBitrate = 800e3; - const int kMaxExpectedBitrate = 1500e3; - // Run in steady state to make the estimator converge. - unsigned int bitrate_bps = SteadyStateRun(kSsrc, kNumberOfFrames, - kStartBitrate, kMinExpectedBitrate, - kMaxExpectedBitrate); - // Reduce the capacity and verify the decrease time. - stream_generator_->SetCapacity(500e3); - int64_t bitrate_drop_time = 0; - for (int i = 0; i < 1000; ++i) { - GenerateAndProcessFrame(kSsrc, bitrate_bps); - if (bitrate_observer_->updated()) { - if (bitrate_observer_->latest_bitrate() <= 500e3) { - bitrate_drop_time = stream_generator_->TimeNow(); - } - bitrate_bps = bitrate_observer_->latest_bitrate(); - } - } - EXPECT_EQ(66000, bitrate_drop_time); -} - -// Verify that the time it takes for the estimator to reduce the bitrate when -// the capacity is tightened stays the same. This test also verifies that we -// handle wrap-arounds in this scenario. -TEST_F(RemoteBitrateEstimatorTest, TestCapacityDropRtpTimestampsWrap) { - const unsigned int kSsrc = 0; - const int kFramerate= 30; - const int kStartBitrate = 900e3; - const int kMinExpectedBitrate = 800e3; - const int kMaxExpectedBitrate = 1500e3; - const int kSteadyStateTime = 5; // Seconds. - // Trigger wrap right after the steady state run. - stream_generator_->SetRtpTimestampOffset( - std::numeric_limits::max() - kSteadyStateTime * 90000); - // Run in steady state to make the estimator converge. - unsigned int bitrate_bps = SteadyStateRun(kSsrc, - kSteadyStateTime * kFramerate, - kStartBitrate, - kMinExpectedBitrate, - kMaxExpectedBitrate); - // Reduce the capacity and verify the decrease time. - stream_generator_->SetCapacity(500e3); - int64_t bitrate_drop_time = 0; - for (int i = 0; i < 1000; ++i) { - GenerateAndProcessFrame(kSsrc, bitrate_bps); - if (bitrate_observer_->updated()) { - if (bitrate_observer_->latest_bitrate() <= 500e3) { - bitrate_drop_time = stream_generator_->TimeNow(); - } - bitrate_bps = bitrate_observer_->latest_bitrate(); - } - } - EXPECT_EQ(37356, bitrate_drop_time); -} - -} // namespace webrtc diff --git a/src/modules/remote_bitrate_estimator/remote_rate_control.cc b/src/modules/remote_bitrate_estimator/remote_rate_control.cc deleted file mode 100644 index cb542a47b..000000000 --- a/src/modules/remote_bitrate_estimator/remote_rate_control.cc +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/remote_bitrate_estimator/remote_rate_control.h" - -#include -#include -#include -#if _WIN32 -#include -#endif - -#include "system_wrappers/interface/trace.h" - -#ifdef MATLAB -extern MatlabEngine eng; // global variable defined elsewhere -#endif - -namespace webrtc { -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(0) -#ifdef MATLAB -,_plot1(NULL), -_plot2(NULL) -#endif -{ -} - -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; -} - -bool RemoteRateControl::ValidEstimate() const { - return _initializedBitRate; -} - -WebRtc_Word32 RemoteRateControl::SetConfiguredBitRates( - WebRtc_UWord32 minBitRateBps, WebRtc_UWord32 maxBitRateBps) -{ - if (minBitRateBps > maxBitRateBps) - { - return -1; - } - _minConfiguredBitRate = minBitRateBps; - _maxConfiguredBitRate = maxBitRateBps; - _currentBitRate = BWE_MIN(BWE_MAX(minBitRateBps, _currentBitRate), - maxBitRateBps); - return 0; -} - -WebRtc_UWord32 RemoteRateControl::LatestEstimate() const { - return _currentBitRate; -} - -WebRtc_UWord32 RemoteRateControl::UpdateBandwidthEstimate(WebRtc_Word64 nowMS) -{ - _currentBitRate = ChangeBitRate(_currentBitRate, - _currentInput._incomingBitRate, - _currentInput._noiseVar, - nowMS); - return _currentBitRate; -} - -void RemoteRateControl::SetRtt(unsigned int rtt) { - _rtt = rtt; -} - -RateControlRegion RemoteRateControl::Update(const RateControlInput* input, - WebRtc_Word64 nowMS) -{ - assert(input); -#ifdef MATLAB - // Create plots - if (_plot1 == NULL) - { - _plot1 = eng.NewPlot(new MatlabPlot()); - - _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"); - } - 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 second - if (!_initializedBitRate) - { - if (_timeFirstIncomingEstimate < 0) - { - if (input->_incomingBitRate > 0) - { - _timeFirstIncomingEstimate = nowMS; - } - } - else if (nowMS - _timeFirstIncomingEstimate > 1000 && - 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; -} - -WebRtc_UWord32 RemoteRateControl::ChangeBitRate(WebRtc_UWord32 currentBitRate, - WebRtc_UWord32 incomingBitRate, - double noiseVar, - WebRtc_Word64 nowMS) -{ - if (!_updated) - { - return _currentBitRate; - } - _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 (_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 WebRtc_UWord32 responseTime = static_cast(_avgChangePeriod + 0.5f) + _rtt + 300; - double alpha = RateIncreaseFactor(nowMS, _lastBitRateChange, - responseTime, noiseVar); - - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "BWE: _avgChangePeriod = %f ms; RTT = %u ms", _avgChangePeriod, _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; - } - 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); - - 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 (!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; -} - -double RemoteRateControl::RateIncreaseFactor(WebRtc_Word64 nowMs, WebRtc_Word64 lastMs, WebRtc_UWord32 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 alpha = 1.005 + B / (1 + exp( b * (d * reactionTimeMs - (c1 * noiseVar + c2)))); - - 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 - - if (lastMs > -1) - { - alpha = pow(alpha, (nowMs - lastMs) / 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; - } - - return alpha; -} - -void RemoteRateControl::UpdateChangePeriod(WebRtc_Word64 nowMs) -{ - WebRtc_Word64 changePeriod = 0; - if (_lastChangeMs > -1) - { - changePeriod = nowMs - _lastChangeMs; - } - _lastChangeMs = nowMs; - _avgChangePeriod = 0.9f * _avgChangePeriod + 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::ChangeState(const RateControlInput& input, WebRtc_Word64 nowMs) -{ - switch (_currentInput._bwState) - { - case kBwNormal: - { - if (_rcState == kRcHold) - { - _lastBitRateChange = nowMs; - ChangeState(kRcIncrease); - } - break; - } - case kBwOverusing: - { - if (_rcState != kRcDecrease) - { - ChangeState(kRcDecrease); - } - break; - } - case kBwUnderUsing: - { - ChangeState(kRcHold); - break; - } - } -} - -void RemoteRateControl::ChangeRegion(RateControlRegion region) -{ - _rcRegion = region; - switch (_rcRegion) - { - case kRcAboveMax: - case kRcMaxUnknown: - { - _beta = 0.9f; - break; - } - case kRcNearMax: - { - _beta = 0.95f; - break; - } - } -} - -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::StateStr(RateControlState state, char* str) -{ - switch (state) - { - case kRcDecrease: - strncpy(str, "DECREASE", 9); - break; - case kRcHold: - strncpy(str, "HOLD", 5); - break; - case kRcIncrease: - strncpy(str, "INCREASE", 9); - break; - } -} - -void RemoteRateControl::StateStr(BandwidthUsage state, char* str) -{ - switch (state) - { - case kBwNormal: - strncpy(str, "NORMAL", 7); - break; - case kBwOverusing: - strncpy(str, "OVER USING", 11); - break; - case kBwUnderUsing: - strncpy(str, "UNDER USING", 12); - break; - } -} - -} // namespace webrtc diff --git a/src/modules/remote_bitrate_estimator/remote_rate_control.h b/src/modules/remote_bitrate_estimator/remote_rate_control.h deleted file mode 100644 index 6c9d11658..000000000 --- a/src/modules/remote_bitrate_estimator/remote_rate_control.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_REMOTE_RATE_CONTROL_H_ -#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(); - WebRtc_Word32 SetConfiguredBitRates(WebRtc_UWord32 minBitRate, - WebRtc_UWord32 maxBitRate); - WebRtc_UWord32 LatestEstimate() const; - WebRtc_UWord32 UpdateBandwidthEstimate(WebRtc_Word64 nowMS); - void SetRtt(unsigned int rtt); - RateControlRegion Update(const RateControlInput* input, - WebRtc_Word64 nowMS); - void Reset(); - - // Returns true if there is a valid estimate of the incoming bitrate, false - // otherwise. - bool ValidEstimate() const; - -private: - WebRtc_UWord32 ChangeBitRate(WebRtc_UWord32 currentBitRate, - WebRtc_UWord32 incomingBitRate, - double delayFactor, - WebRtc_Word64 nowMS); - double RateIncreaseFactor(WebRtc_Word64 nowMs, - WebRtc_Word64 lastMs, - WebRtc_UWord32 reactionTimeMs, - double noiseVar) const; - void UpdateChangePeriod(WebRtc_Word64 nowMs); - void UpdateMaxBitRateEstimate(float incomingBitRateKbps); - void ChangeState(const RateControlInput& input, WebRtc_Word64 nowMs); - void ChangeState(RateControlState newState); - void ChangeRegion(RateControlRegion region); - static void StateStr(RateControlState state, char* str); - static void StateStr(BandwidthUsage state, char* str); - - WebRtc_UWord32 _minConfiguredBitRate; - WebRtc_UWord32 _maxConfiguredBitRate; - WebRtc_UWord32 _currentBitRate; - WebRtc_UWord32 _maxHoldRate; - float _avgMaxBitRate; - float _varMaxBitRate; - RateControlState _rcState; - RateControlState _cameFromState; - RateControlRegion _rcRegion; - WebRtc_Word64 _lastBitRateChange; - RateControlInput _currentInput; - bool _updated; - WebRtc_Word64 _timeFirstIncomingEstimate; - bool _initializedBitRate; - - float _avgChangePeriod; - WebRtc_Word64 _lastChangeMs; - float _beta; - unsigned int _rtt; -#ifdef MATLAB - MatlabPlot *_plot1; - MatlabPlot *_plot2; -#endif -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_REMOTE_RATE_CONTROL_H_ diff --git a/src/modules/rtp_rtcp/test/test_bwe/test_bwe.gypi b/src/modules/rtp_rtcp/test/test_bwe/test_bwe.gypi new file mode 100644 index 000000000..d165e7d50 --- /dev/null +++ b/src/modules/rtp_rtcp/test/test_bwe/test_bwe.gypi @@ -0,0 +1,35 @@ +# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +{ + 'targets': [ + { + 'target_name': 'test_bwe', + 'type': 'executable', + 'dependencies': [ + 'rtp_rtcp', + '<(webrtc_root)/../test/test.gyp:test_support_main', + '<(webrtc_root)/../testing/gtest.gyp:gtest', + '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', + ], + 'include_dirs': [ + '../../source', + ], + 'sources': [ + 'unit_test.cc', + '../../source/bitrate.cc', + ], + }, + ], +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/modules/remote_bitrate_estimator/bitrate_estimator_unittest.cc b/src/modules/rtp_rtcp/test/test_bwe/unit_test.cc similarity index 88% rename from src/modules/remote_bitrate_estimator/bitrate_estimator_unittest.cc rename to src/modules/rtp_rtcp/test/test_bwe/unit_test.cc index b42798a09..3adb09977 100644 --- a/src/modules/remote_bitrate_estimator/bitrate_estimator_unittest.cc +++ b/src/modules/rtp_rtcp/test/test_bwe/unit_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -8,14 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ + /* - * This file includes unit tests for the bitrate estimator. + * This file includes unit tests for the bandwidth estimation and management */ #include #include "typedefs.h" -#include "bitrate_estimator.h" +#include "Bitrate.h" namespace { @@ -25,7 +26,7 @@ class BitRateStatsTest : public ::testing::Test { protected: BitRateStatsTest() {}; - BitRateStats bitRate; + BitRateStats bitRate; }; TEST_F(BitRateStatsTest, TestStrictMode) diff --git a/tools/continuous_build/build_internal/masters/master.webrtc/master.cfg b/tools/continuous_build/build_internal/masters/master.webrtc/master.cfg index ea5ddca1b..c033c3f76 100755 --- a/tools/continuous_build/build_internal/masters/master.webrtc/master.cfg +++ b/tools/continuous_build/build_internal/masters/master.webrtc/master.cfg @@ -106,7 +106,7 @@ NORMAL_TESTS = { 'rtp_rtcp_unittests': (True, True, True), 'signal_processing_unittests': (True, True, True), 'system_wrappers_unittests': (True, True, True), - 'remote_bitrate_estimator_unittests': (True, True, True), + 'test_bwe': (True, True, True), 'test_fec': (True, True, True), 'test_support_unittests': (True, True, True), 'udp_transport_unittests': (True, True, True),