diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/webrtc/modules/remote_bitrate_estimator | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) | |
download | qtwebengine-chromium-ab0a50979b9eb4dfa3320eff7e187e41efedf7a9.tar.gz |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/webrtc/modules/remote_bitrate_estimator')
22 files changed, 845 insertions, 641 deletions
diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/OWNERS b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/OWNERS index b705ede2a00..eab2b8e0041 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/OWNERS +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/OWNERS @@ -2,4 +2,8 @@ pwestin@webrtc.org stefan@webrtc.org henrik.lundin@webrtc.org mflodman@webrtc.org -asapersson@webrtc.org
\ No newline at end of file +asapersson@webrtc.org +# These are for the common case of adding or renaming files. If you're doing +# structural changes, please get a review from a reviewer in this file. +per-file *.gyp=* +per-file *.gypi=* diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc new file mode 100644 index 00000000000..6b208e4999d --- /dev/null +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2014 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 "gtest/gtest.h" +#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" +#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.h" +#include "webrtc/test/testsupport/fileutils.h" + +using std::string; + +namespace webrtc { +namespace testing { +namespace bwe { +#if BWE_TEST_LOGGING_COMPILE_TIME_ENABLE +BweTestConfig::EstimatorConfig CreateEstimatorConfig( + int flow_id, bool plot_delay, bool plot_estimate) { + static const AbsoluteSendTimeRemoteBitrateEstimatorFactory factory = + AbsoluteSendTimeRemoteBitrateEstimatorFactory(); + + return BweTestConfig::EstimatorConfig("AST", flow_id, &factory, kAimdControl, + plot_delay, plot_estimate); +} + +BweTestConfig MakeAdaptiveBweTestConfig() { + BweTestConfig result; + result.estimator_configs.push_back(CreateEstimatorConfig(0, true, true)); + return result; +} + +BweTestConfig MakeMultiFlowBweTestConfig(int flow_count) { + BweTestConfig result; + for (int i = 0; i < flow_count; ++i) { + result.estimator_configs.push_back(CreateEstimatorConfig(i, false, true)); + } + return result; +} + +// This test fixture is used to instantiate tests running with adaptive video +// senders. +class BweSimulation : public BweTest, + public ::testing::TestWithParam<BweTestConfig> { + public: + BweSimulation() : BweTest() {} + virtual ~BweSimulation() {} + + virtual void SetUp() { + const BweTestConfig& config = GetParam(); + SetupTestFromConfig(config); + } + + private: + DISALLOW_COPY_AND_ASSIGN(BweSimulation); +}; + +INSTANTIATE_TEST_CASE_P(VideoSendersTest, BweSimulation, + ::testing::Values(MakeAdaptiveBweTestConfig())); + +TEST_P(BweSimulation, SprintUplinkTest) { + VerboseLogging(true); + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + RateCounterFilter counter1(this, "sender_output"); + TraceBasedDeliveryFilter filter(this, "link_capacity"); + RateCounterFilter counter2(this, "receiver_input"); + ASSERT_TRUE(filter.Init(test::ResourcePath("sprint-uplink", "rx"))); + RunFor(60 * 1000); +} + +TEST_P(BweSimulation, Verizon4gDownlinkTest) { + VerboseLogging(true); + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + RateCounterFilter counter1(this, "sender_output"); + TraceBasedDeliveryFilter filter(this, "link_capacity"); + RateCounterFilter counter2(this, "receiver_input"); + ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx"))); + RunFor(22 * 60 * 1000); +} + +TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) { + VerboseLogging(true); + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + ChokeFilter filter(this); + RateCounterFilter counter(this, "receiver_input"); + filter.SetCapacity(1000); + filter.SetMaxDelay(500); + RunFor(60 * 1000); + filter.SetCapacity(500); + RunFor(60 * 1000); + filter.SetCapacity(1000); + RunFor(60 * 1000); +} + +TEST_P(BweSimulation, Choke200kbps30kbps200kbps) { + VerboseLogging(true); + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + ChokeFilter filter(this); + RateCounterFilter counter(this, "receiver_input"); + filter.SetCapacity(200); + filter.SetMaxDelay(500); + RunFor(60 * 1000); + filter.SetCapacity(30); + RunFor(60 * 1000); + filter.SetCapacity(200); + RunFor(60 * 1000); +} + +TEST_P(BweSimulation, GoogleWifiTrace3Mbps) { + VerboseLogging(true); + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + RateCounterFilter counter1(this, "sender_output"); + TraceBasedDeliveryFilter filter(this, "link_capacity"); + filter.SetMaxDelay(500); + RateCounterFilter counter2(this, "receiver_input"); + ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx"))); + RunFor(300 * 1000); +} + +class MultiFlowBweSimulation : public BweSimulation { + public: + MultiFlowBweSimulation() : BweSimulation() {} + virtual ~MultiFlowBweSimulation() {} + + private: + DISALLOW_COPY_AND_ASSIGN(MultiFlowBweSimulation); +}; + +INSTANTIATE_TEST_CASE_P(VideoSendersTest, MultiFlowBweSimulation, + ::testing::Values(MakeMultiFlowBweTestConfig(3))); + +TEST_P(MultiFlowBweSimulation, SelfFairnessTest) { + VerboseLogging(true); + const int kAllFlowIds[] = {0, 1, 2}; + const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]); + scoped_ptr<AdaptiveVideoSender> senders[kNumFlows]; + for (size_t i = 0; i < kNumFlows; ++i) { + senders[i].reset(new AdaptiveVideoSender(kAllFlowIds[i], this, 30, 300, 0, + 0)); + } + // Second and third flow. + ChokeFilter choke(this, CreateFlowIds(&kAllFlowIds[1], 2)); + choke.SetCapacity(1500); + // First flow. + ChokeFilter choke2(this, CreateFlowIds(&kAllFlowIds[0], 1)); + choke2.SetCapacity(1000); + + scoped_ptr<RateCounterFilter> rate_counters[kNumFlows]; + for (size_t i = 0; i < kNumFlows; ++i) { + rate_counters[i].reset(new RateCounterFilter( + this, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input")); + } + RunFor(30 * 60 * 1000); +} +#endif // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE +} // namespace bwe +} // namespace testing +} // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h index 170ec765c1e..e61e903558f 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h @@ -25,6 +25,11 @@ namespace webrtc { class Clock; +enum RateControlType { + kMimdControl, + kAimdControl +}; + // RemoteBitrateObserver is used to signal changes in bitrate estimates for // the incoming streams. class RemoteBitrateObserver { @@ -37,6 +42,27 @@ class RemoteBitrateObserver { virtual ~RemoteBitrateObserver() {} }; +struct ReceiveBandwidthEstimatorStats { + ReceiveBandwidthEstimatorStats() : total_propagation_time_delta_ms(0) {} + + // The "propagation_time_delta" of a frame is defined as (d_arrival - d_sent), + // where d_arrival is the delta of the arrival times of the frame and the + // previous frame, d_sent is the delta of the sent times of the frame and + // the previous frame. The sent time is calculated from the RTP timestamp. + + // |total_propagation_time_delta_ms| is the sum of the propagation_time_deltas + // of all received frames, except that it's is adjusted to 0 when it becomes + // negative. + int total_propagation_time_delta_ms; + // The propagation_time_deltas for the frames arrived in the last + // kProcessIntervalMs using the clock passed to + // RemoteBitrateEstimatorFactory::Create. + std::vector<int> recent_propagation_time_delta_ms; + // The arrival times for the frames arrived in the last kProcessIntervalMs + // using the clock passed to RemoteBitrateEstimatorFactory::Create. + std::vector<int64_t> recent_arrival_time_ms; +}; + class RemoteBitrateEstimator : public CallStatsObserver, public Module { public: virtual ~RemoteBitrateEstimator() {} @@ -45,6 +71,7 @@ class RemoteBitrateEstimator : public CallStatsObserver, public Module { // estimate and the over-use detector. If an over-use is detected the // remote bitrate estimate will be updated. Note that |payload_size| is the // packet size excluding headers. + // Note that |arrival_time_ms| can be of an arbitrary time base. virtual void IncomingPacket(int64_t arrival_time_ms, int payload_size, const RTPHeader& header) = 0; @@ -58,6 +85,9 @@ class RemoteBitrateEstimator : public CallStatsObserver, public Module { virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs, unsigned int* bitrate_bps) const = 0; + // Returns true if the statistics are available. + virtual bool GetStats(ReceiveBandwidthEstimatorStats* output) const = 0; + protected: static const int kProcessIntervalMs = 1000; static const int kStreamTimeOutMs = 2000; @@ -70,6 +100,7 @@ struct RemoteBitrateEstimatorFactory { virtual RemoteBitrateEstimator* Create( RemoteBitrateObserver* observer, Clock* clock, + RateControlType control_type, uint32_t min_bitrate_bps) const; }; @@ -81,6 +112,7 @@ struct AbsoluteSendTimeRemoteBitrateEstimatorFactory virtual RemoteBitrateEstimator* Create( RemoteBitrateObserver* observer, Clock* clock, + RateControlType control_type, uint32_t min_bitrate_bps) const; }; } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h deleted file mode 100644 index 7928abfacbc..00000000000 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h +++ /dev/null @@ -1,43 +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_RTP_TO_NTP_H_ -#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_RTP_TO_NTP_H_ - -#include <list> - -#include "webrtc/typedefs.h" - -namespace webrtc { - -namespace synchronization { - -struct RtcpMeasurement { - RtcpMeasurement(); - RtcpMeasurement(uint32_t ntp_secs, uint32_t ntp_frac, uint32_t timestamp); - uint32_t ntp_secs; - uint32_t ntp_frac; - uint32_t rtp_timestamp; -}; - -typedef std::list<RtcpMeasurement> RtcpList; - -// Converts an RTP timestamp to the NTP domain in milliseconds using two -// (RTP timestamp, NTP timestamp) pairs. -bool RtpToNtpMs(int64_t rtp_timestamp, const RtcpList& rtcp, - int64_t* timestamp_in_ms); - -// Returns 1 there has been a forward wrap around, 0 if there has been no wrap -// around and -1 if there has been a backwards wrap around (i.e. reordering). -int CheckForWrapArounds(uint32_t rtp_timestamp, uint32_t rtcp_rtp_timestamp); -} // namespace synchronization -} // namespace webrtc - -#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_RTP_TO_NTP_H_ diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc index 86f6cb8ee3c..9baaa9c9134 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc @@ -10,19 +10,12 @@ #include <math.h> #include <stdlib.h> // fabsf -#if _WIN32 -#include <windows.h> -#endif #include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h" #include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h" #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" #include "webrtc/system_wrappers/interface/trace.h" -#ifdef WEBRTC_BWE_MATLAB -extern MatlabEngine eng; // global variable defined elsewhere -#endif - enum { kOverUsingTimeThreshold = 100 }; enum { kMinFramePeriodHistoryLength = 60 }; @@ -43,74 +36,20 @@ OveruseDetector::OveruseDetector(const OverUseDetectorOptions& options) prev_offset_(0.0), time_over_using_(-1), over_use_counter_(0), - hypothesis_(kBwNormal), - time_of_last_received_packet_(-1) -#ifdef WEBRTC_BWE_MATLAB - , plots_() -#endif - { + hypothesis_(kBwNormal) { memcpy(E_, options_.initial_e, sizeof(E_)); memcpy(process_noise_, options_.initial_process_noise, sizeof(process_noise_)); } OveruseDetector::~OveruseDetector() { -#ifdef WEBRTC_BWE_MATLAB - if (plots_.plot1_) { - eng.DeletePlot(plots_.plot1_); - plots_.plot1_ = NULL; - } - if (plots_.plot2_) { - eng.DeletePlot(plots_.plot2_); - plots_.plot2_ = NULL; - } - if (plots_.plot3_) { - eng.DeletePlot(plots_.plot3_); - plots_.plot3_ = NULL; - } - if (plots_.plot4_) { - eng.DeletePlot(plots_.plot4_); - plots_.plot4_ = NULL; - } -#endif - ts_delta_hist_.clear(); } void OveruseDetector::Update(uint16_t packet_size, int64_t timestamp_ms, uint32_t timestamp, - const int64_t now_ms) { - time_of_last_received_packet_ = now_ms; -#ifdef WEBRTC_BWE_MATLAB - // Create plots - const int64_t startTimeMs = nowMS; - if (plots_.plot1_ == NULL) { - plots_.plot1_ = eng.NewPlot(new MatlabPlot()); - plots_.plot1_->AddLine(1000, "b.", "scatter"); - } - if (plots_.plot2_ == NULL) { - plots_.plot2_ = eng.NewPlot(new MatlabPlot()); - plots_.plot2_->AddTimeLine(30, "b", "offset", startTimeMs); - plots_.plot2_->AddTimeLine(30, "r--", "limitPos", startTimeMs); - plots_.plot2_->AddTimeLine(30, "k.", "trigger", startTimeMs); - plots_.plot2_->AddTimeLine(30, "ko", "detection", startTimeMs); - // plots_.plot2_->AddTimeLine(30, "g", "slowMean", startTimeMs); - } - if (plots_.plot3_ == NULL) { - plots_.plot3_ = eng.NewPlot(new MatlabPlot()); - plots_.plot3_->AddTimeLine(30, "b", "noiseVar", startTimeMs); - } - if (plots_.plot4_ == NULL) { - plots_.plot4_ = eng.NewPlot(new MatlabPlot()); - // plots_.plot4_->AddTimeLine(60, "b", "p11", startTimeMs); - // plots_.plot4_->AddTimeLine(60, "r", "p12", startTimeMs); - plots_.plot4_->AddTimeLine(60, "g", "p22", startTimeMs); - // plots_.plot4_->AddTimeLine(60, "g--", "p22_hat", startTimeMs); - // plots_.plot4_->AddTimeLine(30, "b.-", "deltaFs", startTimeMs); - } - -#endif + const int64_t arrival_time_ms) { bool new_timestamp = (timestamp != current_frame_.timestamp); if (timestamp_ms >= 0) { if (prev_frame_.timestamp_ms == -1 && current_frame_.timestamp_ms == -1) { @@ -127,8 +66,6 @@ void OveruseDetector::Update(uint16_t packet_size, return; } else if (new_timestamp) { // First packet of a later frame, the previous frame sample is ready. - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "Frame complete at %I64i", - current_frame_.complete_time_ms); if (prev_frame_.complete_time_ms >= 0) { // This is our second frame. int64_t t_delta = 0; double ts_delta = 0; @@ -143,7 +80,7 @@ void OveruseDetector::Update(uint16_t packet_size, } // Accumulate the frame size current_frame_.size += packet_size; - current_frame_.complete_time_ms = now_ms; + current_frame_.complete_time_ms = arrival_time_ms; } BandwidthUsage OveruseDetector::State() const { @@ -168,10 +105,6 @@ void OveruseDetector::SetRateControlRegion(RateControlRegion region) { } } -int64_t OveruseDetector::time_of_last_received_packet() const { - return time_of_last_received_packet_; -} - void OveruseDetector::SwitchTimeBase() { current_frame_.size = 0; current_frame_.complete_time_ms = -1; @@ -249,10 +182,10 @@ void OveruseDetector::UpdateKalman(int64_t t_delta, const double residual = t_ts_delta - slope_*h[0] - offset_; const bool stable_state = - (BWE_MIN(num_of_deltas_, 60) * fabsf(offset_) < threshold_); + (BWE_MIN(num_of_deltas_, 60) * fabs(offset_) < threshold_); // We try to filter out very late frames. For instance periodic key // frames doesn't fit the Gaussian model well. - if (fabsf(residual) < 3 * sqrt(var_noise_)) { + if (fabs(residual) < 3 * sqrt(var_noise_)) { UpdateNoiseEstimate(residual, min_frame_period, stable_state); } else { UpdateNoiseEstimate(3 * sqrt(var_noise_), min_frame_period, stable_state); @@ -279,39 +212,11 @@ void OveruseDetector::UpdateKalman(int64_t t_delta, E_[0][0] * E_[1][1] - E_[0][1] * E_[1][0] >= 0 && E_[0][0] >= 0); -#ifdef WEBRTC_BWE_MATLAB - // plots_.plot4_->Append("p11",E_[0][0]); - // plots_.plot4_->Append("p12",E_[0][1]); - plots_.plot4_->Append("p22", E_[1][1]); - // plots_.plot4_->Append("p22_hat", 0.5*(process_noise_[1] + - // sqrt(process_noise_[1]*(process_noise_[1] + 4*var_noise_)))); - // plots_.plot4_->Append("deltaFs", fsDelta); - plots_.plot4_->Plot(); -#endif slope_ = slope_ + K[0] * residual; prev_offset_ = offset_; offset_ = offset_ + K[1] * residual; Detect(ts_delta); - -#ifdef WEBRTC_BWE_MATLAB - plots_.plot1_->Append("scatter", - static_cast<double>(current_frame_.size) - prev_frame_.size, - static_cast<double>(t_delta - ts_delta)); - plots_.plot1_->MakeTrend("scatter", "slope", slope_, offset_, "k-"); - plots_.plot1_->MakeTrend("scatter", "thresholdPos", - slope_, offset_ + 2 * sqrt(var_noise_), "r-"); - plots_.plot1_->MakeTrend("scatter", "thresholdNeg", - slope_, offset_ - 2 * sqrt(var_noise_), "r-"); - plots_.plot1_->Plot(); - - plots_.plot2_->Append("offset", offset_); - plots_.plot2_->Append("limitPos", threshold_/BWE_MIN(num_of_deltas_, 60)); - plots_.plot2_->Plot(); - - plots_.plot3_->Append("noiseVar", var_noise_); - plots_.plot3_->Plot(); -#endif } double OveruseDetector::UpdateMinFramePeriod(double ts_delta) { @@ -358,7 +263,7 @@ BandwidthUsage OveruseDetector::Detect(double ts_delta) { return kBwNormal; } const double T = BWE_MIN(num_of_deltas_, 60) * offset_; - if (fabsf(T) > threshold_) { + if (fabs(T) > threshold_) { if (offset_ > 0) { if (time_over_using_ == -1) { // Initialize the timer. Assume that we've been @@ -373,38 +278,17 @@ BandwidthUsage OveruseDetector::Detect(double ts_delta) { if (time_over_using_ > kOverUsingTimeThreshold && over_use_counter_ > 1) { if (offset_ >= prev_offset_) { -#ifdef _DEBUG - if (hypothesis_ != kBwOverusing) { - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwOverusing"); - } -#endif time_over_using_ = 0; over_use_counter_ = 0; hypothesis_ = kBwOverusing; -#ifdef WEBRTC_BWE_MATLAB - plots_.plot2_->Append("detection", offset_); // plot it later -#endif } } -#ifdef WEBRTC_BWE_MATLAB - plots_.plot2_->Append("trigger", offset_); // plot it later -#endif } else { -#ifdef _DEBUG - if (hypothesis_ != kBwUnderusing) { - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwUnderUsing"); - } -#endif time_over_using_ = -1; over_use_counter_ = 0; hypothesis_ = kBwUnderusing; } } else { -#ifdef _DEBUG - if (hypothesis_ != kBwNormal) { - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwNormal"); - } -#endif time_over_using_ = -1; over_use_counter_ = 0; hypothesis_ = kBwNormal; diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.h b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.h index 57f4ddf04f7..9c565e45f18 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.h +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.h @@ -16,10 +16,6 @@ #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" #include "webrtc/typedefs.h" -#ifdef WEBRTC_BWE_MATLAB -#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h" -#endif - namespace webrtc { enum RateControlRegion; @@ -32,11 +28,10 @@ class OveruseDetector { void Update(uint16_t packet_size, int64_t timestamp_ms, uint32_t rtp_timestamp, - int64_t now_ms); + int64_t arrival_time_ms); BandwidthUsage State() const; double NoiseVar() const; void SetRateControlRegion(RateControlRegion region); - int64_t time_of_last_received_packet() const; private: struct FrameSample { @@ -52,16 +47,6 @@ class OveruseDetector { int64_t timestamp_ms; }; - struct DebugPlots { -#ifdef WEBRTC_BWE_MATLAB - DebugPlots() : plot1(NULL), plot2(NULL), plot3(NULL), plot4(NULL) {} - MatlabPlot* plot1; - MatlabPlot* plot2; - MatlabPlot* plot3; - MatlabPlot* plot4; -#endif - }; - // Returns true if |timestamp| represent a time which is later than // |prev_timestamp|. static bool InOrderTimestamp(uint32_t timestamp, uint32_t prev_timestamp); @@ -103,10 +88,6 @@ class OveruseDetector { double time_over_using_; uint16_t over_use_counter_; BandwidthUsage hypothesis_; - int64_t time_of_last_received_packet_; -#ifdef WEBRTC_BWE_MATLAB - DebugPlots plots_; -#endif }; } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc index 4a9b4488108..48485ffb551 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc @@ -10,6 +10,8 @@ #include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h" +#include <assert.h> + namespace webrtc { RateStatistics::RateStatistics(uint32_t window_size_ms, float scale) diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.h b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.h index 429669059a2..f97371bd621 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.h +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.h @@ -34,7 +34,7 @@ class RateStatistics { // Counters are kept in buckets (circular buffer), with one bucket // per millisecond. const int num_buckets_; - scoped_array<uint32_t> buckets_; + scoped_ptr<uint32_t[]> buckets_; // Total count recorded in buckets. uint32_t accumulated_count_; diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi index bbd353fcdd4..c2f1b3da475 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi @@ -21,10 +21,66 @@ 'sources': [ 'include/bwe_defines.h', 'include/remote_bitrate_estimator.h', - 'include/rtp_to_ntp.h', 'rate_statistics.cc', 'rate_statistics.h', - 'rtp_to_ntp.cc', + ], # source + }, + { + 'target_name': 'bwe_tools_util', + 'type': 'static_library', + 'dependencies': [ + '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', + 'rtp_rtcp', + ], + 'sources': [ + 'tools/bwe_rtp.cc', + 'tools/bwe_rtp.h', + ], + }, + { + 'target_name': 'bwe_rtp_to_text', + 'type': 'executable', + 'includes': [ + '../rtp_rtcp/source/rtp_rtcp.gypi', + ], + 'dependencies': [ + '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', + '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default', + 'bwe_tools_util', + 'rtp_rtcp', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + 'include', + ], + }, + 'sources': [ + 'tools/rtp_to_text.cc', + '<(webrtc_root)/modules/video_coding/main/test/rtp_file_reader.cc', + '<(webrtc_root)/modules/video_coding/main/test/rtp_file_reader.h', + ], # source + }, + { + 'target_name': 'bwe_rtp_play', + 'type': 'executable', + 'includes': [ + '../rtp_rtcp/source/rtp_rtcp.gypi', + ], + 'dependencies': [ + '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', + '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default', + 'bwe_tools_util', + 'rtp_rtcp', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + 'include', + ], + }, + 'sources': [ + 'tools/bwe_rtp_play.cc', + '<(webrtc_root)/modules/video_coding/main/test/rtp_file_reader.cc', + '<(webrtc_root)/modules/video_coding/main/test/rtp_file_reader.h', ], # source }, ], # targets diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc index a544ee5d034..08422d28b23 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc @@ -16,8 +16,8 @@ #include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h" #include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" +#include "webrtc/system_wrappers/interface/logging.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" -#include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -55,11 +55,31 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator { virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs, unsigned int* bitrate_bps) const OVERRIDE; + virtual bool GetStats( + ReceiveBandwidthEstimatorStats* output) const OVERRIDE; + private: - typedef std::map<unsigned int, OveruseDetector> SsrcOveruseDetectorMap; + // Map from SSRC to over-use detector and last incoming packet time in + // milliseconds, taken from clock_. + typedef std::map<unsigned int, std::pair<OveruseDetector, int64_t> > + SsrcOveruseDetectorMap; + + static OveruseDetector* GetDetector( + const SsrcOveruseDetectorMap::iterator it) { + return &it->second.first; + } + + static int64_t GetPacketTimeMs(const SsrcOveruseDetectorMap::iterator it) { + return it->second.second; + } + + static void SetPacketTimeMs(SsrcOveruseDetectorMap::iterator it, + int64_t time_ms) { + it->second.second = time_ms; + } // Triggers a new estimate calculation. - void UpdateEstimate(int64_t time_now); + void UpdateEstimate(int64_t now_ms); void GetSsrcs(std::vector<unsigned int>* ssrcs) const; @@ -92,6 +112,7 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket( uint32_t ssrc = header.ssrc; uint32_t rtp_timestamp = header.timestamp + header.extension.transmissionTimeOffset; + int64_t now_ms = clock_->TimeInMilliseconds(); CriticalSectionScoped cs(crit_sect_.get()); SsrcOveruseDetectorMap::iterator it = overuse_detectors_.find(ssrc); if (it == overuse_detectors_.end()) { @@ -102,22 +123,23 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket( // automatically cleaned up when we have one RemoteBitrateEstimator per REMB // group. std::pair<SsrcOveruseDetectorMap::iterator, bool> insert_result = - overuse_detectors_.insert(std::make_pair(ssrc, OveruseDetector( - OverUseDetectorOptions()))); + overuse_detectors_.insert(std::make_pair(ssrc, + std::make_pair(OveruseDetector(OverUseDetectorOptions()), now_ms))); it = insert_result.first; } - OveruseDetector* overuse_detector = &it->second; - incoming_bitrate_.Update(payload_size, arrival_time_ms); + SetPacketTimeMs(it, now_ms); + OveruseDetector* overuse_detector = GetDetector(it); + incoming_bitrate_.Update(payload_size, now_ms); const BandwidthUsage prior_state = overuse_detector->State(); overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time_ms); if (overuse_detector->State() == kBwOverusing) { - unsigned int incoming_bitrate = incoming_bitrate_.Rate(arrival_time_ms); + unsigned int incoming_bitrate = incoming_bitrate_.Rate(now_ms); if (prior_state != kBwOverusing || - remote_rate_.TimeToReduceFurther(arrival_time_ms, incoming_bitrate)) { + remote_rate_.TimeToReduceFurther(now_ms, incoming_bitrate)) { // The first overuse should immediately trigger a new estimate. // We also have to update the estimate immediately if we are overusing // and the target bitrate is too high compared to what we are receiving. - UpdateEstimate(arrival_time_ms); + UpdateEstimate(now_ms); } } } @@ -126,8 +148,9 @@ int32_t RemoteBitrateEstimatorSingleStream::Process() { if (TimeUntilNextProcess() > 0) { return 0; } - UpdateEstimate(clock_->TimeInMilliseconds()); - last_process_time_ = clock_->TimeInMilliseconds(); + int64_t now_ms = clock_->TimeInMilliseconds(); + UpdateEstimate(now_ms); + last_process_time_ = now_ms; return 0; } @@ -138,25 +161,24 @@ int32_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() { return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds(); } -void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t time_now) { +void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) { CriticalSectionScoped cs(crit_sect_.get()); BandwidthUsage bw_state = kBwNormal; double sum_noise_var = 0.0; SsrcOveruseDetectorMap::iterator it = overuse_detectors_.begin(); while (it != overuse_detectors_.end()) { - const int64_t time_of_last_received_packet = - it->second.time_of_last_received_packet(); - if (time_of_last_received_packet >= 0 && - time_now - time_of_last_received_packet > kStreamTimeOutMs) { + if (GetPacketTimeMs(it) >= 0 && + now_ms - GetPacketTimeMs(it) > kStreamTimeOutMs) { // This over-use detector hasn't received packets for |kStreamTimeOutMs| // milliseconds and is considered stale. overuse_detectors_.erase(it++); } else { - sum_noise_var += it->second.NoiseVar(); + OveruseDetector* overuse_detector = GetDetector(it); + sum_noise_var += overuse_detector->NoiseVar(); // Make sure that we trigger an over-use if any of the over-use detectors // is detecting over-use. - if (it->second.State() > bw_state) { - bw_state = it->second.State(); + if (overuse_detector->State() > bw_state) { + bw_state = overuse_detector->State(); } ++it; } @@ -169,17 +191,17 @@ void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t time_now) { double mean_noise_var = sum_noise_var / static_cast<double>(overuse_detectors_.size()); const RateControlInput input(bw_state, - incoming_bitrate_.Rate(time_now), + incoming_bitrate_.Rate(now_ms), mean_noise_var); - const RateControlRegion region = remote_rate_.Update(&input, time_now); - unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(time_now); + const RateControlRegion region = remote_rate_.Update(&input, now_ms); + unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(now_ms); if (remote_rate_.ValidEstimate()) { std::vector<unsigned int> ssrcs; GetSsrcs(&ssrcs); observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate); } for (it = overuse_detectors_.begin(); it != overuse_detectors_.end(); ++it) { - it->second.SetRateControlRegion(region); + GetDetector(it)->SetRateControlRegion(region); } } @@ -210,6 +232,12 @@ bool RemoteBitrateEstimatorSingleStream::LatestEstimate( return true; } +bool RemoteBitrateEstimatorSingleStream::GetStats( + ReceiveBandwidthEstimatorStats* output) const { + // Not implemented. + return false; +} + void RemoteBitrateEstimatorSingleStream::GetSsrcs( std::vector<unsigned int>* ssrcs) const { assert(ssrcs); @@ -225,9 +253,9 @@ void RemoteBitrateEstimatorSingleStream::GetSsrcs( RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create( RemoteBitrateObserver* observer, Clock* clock, + RateControlType control_type, uint32_t min_bitrate_bps) const { - WEBRTC_TRACE(kTraceStateInfo, kTraceRemoteBitrateEstimator, -1, - "RemoteBitrateEstimatorFactory: Instantiating."); + LOG(LS_INFO) << "RemoteBitrateEstimatorFactory: Instantiating."; return new RemoteBitrateEstimatorSingleStream(observer, clock, min_bitrate_bps); } @@ -235,9 +263,10 @@ RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create( RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create( RemoteBitrateObserver* observer, Clock* clock, + RateControlType control_type, uint32_t min_bitrate_bps) const { - WEBRTC_TRACE(kTraceStateInfo, kTraceRemoteBitrateEstimator, -1, - "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating."); + LOG(LS_INFO) << "AbsoluteSendTimeRemoteBitrateEstimatorFactory: " + "Instantiating."; return new RemoteBitrateEstimatorSingleStream(observer, clock, min_bitrate_bps); } diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc index a3e44d87ef5..f67c7f34fc0 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc @@ -10,8 +10,8 @@ #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h" -#include "webrtc/system_wrappers/interface/constructor_magic.h" namespace webrtc { @@ -24,6 +24,7 @@ class RemoteBitrateEstimatorSingleTest : public RemoteBitrateEstimatorTest { bitrate_estimator_.reset(RemoteBitrateEstimatorFactory().Create( bitrate_observer_.get(), &clock_, + kMimdControl, kRemoteBitrateEstimatorMinBitrateBps)); } protected: @@ -35,7 +36,7 @@ TEST_F(RemoteBitrateEstimatorSingleTest, InitialBehavior) { } TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseReordering) { - RateIncreaseReorderingTestHelper(); + RateIncreaseReorderingTestHelper(498136); } TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseRtpTimestamps) { diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc index 88ffe061b99..1b38a1ea306 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc @@ -226,7 +226,8 @@ void RemoteBitrateEstimatorTest::IncomingPacket(uint32_t ssrc, header.ssrc = ssrc; header.timestamp = rtp_timestamp; header.extension.absoluteSendTime = absolute_send_time; - bitrate_estimator_->IncomingPacket(arrival_time, payload_size, header); + bitrate_estimator_->IncomingPacket(arrival_time + kArrivalTimeClockOffsetMs, + payload_size, header); } // Generates a frame of packets belonging to a stream at a given bitrate and @@ -245,6 +246,10 @@ bool RemoteBitrateEstimatorTest::GenerateAndProcessFrame(unsigned int ssrc, while (!packets.empty()) { testing::RtpStream::RtpPacket* packet = packets.front(); bitrate_observer_->Reset(); + // The simulated clock should match the time of packet->arrival_time + // since both are used in IncomingPacket(). + clock_.AdvanceTimeMicroseconds(packet->arrival_time - + clock_.TimeInMicroseconds()); IncomingPacket(packet->ssrc, packet->size, (packet->arrival_time + 500) / 1000, @@ -256,8 +261,6 @@ bool RemoteBitrateEstimatorTest::GenerateAndProcessFrame(unsigned int ssrc, overuse = true; EXPECT_LE(bitrate_observer_->latest_bitrate(), bitrate_bps); } - clock_.AdvanceTimeMicroseconds(packet->arrival_time - - clock_.TimeInMicroseconds()); delete packet; packets.pop_front(); } @@ -341,9 +344,14 @@ void RemoteBitrateEstimatorTest::InitialBehaviorTestHelper( EXPECT_TRUE(bitrate_observer_->updated()); bitrate_observer_->Reset(); EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps); + bitrate_estimator_->RemoveStream(kDefaultSsrc); + EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps)); + ASSERT_EQ(0u, ssrcs.size()); + EXPECT_EQ(0u, bitrate_bps); } -void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper() { +void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper( + uint32_t expected_bitrate_bps) { const int kFramerate = 50; // 50 fps to avoid rounding errors. const int kFrameIntervalMs = 1000 / kFramerate; const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate); @@ -364,7 +372,7 @@ void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper() { } bitrate_estimator_->Process(); EXPECT_TRUE(bitrate_observer_->updated()); - EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate()); + EXPECT_EQ(expected_bitrate_bps, bitrate_observer_->latest_bitrate()); for (int i = 0; i < 10; ++i) { clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs); timestamp += 2 * 90 * kFrameIntervalMs; @@ -379,7 +387,7 @@ void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper() { } bitrate_estimator_->Process(); EXPECT_TRUE(bitrate_observer_->updated()); - EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate()); + EXPECT_EQ(expected_bitrate_bps, bitrate_observer_->latest_bitrate()); } // Make sure we initially increase the bitrate as expected. @@ -486,5 +494,21 @@ void RemoteBitrateEstimatorTest::CapacityDropTestHelper( EXPECT_EQ(expected_bitrate_drop_delta, bitrate_drop_time - overuse_start_time); + + // Remove stream one by one. + unsigned int latest_bps = 0; + std::vector<unsigned int> ssrcs; + for (int i = 0; i < number_of_streams; i++) { + EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &latest_bps)); + EXPECT_EQ(number_of_streams - i, static_cast<int>(ssrcs.size())); + EXPECT_EQ(bitrate_bps, latest_bps); + for (int j = i; j < number_of_streams; j++) { + EXPECT_EQ(kDefaultSsrc + j, ssrcs[j - i]); + } + bitrate_estimator_->RemoveStream(kDefaultSsrc + i); + } + EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &latest_bps)); + EXPECT_EQ(0u, ssrcs.size()); + EXPECT_EQ(0u, latest_bps); } } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h index 64830dab70f..1d748c57b9f 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h @@ -16,9 +16,9 @@ #include <utility> #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/system_wrappers/interface/clock.h" -#include "webrtc/system_wrappers/interface/constructor_magic.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" namespace webrtc { @@ -190,7 +190,7 @@ class RemoteBitrateEstimatorTest : public ::testing::Test { unsigned int target_bitrate); void InitialBehaviorTestHelper(unsigned int expected_converge_bitrate); - void RateIncreaseReorderingTestHelper(); + void RateIncreaseReorderingTestHelper(unsigned int expected_bitrate); void RateIncreaseRtpTimestampsTestHelper(); void CapacityDropTestHelper(int number_of_streams, bool wrap_time_stamp, @@ -198,6 +198,7 @@ class RemoteBitrateEstimatorTest : public ::testing::Test { unsigned int expected_bitrate_drop_delta); static const unsigned int kDefaultSsrc; + static const int kArrivalTimeClockOffsetMs = 60000; SimulatedClock clock_; // Time at the receiver. scoped_ptr<testing::TestBitrateObserver> bitrate_observer_; diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc index ed8e5c555ee..67b60848148 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc @@ -8,90 +8,95 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include <sstream> + #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.h" +#include "webrtc/test/testsupport/fileutils.h" +#include "webrtc/test/testsupport/perf_test.h" + +using std::string; namespace webrtc { namespace testing { namespace bwe { +enum Estimator { kAbsSendTime, kTransmissionOffset }; -std::vector<const PacketSenderFactory*> VideoSenderFactories(uint32_t count) { - class VideoPacketSenderFactory : public PacketSenderFactory { - public: - VideoPacketSenderFactory(float fps, uint32_t kbps, uint32_t ssrc, - float frame_offset) - : fps_(fps), - kbps_(kbps), - ssrc_(ssrc), - frame_offset_(frame_offset) { - } - virtual ~VideoPacketSenderFactory() {} - virtual PacketSender* Create() const { - return new VideoSender(NULL, fps_, kbps_, ssrc_, frame_offset_); - } - private: - float fps_; - uint32_t kbps_; - uint32_t ssrc_; - float frame_offset_; - }; - - static const VideoPacketSenderFactory factories[] = { - VideoPacketSenderFactory(30.00f, 150, 0x1234, 0.13f), - VideoPacketSenderFactory(15.00f, 500, 0x2345, 0.16f), - VideoPacketSenderFactory(30.00f, 1200, 0x3456, 0.26f), - VideoPacketSenderFactory(7.49f, 150, 0x4567, 0.05f), - VideoPacketSenderFactory(7.50f, 150, 0x5678, 0.15f), - VideoPacketSenderFactory(7.51f, 150, 0x6789, 0.25f), - VideoPacketSenderFactory(15.02f, 150, 0x7890, 0.27f), - VideoPacketSenderFactory(15.03f, 150, 0x8901, 0.38f), - VideoPacketSenderFactory(30.02f, 150, 0x9012, 0.39f), - VideoPacketSenderFactory(30.03f, 150, 0x0123, 0.52f) - }; - assert(count <= sizeof(factories) / sizeof(factories[0])); - - std::vector<const PacketSenderFactory*> result; - for (uint32_t i = 0; i < count; ++i) { - result.push_back(&factories[i]); - } - return result; -} - -std::vector<BweTestConfig::EstimatorConfig> EstimatorConfigs() { +BweTestConfig::EstimatorConfig EstimatorConfigs(Estimator estimator, + int flow_id) { static const RemoteBitrateEstimatorFactory factories[] = { RemoteBitrateEstimatorFactory(), AbsoluteSendTimeRemoteBitrateEstimatorFactory() }; - - std::vector<BweTestConfig::EstimatorConfig> result; - result.push_back(BweTestConfig::EstimatorConfig("TOF", &factories[0])); - result.push_back(BweTestConfig::EstimatorConfig("AST", &factories[1])); - return result; + switch (estimator) { + case kTransmissionOffset: + return BweTestConfig::EstimatorConfig("TOF", flow_id, &factories[0], + kMimdControl, false, false); + case kAbsSendTime: + return BweTestConfig::EstimatorConfig("AST", flow_id, &factories[1], + kMimdControl, false, false); + } + assert(false); + return BweTestConfig::EstimatorConfig(); } -BweTestConfig MakeBweTestConfig(uint32_t sender_count) { - BweTestConfig result = { - VideoSenderFactories(sender_count), EstimatorConfigs() - }; +struct DefaultBweTestConfig { + BweTestConfig bwe_test_config; + size_t number_of_senders; +}; + +DefaultBweTestConfig MakeBweTestConfig(uint32_t sender_count, + Estimator estimator) { + DefaultBweTestConfig result; + result.bwe_test_config.estimator_configs.push_back( + EstimatorConfigs(estimator, 0)); + result.number_of_senders = sender_count; return result; } -INSTANTIATE_TEST_CASE_P(VideoSendersTest, BweTest, - ::testing::Values(MakeBweTestConfig(1), - MakeBweTestConfig(3))); +class DefaultBweTest : public BweTest, + public ::testing::TestWithParam<DefaultBweTestConfig> { + public: + DefaultBweTest() : packet_senders_() {} + virtual ~DefaultBweTest() {} + + virtual void SetUp() { + const DefaultBweTestConfig& config = GetParam(); + SetupTestFromConfig(config.bwe_test_config); + for (size_t i = 0; i < config.number_of_senders; ++i) { + packet_senders_.push_back(new VideoSender(0, this, 30, 300, 0, 0)); + } + } + + virtual void TearDown() { + while (!packet_senders_.empty()) { + delete packet_senders_.front(); + packet_senders_.pop_front(); + } + } + + protected: + std::list<PacketSender*> packet_senders_; +}; + +INSTANTIATE_TEST_CASE_P(VideoSendersTest, DefaultBweTest, + ::testing::Values(MakeBweTestConfig(1, kAbsSendTime), + MakeBweTestConfig(3, kAbsSendTime), + MakeBweTestConfig(1, kTransmissionOffset), + MakeBweTestConfig(3, kTransmissionOffset))); -TEST_P(BweTest, UnlimitedSpeed) { +TEST_P(DefaultBweTest, UnlimitedSpeed) { VerboseLogging(false); RunFor(10 * 60 * 1000); } -TEST_P(BweTest, SteadyLoss) { +TEST_P(DefaultBweTest, DISABLED_SteadyLoss) { LossFilter loss(this); loss.SetLoss(20.0); RunFor(10 * 60 * 1000); } -TEST_P(BweTest, IncreasingLoss1) { +TEST_P(DefaultBweTest, IncreasingLoss1) { LossFilter loss(this); for (int i = 0; i < 76; ++i) { loss.SetLoss(i); @@ -99,13 +104,13 @@ TEST_P(BweTest, IncreasingLoss1) { } } -TEST_P(BweTest, SteadyDelay) { +TEST_P(DefaultBweTest, SteadyDelay) { DelayFilter delay(this); delay.SetDelay(1000); RunFor(10 * 60 * 1000); } -TEST_P(BweTest, IncreasingDelay1) { +TEST_P(DefaultBweTest, DISABLED_IncreasingDelay1) { DelayFilter delay(this); RunFor(10 * 60 * 1000); for (int i = 0; i < 30 * 2; ++i) { @@ -115,7 +120,7 @@ TEST_P(BweTest, IncreasingDelay1) { RunFor(10 * 60 * 1000); } -TEST_P(BweTest, IncreasingDelay2) { +TEST_P(DefaultBweTest, IncreasingDelay2) { DelayFilter delay(this); RateCounterFilter counter(this); RunFor(1 * 60 * 1000); @@ -127,7 +132,7 @@ TEST_P(BweTest, IncreasingDelay2) { RunFor(10 * 60 * 1000); } -TEST_P(BweTest, JumpyDelay1) { +TEST_P(DefaultBweTest, JumpyDelay1) { DelayFilter delay(this); RunFor(10 * 60 * 1000); for (int i = 1; i < 200; ++i) { @@ -140,14 +145,14 @@ TEST_P(BweTest, JumpyDelay1) { RunFor(10 * 60 * 1000); } -TEST_P(BweTest, SteadyJitter) { +TEST_P(DefaultBweTest, SteadyJitter) { JitterFilter jitter(this); RateCounterFilter counter(this); jitter.SetJitter(20); RunFor(2 * 60 * 1000); } -TEST_P(BweTest, IncreasingJitter1) { +TEST_P(DefaultBweTest, IncreasingJitter1) { JitterFilter jitter(this); for (int i = 0; i < 2 * 60 * 2; ++i) { jitter.SetJitter(i); @@ -156,7 +161,7 @@ TEST_P(BweTest, IncreasingJitter1) { RunFor(10 * 60 * 1000); } -TEST_P(BweTest, IncreasingJitter2) { +TEST_P(DefaultBweTest, IncreasingJitter2) { JitterFilter jitter(this); RunFor(30 * 1000); for (int i = 1; i < 51; ++i) { @@ -167,13 +172,13 @@ TEST_P(BweTest, IncreasingJitter2) { RunFor(10 * 60 * 1000); } -TEST_P(BweTest, SteadyReorder) { +TEST_P(DefaultBweTest, SteadyReorder) { ReorderFilter reorder(this); reorder.SetReorder(20.0); RunFor(10 * 60 * 1000); } -TEST_P(BweTest, IncreasingReorder1) { +TEST_P(DefaultBweTest, IncreasingReorder1) { ReorderFilter reorder(this); for (int i = 0; i < 76; ++i) { reorder.SetReorder(i); @@ -181,13 +186,13 @@ TEST_P(BweTest, IncreasingReorder1) { } } -TEST_P(BweTest, SteadyChoke) { +TEST_P(DefaultBweTest, DISABLED_SteadyChoke) { ChokeFilter choke(this); choke.SetCapacity(140); RunFor(10 * 60 * 1000); } -TEST_P(BweTest, IncreasingChoke1) { +TEST_P(DefaultBweTest, DISABLED_IncreasingChoke1) { ChokeFilter choke(this); for (int i = 1200; i >= 100; i -= 100) { choke.SetCapacity(i); @@ -195,7 +200,7 @@ TEST_P(BweTest, IncreasingChoke1) { } } -TEST_P(BweTest, IncreasingChoke2) { +TEST_P(DefaultBweTest, DISABLED_IncreasingChoke2) { ChokeFilter choke(this); RunFor(60 * 1000); for (int i = 1200; i >= 100; i -= 20) { @@ -204,7 +209,7 @@ TEST_P(BweTest, IncreasingChoke2) { } } -TEST_P(BweTest, Multi1) { +TEST_P(DefaultBweTest, DISABLED_Multi1) { DelayFilter delay(this); ChokeFilter choke(this); RateCounterFilter counter(this); @@ -219,7 +224,7 @@ TEST_P(BweTest, Multi1) { RunFor(5 * 60 * 1000); } -TEST_P(BweTest, Multi2) { +TEST_P(DefaultBweTest, Multi2) { ChokeFilter choke(this); JitterFilter jitter(this); RateCounterFilter counter(this); @@ -227,6 +232,108 @@ TEST_P(BweTest, Multi2) { jitter.SetJitter(120); RunFor(5 * 60 * 1000); } + +// This test fixture is used to instantiate tests running with adaptive video +// senders. +class BweFeedbackTest : public BweTest, + public ::testing::TestWithParam<BweTestConfig> { + public: + BweFeedbackTest() : BweTest() {} + virtual ~BweFeedbackTest() {} + + virtual void SetUp() { + BweTestConfig config; + config.estimator_configs.push_back(EstimatorConfigs(kAbsSendTime, 0)); + SetupTestFromConfig(config); + } + + void PrintResults(double max_throughput_kbps, Stats<double> throughput_kbps, + Stats<double> delay_ms) { + double utilization = throughput_kbps.GetMean() / max_throughput_kbps; + webrtc::test::PrintResult("BwePerformance", + GetTestName(), + "Utilization", + utilization * 100.0, + "%", + false); + std::stringstream ss; + ss << throughput_kbps.GetStdDev() / throughput_kbps.GetMean(); + webrtc::test::PrintResult("BwePerformance", + GetTestName(), + "Utilization var coeff", + ss.str(), + "", + false); + webrtc::test::PrintResult("BwePerformance", + GetTestName(), + "Average delay", + delay_ms.AsString(), + "ms", + false); + } + + private: + DISALLOW_COPY_AND_ASSIGN(BweFeedbackTest); +}; + +TEST_F(BweFeedbackTest, Choke1000kbps500kbps1000kbps) { + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + ChokeFilter filter(this); + RateCounterFilter counter(this, "receiver_input"); + const int kHighCapacityKbps = 1000; + const int kLowCapacityKbps = 500; + filter.SetCapacity(kHighCapacityKbps); + filter.SetMaxDelay(500); + RunFor(60 * 1000); + filter.SetCapacity(kLowCapacityKbps); + RunFor(60 * 1000); + filter.SetCapacity(kHighCapacityKbps); + RunFor(60 * 1000); + PrintResults((2 * kHighCapacityKbps + kLowCapacityKbps) / 3.0, + counter.GetBitrateStats(), filter.GetDelayStats()); +} + +TEST_F(BweFeedbackTest, Choke200kbps30kbps200kbps) { + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + ChokeFilter filter(this); + RateCounterFilter counter(this, "receiver_input"); + const int kHighCapacityKbps = 200; + const int kLowCapacityKbps = 30; + filter.SetCapacity(kHighCapacityKbps); + filter.SetMaxDelay(500); + RunFor(60 * 1000); + filter.SetCapacity(kLowCapacityKbps); + RunFor(60 * 1000); + filter.SetCapacity(kHighCapacityKbps); + RunFor(60 * 1000); + + PrintResults((2 * kHighCapacityKbps + kLowCapacityKbps) / 3.0, + counter.GetBitrateStats(), filter.GetDelayStats()); +} + +TEST_F(BweFeedbackTest, Verizon4gDownlinkTest) { + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + RateCounterFilter counter1(this, "sender_output"); + TraceBasedDeliveryFilter filter(this, "link_capacity"); + RateCounterFilter counter2(this, "receiver_input"); + ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx"))); + RunFor(22 * 60 * 1000); + PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(), + filter.GetDelayStats()); +} + +// webrtc:3277 +TEST_F(BweFeedbackTest, DISABLED_GoogleWifiTrace3Mbps) { + AdaptiveVideoSender sender(0, this, 30, 300, 0, 0); + RateCounterFilter counter1(this, "sender_output"); + TraceBasedDeliveryFilter filter(this, "link_capacity"); + filter.SetMaxDelay(500); + RateCounterFilter counter2(this, "receiver_input"); + ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx"))); + RunFor(300 * 1000); + PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(), + filter.GetDelayStats()); +} } // namespace bwe } // namespace testing } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc index 994abdbee89..dda36a765e9 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc @@ -122,8 +122,6 @@ RateControlRegion RemoteRateControl::Update(const RateControlInput* input, } updated_ = true; current_input_ = *input; - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: Incoming rate = %u kbps", - input->_incomingBitRate/1000); return rate_control_region_; } @@ -158,18 +156,11 @@ uint32_t RemoteRateControl::ChangeBitRate(uint32_t current_bit_rate, ChangeRegion(kRcAboveMax); } } - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, - "BWE: Response time: %f + %i + 10*33\n", - avg_change_period_, rtt_); const uint32_t response_time = static_cast<uint32_t>(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: avg_change_period_ = %f ms; RTT = %u ms", avg_change_period_, - rtt_); - current_bit_rate = static_cast<uint32_t>(current_bit_rate * alpha) + 1000; if (max_hold_rate_ > 0 && beta_ * max_hold_rate_ > current_bit_rate) { current_bit_rate = static_cast<uint32_t>(beta_ * max_hold_rate_); @@ -178,9 +169,6 @@ uint32_t RemoteRateControl::ChangeBitRate(uint32_t current_bit_rate, 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; } @@ -207,10 +195,6 @@ uint32_t RemoteRateControl::ChangeBitRate(uint32_t current_bit_rate, } 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); @@ -251,8 +235,6 @@ double RemoteRateControl::RateIncreaseFactor(int64_t now_ms, alpha = 1.3; } - WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: alpha = %f", alpha); - if (last_ms > -1) { alpha = pow(alpha, (now_ms - last_ms) / 1000.0); } @@ -341,45 +323,5 @@ void RemoteRateControl::ChangeRegion(RateControlRegion region) { 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) { - case kRcDecrease: - strncpy(str, "DECREASE", 9); - break; - case kRcHold: - strncpy(str, "HOLD", 5); - break; - case kRcIncrease: - strncpy(str, "INCREASE", 9); - break; - default: - assert(false); - } -} - -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; - default: - assert(false); - } } } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h index b525834eca1..d02c6d56b50 100644 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h @@ -53,8 +53,6 @@ class RemoteRateControl { 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_; diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp.cc deleted file mode 100644 index 109edae7cc5..00000000000 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp.cc +++ /dev/null @@ -1,119 +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 "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h" - -#include "webrtc/system_wrappers/interface/clock.h" - -#include <assert.h> - -namespace webrtc { - -namespace synchronization { - -RtcpMeasurement::RtcpMeasurement() - : ntp_secs(0), ntp_frac(0), rtp_timestamp(0) {} - -RtcpMeasurement::RtcpMeasurement(uint32_t ntp_secs, uint32_t ntp_frac, - uint32_t timestamp) - : ntp_secs(ntp_secs), ntp_frac(ntp_frac), rtp_timestamp(timestamp) {} - -// Calculates the RTP timestamp frequency from two pairs of NTP and RTP -// timestamps. -bool CalculateFrequency( - int64_t rtcp_ntp_ms1, - uint32_t rtp_timestamp1, - int64_t rtcp_ntp_ms2, - uint32_t rtp_timestamp2, - double* frequency_khz) { - if (rtcp_ntp_ms1 <= rtcp_ntp_ms2) { - return false; - } - *frequency_khz = static_cast<double>(rtp_timestamp1 - rtp_timestamp2) / - static_cast<double>(rtcp_ntp_ms1 - rtcp_ntp_ms2); - return true; -} - -// Detects if there has been a wraparound between |old_timestamp| and -// |new_timestamp|, and compensates by adding 2^32 if that is the case. -bool CompensateForWrapAround(uint32_t new_timestamp, - uint32_t old_timestamp, - int64_t* compensated_timestamp) { - assert(compensated_timestamp); - int64_t wraps = synchronization::CheckForWrapArounds(new_timestamp, - old_timestamp); - if (wraps < 0) { - // Reordering, don't use this packet. - return false; - } - *compensated_timestamp = new_timestamp + (wraps << 32); - return true; -} - -// Converts |rtp_timestamp| to the NTP time base using the NTP and RTP timestamp -// pairs in |rtcp|. The converted timestamp is returned in -// |rtp_timestamp_in_ms|. This function compensates for wrap arounds in RTP -// timestamps and returns false if it can't do the conversion due to reordering. -bool RtpToNtpMs(int64_t rtp_timestamp, - const synchronization::RtcpList& rtcp, - int64_t* rtp_timestamp_in_ms) { - assert(rtcp.size() == 2); - int64_t rtcp_ntp_ms_new = Clock::NtpToMs(rtcp.front().ntp_secs, - rtcp.front().ntp_frac); - int64_t rtcp_ntp_ms_old = Clock::NtpToMs(rtcp.back().ntp_secs, - rtcp.back().ntp_frac); - int64_t rtcp_timestamp_new = rtcp.front().rtp_timestamp; - int64_t rtcp_timestamp_old = rtcp.back().rtp_timestamp; - if (!CompensateForWrapAround(rtcp_timestamp_new, - rtcp_timestamp_old, - &rtcp_timestamp_new)) { - return false; - } - double freq_khz; - if (!CalculateFrequency(rtcp_ntp_ms_new, - rtcp_timestamp_new, - rtcp_ntp_ms_old, - rtcp_timestamp_old, - &freq_khz)) { - return false; - } - double offset = rtcp_timestamp_new - freq_khz * rtcp_ntp_ms_new; - int64_t rtp_timestamp_unwrapped; - if (!CompensateForWrapAround(rtp_timestamp, rtcp_timestamp_old, - &rtp_timestamp_unwrapped)) { - return false; - } - double rtp_timestamp_ntp_ms = (static_cast<double>(rtp_timestamp_unwrapped) - - offset) / freq_khz + 0.5f; - if (rtp_timestamp_ntp_ms < 0) { - return false; - } - *rtp_timestamp_in_ms = rtp_timestamp_ntp_ms; - return true; -} - -int CheckForWrapArounds(uint32_t new_timestamp, uint32_t old_timestamp) { - if (new_timestamp < old_timestamp) { - // This difference should be less than -2^31 if we have had a wrap around - // (e.g. |new_timestamp| = 1, |rtcp_rtp_timestamp| = 2^32 - 1). Since it is - // cast to a int32_t, it should be positive. - if (static_cast<int32_t>(new_timestamp - old_timestamp) > 0) { - // Forward wrap around. - return 1; - } - } else if (static_cast<int32_t>(old_timestamp - new_timestamp) > 0) { - // This difference should be less than -2^31 if we have had a backward wrap - // around. Since it is cast to a int32_t, it should be positive. - return -1; - } - return 0; -} -} // namespace synchronization -} // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp_unittest.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp_unittest.cc deleted file mode 100644 index aff314aaa53..00000000000 --- a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp_unittest.cc +++ /dev/null @@ -1,163 +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 "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h" - -namespace webrtc { - -TEST(WrapAroundTests, NoWrap) { - EXPECT_EQ(0, synchronization::CheckForWrapArounds(0xFFFFFFFF, 0xFFFFFFFE)); - EXPECT_EQ(0, synchronization::CheckForWrapArounds(1, 0)); - EXPECT_EQ(0, synchronization::CheckForWrapArounds(0x00010000, 0x0000FFFF)); -} - -TEST(WrapAroundTests, ForwardWrap) { - EXPECT_EQ(1, synchronization::CheckForWrapArounds(0, 0xFFFFFFFF)); - EXPECT_EQ(1, synchronization::CheckForWrapArounds(0, 0xFFFF0000)); - EXPECT_EQ(1, synchronization::CheckForWrapArounds(0x0000FFFF, 0xFFFFFFFF)); - EXPECT_EQ(1, synchronization::CheckForWrapArounds(0x0000FFFF, 0xFFFF0000)); -} - -TEST(WrapAroundTests, BackwardWrap) { - EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFFFFFF, 0)); - EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFF0000, 0)); - EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFFFFFF, 0x0000FFFF)); - EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFF0000, 0x0000FFFF)); -} - -TEST(WrapAroundTests, OldRtcpWrapped) { - synchronization::RtcpList rtcp; - uint32_t ntp_sec = 0; - uint32_t ntp_frac = 0; - uint32_t timestamp = 0; - const uint32_t kOneMsInNtpFrac = 4294967; - const uint32_t kTimestampTicksPerMs = 90; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp -= kTimestampTicksPerMs; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp -= kTimestampTicksPerMs; - int64_t timestamp_in_ms = -1; - // This expected to fail since it's highly unlikely that the older RTCP - // has a much smaller RTP timestamp than the newer. - EXPECT_FALSE(synchronization::RtpToNtpMs(timestamp, rtcp, ×tamp_in_ms)); -} - -TEST(WrapAroundTests, NewRtcpWrapped) { - synchronization::RtcpList rtcp; - uint32_t ntp_sec = 0; - uint32_t ntp_frac = 0; - uint32_t timestamp = 0xFFFFFFFF; - const uint32_t kOneMsInNtpFrac = 4294967; - const uint32_t kTimestampTicksPerMs = 90; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp += kTimestampTicksPerMs; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - int64_t timestamp_in_ms = -1; - EXPECT_TRUE(synchronization::RtpToNtpMs(rtcp.back().rtp_timestamp, rtcp, - ×tamp_in_ms)); - // Since this RTP packet has the same timestamp as the RTCP packet constructed - // at time 0 it should be mapped to 0 as well. - EXPECT_EQ(0, timestamp_in_ms); -} - -TEST(WrapAroundTests, RtpWrapped) { - const uint32_t kOneMsInNtpFrac = 4294967; - const uint32_t kTimestampTicksPerMs = 90; - synchronization::RtcpList rtcp; - uint32_t ntp_sec = 0; - uint32_t ntp_frac = 0; - uint32_t timestamp = 0xFFFFFFFF - 2 * kTimestampTicksPerMs; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp += kTimestampTicksPerMs; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp += kTimestampTicksPerMs; - int64_t timestamp_in_ms = -1; - EXPECT_TRUE(synchronization::RtpToNtpMs(timestamp, rtcp, - ×tamp_in_ms)); - // Since this RTP packet has the same timestamp as the RTCP packet constructed - // at time 0 it should be mapped to 0 as well. - EXPECT_EQ(2, timestamp_in_ms); -} - -TEST(WrapAroundTests, OldRtp_RtcpsWrapped) { - const uint32_t kOneMsInNtpFrac = 4294967; - const uint32_t kTimestampTicksPerMs = 90; - synchronization::RtcpList rtcp; - uint32_t ntp_sec = 0; - uint32_t ntp_frac = 0; - uint32_t timestamp = 0; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp += kTimestampTicksPerMs; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp -= 2*kTimestampTicksPerMs; - int64_t timestamp_in_ms = -1; - EXPECT_FALSE(synchronization::RtpToNtpMs(timestamp, rtcp, - ×tamp_in_ms)); -} - -TEST(WrapAroundTests, OldRtp_NewRtcpWrapped) { - const uint32_t kOneMsInNtpFrac = 4294967; - const uint32_t kTimestampTicksPerMs = 90; - synchronization::RtcpList rtcp; - uint32_t ntp_sec = 0; - uint32_t ntp_frac = 0; - uint32_t timestamp = 0xFFFFFFFF; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp += kTimestampTicksPerMs; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp -= kTimestampTicksPerMs; - int64_t timestamp_in_ms = -1; - EXPECT_TRUE(synchronization::RtpToNtpMs(timestamp, rtcp, - ×tamp_in_ms)); - // Constructed at the same time as the first RTCP and should therefore be - // mapped to zero. - EXPECT_EQ(0, timestamp_in_ms); -} - -TEST(WrapAroundTests, OldRtp_OldRtcpWrapped) { - const uint32_t kOneMsInNtpFrac = 4294967; - const uint32_t kTimestampTicksPerMs = 90; - synchronization::RtcpList rtcp; - uint32_t ntp_sec = 0; - uint32_t ntp_frac = 0; - uint32_t timestamp = 0; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp -= kTimestampTicksPerMs; - rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac, - timestamp)); - ntp_frac += kOneMsInNtpFrac; - timestamp += 2*kTimestampTicksPerMs; - int64_t timestamp_in_ms = -1; - EXPECT_FALSE(synchronization::RtpToNtpMs(timestamp, rtcp, - ×tamp_in_ms)); -} -}; // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc new file mode 100644 index 00000000000..40fa6df8ffb --- /dev/null +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014 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 "webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h" + +#include <stdio.h> +#include <string> + +#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" +#include "webrtc/modules/video_coding/main/test/rtp_file_reader.h" +#include "webrtc/modules/video_coding/main/test/rtp_player.h" + +using webrtc::rtpplayer::RtpPacketSourceInterface; + +const int kMinBitrateBps = 30000; + +bool ParseArgsAndSetupEstimator(int argc, + char** argv, + webrtc::Clock* clock, + webrtc::RemoteBitrateObserver* observer, + RtpPacketSourceInterface** rtp_reader, + webrtc::RtpHeaderParser** parser, + webrtc::RemoteBitrateEstimator** estimator, + std::string* estimator_used) { + *rtp_reader = webrtc::rtpplayer::CreateRtpFileReader(argv[3]); + if (!*rtp_reader) { + fprintf(stderr, "Cannot open input file %s\n", argv[3]); + return false; + } + fprintf(stderr, "Input file: %s\n\n", argv[3]); + webrtc::RTPExtensionType extension = webrtc::kRtpExtensionAbsoluteSendTime; + + if (strncmp("tsoffset", argv[1], 8) == 0) { + extension = webrtc::kRtpExtensionTransmissionTimeOffset; + fprintf(stderr, "Extension: toffset\n"); + } else { + fprintf(stderr, "Extension: abs\n"); + } + int id = atoi(argv[2]); + + // Setup the RTP header parser and the bitrate estimator. + *parser = webrtc::RtpHeaderParser::Create(); + (*parser)->RegisterRtpHeaderExtension(extension, id); + if (estimator) { + switch (extension) { + case webrtc::kRtpExtensionAbsoluteSendTime: { + webrtc::AbsoluteSendTimeRemoteBitrateEstimatorFactory factory; + *estimator = factory.Create(observer, clock, webrtc::kAimdControl, + kMinBitrateBps); + *estimator_used = "AbsoluteSendTimeRemoteBitrateEstimator"; + break; + } + case webrtc::kRtpExtensionTransmissionTimeOffset: { + webrtc::RemoteBitrateEstimatorFactory factory; + *estimator = factory.Create(observer, clock, webrtc::kAimdControl, + kMinBitrateBps); + *estimator_used = "RemoteBitrateEstimator"; + break; + } + default: + assert(false); + } + } + return true; +} diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h new file mode 100644 index 00000000000..714457d5668 --- /dev/null +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 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_TOOLS_BWE_RTP_H_ +#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TOOLS_BWE_RTP_H_ + +#include <string> + +namespace webrtc { +class Clock; +class RemoteBitrateEstimator; +class RemoteBitrateObserver; +class RtpHeaderParser; +namespace rtpplayer { +class RtpPacketSourceInterface; +} +} + +bool ParseArgsAndSetupEstimator( + int argc, + char** argv, + webrtc::Clock* clock, + webrtc::RemoteBitrateObserver* observer, + webrtc::rtpplayer::RtpPacketSourceInterface** rtp_reader, + webrtc::RtpHeaderParser** parser, + webrtc::RemoteBitrateEstimator** estimator, + std::string* estimator_used); + +#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TOOLS_BWE_RTP_H_ diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp_play.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp_play.cc new file mode 100644 index 00000000000..9ea3f08eab5 --- /dev/null +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp_play.cc @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014 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 <stdio.h> + +#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" +#include "webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" +#include "webrtc/modules/video_coding/main/test/rtp_file_reader.h" +#include "webrtc/modules/video_coding/main/test/rtp_player.h" +#include "webrtc/system_wrappers/interface/scoped_ptr.h" + +using webrtc::rtpplayer::RtpPacketSourceInterface; + +class Observer : public webrtc::RemoteBitrateObserver { + public: + explicit Observer(webrtc::Clock* clock) : clock_(clock) {} + + // Called when a receive channel group has a new bitrate estimate for the + // incoming streams. + virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs, + unsigned int bitrate) { + printf("[%u] Num SSRCs: %d, bitrate: %u\n", + static_cast<uint32_t>(clock_->TimeInMilliseconds()), + static_cast<int>(ssrcs.size()), bitrate); + } + + virtual ~Observer() {} + + private: + webrtc::Clock* clock_; +}; + +int main(int argc, char** argv) { + if (argc < 4) { + printf("Usage: bwe_rtp_play <extension type> <extension id> " + "<input_file.rtp>\n"); + printf("<extension type> can either be:\n" + " abs for absolute send time or\n" + " tsoffset for timestamp offset.\n" + "<extension id> is the id associated with the extension.\n"); + return -1; + } + RtpPacketSourceInterface* reader; + webrtc::RemoteBitrateEstimator* estimator; + webrtc::RtpHeaderParser* parser; + std::string estimator_used; + webrtc::SimulatedClock clock(0); + Observer observer(&clock); + if (!ParseArgsAndSetupEstimator(argc, argv, &clock, &observer, &reader, + &parser, &estimator, &estimator_used)) { + return -1; + } + webrtc::scoped_ptr<RtpPacketSourceInterface> rtp_reader(reader); + webrtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_parser(parser); + webrtc::scoped_ptr<webrtc::RemoteBitrateEstimator> rbe(estimator); + + // Process the file. + int packet_counter = 0; + int64_t next_process_time_ms = 0; + int64_t next_rtp_time_ms = 0; + int64_t first_rtp_time_ms = -1; + const uint32_t kMaxPacketSize = 1500; + uint8_t packet_buffer[kMaxPacketSize]; + uint8_t* packet = packet_buffer; + int non_zero_abs_send_time = 0; + int non_zero_ts_offsets = 0; + while (true) { + uint32_t next_rtp_time; + if (next_rtp_time_ms <= clock.TimeInMilliseconds()) { + uint32_t packet_length = kMaxPacketSize; + if (rtp_reader->NextPacket(packet, &packet_length, + &next_rtp_time) == -1) { + break; + } + if (first_rtp_time_ms == -1) + first_rtp_time_ms = next_rtp_time; + next_rtp_time_ms = next_rtp_time - first_rtp_time_ms; + webrtc::RTPHeader header; + parser->Parse(packet, packet_length, &header); + if (header.extension.absoluteSendTime != 0) + ++non_zero_abs_send_time; + if (header.extension.transmissionTimeOffset != 0) + ++non_zero_ts_offsets; + rbe->IncomingPacket(clock.TimeInMilliseconds(), + packet_length - header.headerLength, + header); + ++packet_counter; + } + next_process_time_ms = rbe->TimeUntilNextProcess() + + clock.TimeInMilliseconds(); + if (next_process_time_ms <= clock.TimeInMilliseconds()) { + rbe->Process(); + } + int time_until_next_event = + std::min(next_process_time_ms, next_rtp_time_ms) - + clock.TimeInMilliseconds(); + clock.AdvanceTimeMilliseconds(std::max(time_until_next_event, 0)); + } + printf("Parsed %d packets\nTime passed: %u ms\n", packet_counter, + static_cast<uint32_t>(clock.TimeInMilliseconds())); + printf("Estimator used: %s\n", estimator_used.c_str()); + printf("Packets with non-zero absolute send time: %d\n", + non_zero_abs_send_time); + printf("Packets with non-zero timestamp offset: %d\n", + non_zero_ts_offsets); + return 0; +} diff --git a/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/rtp_to_text.cc b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/rtp_to_text.cc new file mode 100644 index 00000000000..af4a4d4ee7b --- /dev/null +++ b/chromium/third_party/webrtc/modules/remote_bitrate_estimator/tools/rtp_to_text.cc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014 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 <stdio.h> +#include <sstream> + +#include "webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" +#include "webrtc/modules/video_coding/main/test/rtp_file_reader.h" +#include "webrtc/modules/video_coding/main/test/rtp_player.h" +#include "webrtc/system_wrappers/interface/scoped_ptr.h" + +using webrtc::rtpplayer::RtpPacketSourceInterface; + +int main(int argc, char** argv) { + if (argc < 4) { + fprintf(stderr, "Usage: rtp_to_text <extension type> <extension id>" + " <input_file.rtp> [-t]\n"); + fprintf(stderr, "<extension type> can either be:\n" + " abs for absolute send time or\n" + " tsoffset for timestamp offset.\n" + "<extension id> is the id associated with the extension.\n" + " -t is an optional flag, if set only packet arrival time will be" + " output.\n"); + return -1; + } + RtpPacketSourceInterface* reader; + webrtc::RtpHeaderParser* parser; + if (!ParseArgsAndSetupEstimator(argc, argv, NULL, NULL, &reader, &parser, + NULL, NULL)) { + return -1; + } + bool arrival_time_only = (argc >= 5 && strncmp(argv[4], "-t", 2) == 0); + webrtc::scoped_ptr<RtpPacketSourceInterface> rtp_reader(reader); + webrtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_parser(parser); + fprintf(stdout, "seqnum timestamp ts_offset abs_sendtime recvtime " + "markerbit ssrc size\n"); + int packet_counter = 0; + static const uint32_t kMaxPacketSize = 1500; + uint8_t packet_buffer[kMaxPacketSize]; + uint8_t* packet = packet_buffer; + uint32_t packet_length = kMaxPacketSize; + uint32_t time_ms = 0; + int non_zero_abs_send_time = 0; + int non_zero_ts_offsets = 0; + while (rtp_reader->NextPacket(packet, &packet_length, &time_ms) == 0) { + webrtc::RTPHeader header; + parser->Parse(packet, packet_length, &header); + if (header.extension.absoluteSendTime != 0) + ++non_zero_abs_send_time; + if (header.extension.transmissionTimeOffset != 0) + ++non_zero_ts_offsets; + if (arrival_time_only) { + std::stringstream ss; + ss << static_cast<int64_t>(time_ms) * 1000000; + fprintf(stdout, "%s\n", ss.str().c_str()); + } else { + fprintf(stdout, "%u %u %d %u %u %d %u %u\n", header.sequenceNumber, + header.timestamp, header.extension.transmissionTimeOffset, + header.extension.absoluteSendTime, time_ms, header.markerBit, + header.ssrc, packet_length); + } + packet_length = kMaxPacketSize; + ++packet_counter; + } + fprintf(stderr, "Parsed %d packets\n", packet_counter); + fprintf(stderr, "Packets with non-zero absolute send time: %d\n", + non_zero_abs_send_time); + fprintf(stderr, "Packets with non-zero timestamp offset: %d\n", + non_zero_ts_offsets); + return 0; +} |