From 4fbd145dcefd23169a9b1612d5ca92dace8196d6 Mon Sep 17 00:00:00 2001 From: stefan Date: Mon, 28 Sep 2015 03:57:14 -0700 Subject: [PATCH] Fix suspend below min bitrate in new API by making it possible to set min bitrate at the receive-side. In addition to this the ramp-up tests are refactored to use a receive call instead of only a remote bitrate estimator, and to make use of BaseTest. BUG=webrtc:4836 Review URL: https://codereview.webrtc.org/1368943002 Cr-Commit-Position: refs/heads/master@{#10087} --- webrtc/call/call.cc | 21 +- .../aimd_rate_control.cc | 15 +- .../aimd_rate_control.h | 6 +- .../mock/mock_remote_bitrate_estimator.h | 1 + .../include/remote_bitrate_estimator.h | 2 + .../remote_bitrate_estimator_abs_send_time.cc | 9 +- .../remote_bitrate_estimator_abs_send_time.h | 4 +- ...itrate_estimator_abs_send_time_unittest.cc | 4 +- .../remote_bitrate_estimator_single_stream.cc | 12 +- .../remote_bitrate_estimator_single_stream.h | 4 +- ...itrate_estimator_single_stream_unittest.cc | 4 +- .../remote_estimator_proxy.cc | 2 - .../remote_estimator_proxy.h | 3 +- .../test/estimators/remb.cc | 6 +- .../test/estimators/send_side.cc | 5 +- .../remote_bitrate_estimator/tools/bwe_rtp.cc | 10 +- .../transport_feedback_adapter.h | 4 + .../source/rtcp_format_remb_unittest.cc | 9 +- .../rtp_rtcp/source/rtcp_receiver_unittest.cc | 9 +- webrtc/test/rtp_rtcp_observer.h | 2 +- webrtc/video/rampup_tests.cc | 747 +++++++----------- webrtc/video/rampup_tests.h | 178 ++--- webrtc/video_engine/vie_channel_group.cc | 45 +- webrtc/video_engine/vie_channel_group.h | 4 + 24 files changed, 461 insertions(+), 645 deletions(-) diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc index 21109c21f5..2c80ccff0d 100644 --- a/webrtc/call/call.cc +++ b/webrtc/call/call.cc @@ -85,9 +85,6 @@ class Call : public webrtc::Call, public PacketReceiver { size_t length, const PacketTime& packet_time); - void SetBitrateControllerConfig( - const webrtc::Call::Config::BitrateConfig& bitrate_config); - void ConfigureSync(const std::string& sync_group) EXCLUSIVE_LOCKS_REQUIRED(receive_crit_); @@ -159,7 +156,9 @@ Call::Call(const Call::Config& config) Trace::CreateTrace(); module_process_thread_->Start(); - SetBitrateControllerConfig(config_.bitrate_config); + channel_group_->SetBweBitrates(config_.bitrate_config.min_bitrate_bps, + config_.bitrate_config.start_bitrate_bps, + config_.bitrate_config.max_bitrate_bps); } Call::~Call() { @@ -387,17 +386,9 @@ void Call::SetBitrateConfig( return; } config_.bitrate_config = bitrate_config; - SetBitrateControllerConfig(bitrate_config); -} - -void Call::SetBitrateControllerConfig( - const webrtc::Call::Config::BitrateConfig& bitrate_config) { - BitrateController* bitrate_controller = - channel_group_->GetBitrateController(); - if (bitrate_config.start_bitrate_bps > 0) - bitrate_controller->SetStartBitrate(bitrate_config.start_bitrate_bps); - bitrate_controller->SetMinMaxBitrate(bitrate_config.min_bitrate_bps, - bitrate_config.max_bitrate_bps); + channel_group_->SetBweBitrates(bitrate_config.min_bitrate_bps, + bitrate_config.start_bitrate_bps, + bitrate_config.max_bitrate_bps); } void Call::SignalNetworkState(NetworkState state) { diff --git a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc index 6771c454dd..2d5573228d 100644 --- a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc +++ b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc @@ -15,7 +15,9 @@ #include #include "webrtc/base/checks.h" + #include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h" +#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" namespace webrtc { @@ -25,8 +27,9 @@ static const int64_t kLogIntervalMs = 1000; static const double kWithinIncomingBitrateHysteresis = 1.05; static const int64_t kMaxFeedbackIntervalMs = 1000; -AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps) - : min_configured_bitrate_bps_(min_bitrate_bps), +AimdRateControl::AimdRateControl() + : min_configured_bitrate_bps_( + RemoteBitrateEstimator::kDefaultMinBitrateBps), max_configured_bitrate_bps_(30000000), current_bitrate_bps_(max_configured_bitrate_bps_), avg_max_bitrate_kbps_(-1.0f), @@ -41,11 +44,11 @@ AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps) beta_(0.85f), rtt_(kDefaultRttMs), time_of_last_log_(-1), - in_experiment_(AdaptiveThresholdExperimentIsEnabled()) { -} + in_experiment_(AdaptiveThresholdExperimentIsEnabled()) {} -uint32_t AimdRateControl::GetMinBitrate() const { - return min_configured_bitrate_bps_; +void AimdRateControl::SetMinBitrate(int min_bitrate_bps) { + min_configured_bitrate_bps_ = min_bitrate_bps; + current_bitrate_bps_ = std::max(min_bitrate_bps, current_bitrate_bps_); } bool AimdRateControl::ValidEstimate() const { diff --git a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h index 696b7806f1..bc5ca41dff 100644 --- a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h +++ b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h @@ -23,13 +23,13 @@ namespace webrtc { // multiplicatively. class AimdRateControl { public: - explicit AimdRateControl(uint32_t min_bitrate_bps); + AimdRateControl(); virtual ~AimdRateControl() {} // Returns true if there is a valid estimate of the incoming bitrate, false // otherwise. bool ValidEstimate() const; - uint32_t GetMinBitrate() const; + void SetMinBitrate(int min_bitrate_bps); int64_t GetFeedbackInterval() const; // Returns true if the bitrate estimate hasn't been changed for more than // an RTT, or if the incoming_bitrate is more than 5% above the current @@ -81,8 +81,6 @@ class AimdRateControl { int64_t rtt_; int64_t time_of_last_log_; bool in_experiment_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AimdRateControl); }; } // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h b/webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h index 7890fb72aa..91a8ac8707 100644 --- a/webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h +++ b/webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h @@ -34,6 +34,7 @@ class MockRemoteBitrateEstimator : public RemoteBitrateEstimator { // From Module. MOCK_METHOD0(TimeUntilNextProcess, int64_t()); MOCK_METHOD0(Process, int32_t()); + MOCK_METHOD1(SetMinBitrate, void(int)); }; } // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h b/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h index f201aeb188..4bd9d8c7bc 100644 --- a/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h +++ b/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h @@ -91,6 +91,8 @@ class RemoteBitrateEstimator : public CallStatsObserver, public Module { // Returns true if the statistics are available. virtual bool GetStats(ReceiveBandwidthEstimatorStats* output) const = 0; + virtual void SetMinBitrate(int min_bitrate_bps) = 0; + protected: static const int64_t kProcessIntervalMs = 500; static const int64_t kStreamTimeOutMs = 2000; diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc index 46dc2305a9..56a309c59d 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc @@ -89,8 +89,7 @@ bool RemoteBitrateEstimatorAbsSendTime::IsWithinClusterBounds( RemoteBitrateEstimatorAbsSendTime::RemoteBitrateEstimatorAbsSendTime( RemoteBitrateObserver* observer, - Clock* clock, - uint32_t min_bitrate_bps) + Clock* clock) : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), observer_(observer), clock_(clock), @@ -99,7 +98,6 @@ bool RemoteBitrateEstimatorAbsSendTime::IsWithinClusterBounds( estimator_(OverUseDetectorOptions()), detector_(OverUseDetectorOptions()), incoming_bitrate_(kBitrateWindowMs, 8000), - remote_rate_(min_bitrate_bps), last_process_time_(-1), process_interval_ms_(kProcessIntervalMs), total_propagation_delta_ms_(0), @@ -437,4 +435,9 @@ void RemoteBitrateEstimatorAbsSendTime::UpdateStats(int propagation_delta_ms, total_propagation_delta_ms_ = std::max(total_propagation_delta_ms_ + propagation_delta_ms, 0); } + +void RemoteBitrateEstimatorAbsSendTime::SetMinBitrate(int min_bitrate_bps) { + CriticalSectionScoped cs(crit_sect_.get()); + remote_rate_.SetMinBitrate(min_bitrate_bps); +} } // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h index a7086f372c..b5ec81568a 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h @@ -66,8 +66,7 @@ struct Cluster { class RemoteBitrateEstimatorAbsSendTime : public RemoteBitrateEstimator { public: RemoteBitrateEstimatorAbsSendTime(RemoteBitrateObserver* observer, - Clock* clock, - uint32_t min_bitrate_bps); + Clock* clock); virtual ~RemoteBitrateEstimatorAbsSendTime() {} void IncomingPacketFeedbackVector( @@ -88,6 +87,7 @@ class RemoteBitrateEstimatorAbsSendTime : public RemoteBitrateEstimator { bool LatestEstimate(std::vector* ssrcs, unsigned int* bitrate_bps) const override; bool GetStats(ReceiveBandwidthEstimatorStats* output) const override; + void SetMinBitrate(int min_bitrate_bps) override; private: typedef std::map Ssrcs; diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc index 692f882466..195c95aacb 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc @@ -17,13 +17,11 @@ namespace webrtc { class RemoteBitrateEstimatorAbsSendTimeTest : public RemoteBitrateEstimatorTest { public: - static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; RemoteBitrateEstimatorAbsSendTimeTest() {} virtual void SetUp() { bitrate_estimator_.reset(new RemoteBitrateEstimatorAbsSendTime( - bitrate_observer_.get(), &clock_, - kRemoteBitrateEstimatorMinBitrateBps)); + bitrate_observer_.get(), &clock_)); } protected: RTC_DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorAbsSendTimeTest); diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc index 6fd54e97f9..08e076e540 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc @@ -44,11 +44,10 @@ struct RemoteBitrateEstimatorSingleStream::Detector { RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream( RemoteBitrateObserver* observer, - Clock* clock, - uint32_t min_bitrate_bps) + Clock* clock) : clock_(clock), incoming_bitrate_(kBitrateWindowMs, 8000), - remote_rate_(new AimdRateControl(min_bitrate_bps)), + remote_rate_(new AimdRateControl()), observer_(observer), crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), last_process_time_(-1), @@ -164,7 +163,7 @@ void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) { } // We can't update the estimate if we don't have any active streams. if (overuse_detectors_.empty()) { - remote_rate_.reset(new AimdRateControl(remote_rate_->GetMinBitrate())); + remote_rate_.reset(new AimdRateControl()); return; } double mean_noise_var = sum_var_noise / @@ -230,4 +229,9 @@ void RemoteBitrateEstimatorSingleStream::GetSsrcs( } } +void RemoteBitrateEstimatorSingleStream::SetMinBitrate(int min_bitrate_bps) { + CriticalSectionScoped cs(crit_sect_.get()); + remote_rate_->SetMinBitrate(min_bitrate_bps); +} + } // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h index 6d07ad164c..2816f8d97d 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h @@ -24,8 +24,7 @@ namespace webrtc { class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator { public: RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer, - Clock* clock, - uint32_t min_bitrate_bps); + Clock* clock); virtual ~RemoteBitrateEstimatorSingleStream(); void IncomingPacket(int64_t arrival_time_ms, @@ -39,6 +38,7 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator { bool LatestEstimate(std::vector* ssrcs, unsigned int* bitrate_bps) const override; bool GetStats(ReceiveBandwidthEstimatorStats* output) const override; + void SetMinBitrate(int min_bitrate_bps) override; private: struct Detector; diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc index b0d0fe78db..a6c182a7bc 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc @@ -17,13 +17,11 @@ namespace webrtc { class RemoteBitrateEstimatorSingleTest : public RemoteBitrateEstimatorTest { public: - static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; RemoteBitrateEstimatorSingleTest() {} virtual void SetUp() { bitrate_estimator_.reset(new RemoteBitrateEstimatorSingleStream( - bitrate_observer_.get(), &clock_, - kRemoteBitrateEstimatorMinBitrateBps)); + bitrate_observer_.get(), &clock_)); } protected: RTC_DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorSingleTest); diff --git a/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc b/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc index e91f1c04d4..73b7b15fa4 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc @@ -63,8 +63,6 @@ bool RemoteEstimatorProxy::GetStats( return false; } -void RemoteEstimatorProxy::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { -} int64_t RemoteEstimatorProxy::TimeUntilNextProcess() { int64_t now = clock_->TimeInMilliseconds(); diff --git a/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h b/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h index 6d7390ec2e..e867ff77a4 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h +++ b/webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h @@ -45,7 +45,8 @@ class RemoteEstimatorProxy : public RemoteBitrateEstimator { bool LatestEstimate(std::vector* ssrcs, unsigned int* bitrate_bps) const override; bool GetStats(ReceiveBandwidthEstimatorStats* output) const override; - void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override; + void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override {} + void SetMinBitrate(int min_bitrate_bps) override {} int64_t TimeUntilNextProcess() override; int32_t Process() override; diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc index 8ec2b728db..b18b9f06b9 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/remb.cc @@ -69,15 +69,13 @@ RembReceiver::RembReceiver(int flow_id, bool plot) recv_stats_(ReceiveStatistics::Create(&clock_)), latest_estimate_bps_(-1), last_feedback_ms_(-1), - estimator_(new RemoteBitrateEstimatorAbsSendTime( - this, - &clock_, - kRemoteBitrateEstimatorMinBitrateBps)) { + estimator_(new RemoteBitrateEstimatorAbsSendTime(this, &clock_)) { std::stringstream ss; ss << "Estimate_" << flow_id_ << "#1"; estimate_log_prefix_ = ss.str(); // Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic. estimator_->OnRttUpdate(50, 50); + estimator_->SetMinBitrate(kRemoteBitrateEstimatorMinBitrateBps); } RembReceiver::~RembReceiver() { diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc index 37b604dfe9..250d0c1262 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc @@ -23,9 +23,7 @@ const int kFeedbackIntervalMs = 50; FullBweSender::FullBweSender(int kbps, BitrateObserver* observer, Clock* clock) : bitrate_controller_( BitrateController::CreateBitrateController(clock, observer)), - rbe_(new RemoteBitrateEstimatorAbsSendTime(this, - clock, - 1000 * kMinBitrateKbps)), + rbe_(new RemoteBitrateEstimatorAbsSendTime(this, clock)), feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()), clock_(clock), send_time_history_(10000), @@ -36,6 +34,7 @@ FullBweSender::FullBweSender(int kbps, BitrateObserver* observer, Clock* clock) bitrate_controller_->SetStartBitrate(1000 * kbps); bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps, 1000 * kMaxBitrateKbps); + rbe_->SetMinBitrate(1000 * kMinBitrateKbps); } FullBweSender::~FullBweSender() { diff --git a/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc index 7728873db8..9493805a1c 100644 --- a/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc +++ b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc @@ -21,8 +21,6 @@ #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" #include "webrtc/test/rtp_file_reader.h" -const int kMinBitrateBps = 30000; - namespace flags { DEFINE_string(extension_type, @@ -116,14 +114,14 @@ bool ParseArgsAndSetupEstimator(int argc, if (estimator) { switch (extension) { case webrtc::kRtpExtensionAbsoluteSendTime: { - *estimator = new webrtc::RemoteBitrateEstimatorAbsSendTime( - observer, clock, kMinBitrateBps); + *estimator = + new webrtc::RemoteBitrateEstimatorAbsSendTime(observer, clock); *estimator_used = "AbsoluteSendTimeRemoteBitrateEstimator"; break; } case webrtc::kRtpExtensionTransmissionTimeOffset: { - *estimator = new webrtc::RemoteBitrateEstimatorSingleStream( - observer, clock, kMinBitrateBps); + *estimator = + new webrtc::RemoteBitrateEstimatorSingleStream(observer, clock); *estimator_used = "RemoteBitrateEstimator"; break; } diff --git a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h index 2969c29046..56b2c73873 100644 --- a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h +++ b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h @@ -39,6 +39,10 @@ class TransportFeedbackAdapter : public TransportFeedbackObserver, void SetBitrateEstimator(RemoteBitrateEstimator* rbe); + RemoteBitrateEstimator* GetBitrateEstimator() const { + return bitrate_estimator_.get(); + } + private: void OnReceiveBitrateChanged(const std::vector& ssrcs, unsigned int bitrate) override; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc index eb6d35ed3e..ad7d66b76f 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc @@ -55,8 +55,6 @@ class TestTransport : public Transport { class RtcpFormatRembTest : public ::testing::Test { protected: - static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; - RtcpFormatRembTest() : over_use_detector_options_(), system_clock_(Clock::GetRealTimeClock()), @@ -66,10 +64,9 @@ class RtcpFormatRembTest : public ::testing::Test { rtcp_receiver_(nullptr), test_transport_(nullptr), remote_bitrate_observer_(), - remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream( - &remote_bitrate_observer_, - system_clock_, - kRemoteBitrateEstimatorMinBitrateBps)) {} + remote_bitrate_estimator_( + new RemoteBitrateEstimatorSingleStream(&remote_bitrate_observer_, + system_clock_)) {} void SetUp() override; void TearDown() override; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index e09c29d72c..2e99009b59 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -58,16 +58,13 @@ class TestTransport : public Transport, class RtcpReceiverTest : public ::testing::Test { protected: - static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; - RtcpReceiverTest() : over_use_detector_options_(), system_clock_(1335900000), remote_bitrate_observer_(), - remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream( - &remote_bitrate_observer_, - &system_clock_, - kRemoteBitrateEstimatorMinBitrateBps)) { + remote_bitrate_estimator_( + new RemoteBitrateEstimatorSingleStream(&remote_bitrate_observer_, + &system_clock_)) { test_transport_ = new TestTransport(); RtpRtcp::Configuration configuration; diff --git a/webrtc/test/rtp_rtcp_observer.h b/webrtc/test/rtp_rtcp_observer.h index 8e88716144..38e2fa7e47 100644 --- a/webrtc/test/rtp_rtcp_observer.h +++ b/webrtc/test/rtp_rtcp_observer.h @@ -171,9 +171,9 @@ class RtpRtcpObserver { rtc::CriticalSection crit_; const rtc::scoped_ptr observation_complete_; const rtc::scoped_ptr parser_; + PacketTransport send_transport_, receive_transport_; private: - PacketTransport send_transport_, receive_transport_; unsigned int timeout_ms_; }; } // namespace test diff --git a/webrtc/video/rampup_tests.cc b/webrtc/video/rampup_tests.cc index f69f8ce97b..ec014206bd 100644 --- a/webrtc/video/rampup_tests.cc +++ b/webrtc/video/rampup_tests.cc @@ -29,8 +29,7 @@ namespace webrtc { namespace { -static const int kMaxPacketSize = 1500; -const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; +static const int64_t kPollIntervalMs = 250; std::vector GenerateSsrcs(size_t num_streams, uint32_t ssrc_offset) { @@ -41,294 +40,298 @@ std::vector GenerateSsrcs(size_t num_streams, } } // namespace -StreamObserver::StreamObserver(const SsrcMap& rtx_media_ssrcs, - newapi::Transport* feedback_transport, - Clock* clock) - : clock_(clock), - test_done_(EventWrapper::Create()), - rtp_parser_(RtpHeaderParser::Create()), - feedback_transport_(feedback_transport), - receive_stats_(ReceiveStatistics::Create(clock)), - payload_registry_( - new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))), - remote_bitrate_estimator_(nullptr), +RampUpTester::RampUpTester(size_t num_streams, + unsigned int start_bitrate_bps, + const std::string& extension_type, + bool rtx, + bool red) + : EndToEndTest(test::CallTest::kLongTimeoutMs), + event_(false, false), + clock_(Clock::GetRealTimeClock()), + num_streams_(num_streams), + rtx_(rtx), + red_(red), + send_stream_(nullptr), + start_bitrate_bps_(start_bitrate_bps), + start_bitrate_verified_(false), expected_bitrate_bps_(0), - start_bitrate_bps_(0), - rtx_media_ssrcs_(rtx_media_ssrcs), - total_sent_(0), - padding_sent_(0), - rtx_media_sent_(0), - total_packets_sent_(0), - padding_packets_sent_(0), - rtx_media_packets_sent_(0), test_start_ms_(clock_->TimeInMilliseconds()), - ramp_up_finished_ms_(0) { - // Ideally we would only have to instantiate an RtcpSender, an - // RtpHeaderParser and a RemoteBitrateEstimator here, but due to the current - // state of the RTP module we need a full module and receive statistics to - // be able to produce an RTCP with REMB. - RtpRtcp::Configuration config; - config.receive_statistics = receive_stats_.get(); - feedback_transport_.Enable(); - config.outgoing_transport = &feedback_transport_; - rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); - rtp_rtcp_->SetREMBStatus(true); - rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); - packet_router_.reset(new PacketRouter()); - packet_router_->AddRtpModule(rtp_rtcp_.get()); - rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, - kAbsSendTimeExtensionId); - rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset, - kTransmissionTimeOffsetExtensionId); - rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber, - kTransportSequenceNumberExtensionId); - payload_registry_->SetRtxPayloadType(RampUpTest::kSendRtxPayloadType, - RampUpTest::kFakeSendPayloadType); -} - -StreamObserver::~StreamObserver() { - packet_router_->RemoveRtpModule(rtp_rtcp_.get()); -} - -void StreamObserver::set_expected_bitrate_bps( - unsigned int expected_bitrate_bps) { - rtc::CritScope lock(&crit_); - expected_bitrate_bps_ = expected_bitrate_bps; -} - -void StreamObserver::set_start_bitrate_bps(unsigned int start_bitrate_bps) { - rtc::CritScope lock(&crit_); - start_bitrate_bps_ = start_bitrate_bps; -} - -void StreamObserver::OnReceiveBitrateChanged( - const std::vector& ssrcs, unsigned int bitrate) { - rtc::CritScope lock(&crit_); - RTC_DCHECK_GT(expected_bitrate_bps_, 0u); - if (start_bitrate_bps_ != 0) { - // For tests with an explicitly set start bitrate, verify the first - // bitrate estimate is close to the start bitrate and lower than the - // test target bitrate. This is to verify a call respects the configured - // start bitrate, but due to the BWE implementation we can't guarantee the - // first estimate really is as high as the start bitrate. - EXPECT_GT(bitrate, 0.9 * start_bitrate_bps_); - start_bitrate_bps_ = 0; + ramp_up_finished_ms_(-1), + extension_type_(extension_type), + ssrcs_(GenerateSsrcs(num_streams, 100)), + rtx_ssrcs_(GenerateSsrcs(num_streams, 200)), + poller_thread_(ThreadWrapper::CreateThread(&BitrateStatsPollingThread, + this, + "BitrateStatsPollingThread")), + sender_call_(nullptr) { + if (rtx_) { + for (size_t i = 0; i < ssrcs_.size(); ++i) + rtx_ssrc_map_[rtx_ssrcs_[i]] = ssrcs_[i]; } - if (bitrate >= expected_bitrate_bps_) { - ramp_up_finished_ms_ = clock_->TimeInMilliseconds(); - // Just trigger if there was any rtx padding packet. - if (rtx_media_ssrcs_.empty() || rtx_media_sent_ > 0) { - TriggerTestDone(); + poller_thread_->Start(); +} + +RampUpTester::~RampUpTester() { + event_.Set(); + poller_thread_->Stop(); +} + +Call::Config RampUpTester::GetSenderCallConfig() { + Call::Config call_config; + if (start_bitrate_bps_ != 0) { + call_config.bitrate_config.start_bitrate_bps = start_bitrate_bps_; + } + call_config.bitrate_config.min_bitrate_bps = 10000; + return call_config; +} + +void RampUpTester::OnStreamsCreated( + VideoSendStream* send_stream, + const std::vector& receive_streams) { + send_stream_ = send_stream; +} + +size_t RampUpTester::GetNumStreams() const { + return num_streams_; +} + +void RampUpTester::ModifyConfigs( + VideoSendStream::Config* send_config, + std::vector* receive_configs, + VideoEncoderConfig* encoder_config) { + send_config->suspend_below_min_bitrate = true; + + if (num_streams_ == 1) { + encoder_config->streams[0].target_bitrate_bps = + encoder_config->streams[0].max_bitrate_bps = 2000000; + // For single stream rampup until 1mbps + expected_bitrate_bps_ = kSingleStreamTargetBps; + } else { + // For multi stream rampup until all streams are being sent. That means + // enough birate to send all the target streams plus the min bitrate of + // the last one. + expected_bitrate_bps_ = encoder_config->streams.back().min_bitrate_bps; + for (size_t i = 0; i < encoder_config->streams.size() - 1; ++i) { + expected_bitrate_bps_ += encoder_config->streams[i].target_bitrate_bps; } } - rtp_rtcp_->SetREMBData(bitrate, ssrcs); - rtp_rtcp_->Process(); -} -bool StreamObserver::SendRtp(const uint8_t* packet, size_t length) { - rtc::CritScope lock(&crit_); - RTPHeader header; - EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header)); - receive_stats_->IncomingPacket(header, length, false); - payload_registry_->SetIncomingPayloadType(header); - RTC_DCHECK(remote_bitrate_estimator_ != nullptr); - remote_bitrate_estimator_->IncomingPacket( - clock_->TimeInMilliseconds(), length - header.headerLength, header, true); - if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) { - remote_bitrate_estimator_->Process(); - rtp_rtcp_->Process(); - } - total_sent_ += length; - padding_sent_ += header.paddingLength; - ++total_packets_sent_; - if (header.paddingLength > 0) - ++padding_packets_sent_; - // Handle RTX retransmission, but only for non-padding-only packets. - if (rtx_media_ssrcs_.find(header.ssrc) != rtx_media_ssrcs_.end() && - header.headerLength + header.paddingLength != length) { - rtx_media_sent_ += length - header.headerLength - header.paddingLength; - if (header.paddingLength == 0) - ++rtx_media_packets_sent_; - uint8_t restored_packet[kMaxPacketSize]; - uint8_t* restored_packet_ptr = restored_packet; - size_t restored_length = length; - EXPECT_TRUE(payload_registry_->RestoreOriginalPacket( - &restored_packet_ptr, packet, &restored_length, - rtx_media_ssrcs_[header.ssrc], header)); - EXPECT_TRUE( - rtp_parser_->Parse(restored_packet_ptr, restored_length, &header)); + send_config->rtp.extensions.clear(); + + bool remb; + if (extension_type_ == RtpExtension::kAbsSendTime) { + remb = true; + send_config->rtp.extensions.push_back( + RtpExtension(extension_type_.c_str(), kAbsSendTimeExtensionId)); + } else if (extension_type_ == RtpExtension::kTransportSequenceNumber) { + remb = false; + send_config->rtp.extensions.push_back(RtpExtension( + extension_type_.c_str(), kTransportSequenceNumberExtensionId)); } else { - rtp_rtcp_->SetRemoteSSRC(header.ssrc); + remb = true; + send_config->rtp.extensions.push_back(RtpExtension( + extension_type_.c_str(), kTransmissionTimeOffsetExtensionId)); + } + + send_config->rtp.nack.rtp_history_ms = test::CallTest::kNackRtpHistoryMs; + send_config->rtp.ssrcs = ssrcs_; + if (rtx_) { + send_config->rtp.rtx.payload_type = test::CallTest::kSendRtxPayloadType; + send_config->rtp.rtx.ssrcs = rtx_ssrcs_; + } + if (red_) { + send_config->rtp.fec.ulpfec_payload_type = + test::CallTest::kUlpfecPayloadType; + send_config->rtp.fec.red_payload_type = test::CallTest::kRedPayloadType; + } + + size_t i = 0; + for (VideoReceiveStream::Config& recv_config : *receive_configs) { + recv_config.rtp.remb = remb; + recv_config.rtp.extensions = send_config->rtp.extensions; + + recv_config.rtp.remote_ssrc = ssrcs_[i]; + recv_config.rtp.nack.rtp_history_ms = send_config->rtp.nack.rtp_history_ms; + + if (red_) { + recv_config.rtp.fec.red_payload_type = + send_config->rtp.fec.red_payload_type; + recv_config.rtp.fec.ulpfec_payload_type = + send_config->rtp.fec.ulpfec_payload_type; + } + + if (rtx_) { + recv_config.rtp.rtx[send_config->encoder_settings.payload_type].ssrc = + rtx_ssrcs_[i]; + recv_config.rtp.rtx[send_config->encoder_settings.payload_type] + .payload_type = send_config->rtp.rtx.payload_type; + } + ++i; } - return true; } -bool StreamObserver::SendRtcp(const uint8_t* packet, size_t length) { - return true; +void RampUpTester::OnCallsCreated(Call* sender_call, Call* receiver_call) { + sender_call_ = sender_call; } -EventTypeWrapper StreamObserver::Wait() { - return test_done_->Wait(test::CallTest::kLongTimeoutMs); +bool RampUpTester::BitrateStatsPollingThread(void* obj) { + return static_cast(obj)->PollStats(); } -void StreamObserver::SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe) { - remote_bitrate_estimator_.reset(rbe); +bool RampUpTester::PollStats() { + if (sender_call_) { + Call::Stats stats = sender_call_->GetStats(); + + RTC_DCHECK_GT(expected_bitrate_bps_, 0); + if (!start_bitrate_verified_ && start_bitrate_bps_ != 0) { + // For tests with an explicitly set start bitrate, verify the first + // bitrate estimate is close to the start bitrate and lower than the + // test target bitrate. This is to verify a call respects the configured + // start bitrate, but due to the BWE implementation we can't guarantee the + // first estimate really is as high as the start bitrate. + EXPECT_GT(stats.send_bandwidth_bps, 0.9 * start_bitrate_bps_); + start_bitrate_verified_ = true; + } + if (stats.send_bandwidth_bps >= expected_bitrate_bps_) { + ramp_up_finished_ms_ = clock_->TimeInMilliseconds(); + observation_complete_->Set(); + } + } + + return !event_.Wait(kPollIntervalMs); } -PacketRouter* StreamObserver::GetPacketRouter() { - return packet_router_.get(); -} - -void StreamObserver::ReportResult(const std::string& measurement, - size_t value, - const std::string& units) { +void RampUpTester::ReportResult(const std::string& measurement, + size_t value, + const std::string& units) const { webrtc::test::PrintResult( measurement, "", ::testing::UnitTest::GetInstance()->current_test_info()->name(), value, units, false); } -void StreamObserver::TriggerTestDone() EXCLUSIVE_LOCKS_REQUIRED(crit_) { - ReportResult("ramp-up-total-sent", total_sent_, "bytes"); - ReportResult("ramp-up-padding-sent", padding_sent_, "bytes"); - ReportResult("ramp-up-rtx-media-sent", rtx_media_sent_, "bytes"); - ReportResult("ramp-up-total-packets-sent", total_packets_sent_, "packets"); - ReportResult("ramp-up-padding-packets-sent", - padding_packets_sent_, - "packets"); - ReportResult("ramp-up-rtx-packets-sent", - rtx_media_packets_sent_, - "packets"); - ReportResult("ramp-up-time", - ramp_up_finished_ms_ - test_start_ms_, - "milliseconds"); - test_done_->Set(); +void RampUpTester::GetStats(const VideoSendStream::StreamStats& stream, + size_t* total_packets_sent, + size_t* total_sent, + size_t* padding_sent, + size_t* media_sent) const { + *total_packets_sent += stream.rtp_stats.transmitted.packets + + stream.rtp_stats.retransmitted.packets + + stream.rtp_stats.fec.packets; + *total_sent += stream.rtp_stats.transmitted.TotalBytes() + + stream.rtp_stats.retransmitted.TotalBytes() + + stream.rtp_stats.fec.TotalBytes(); + *padding_sent += stream.rtp_stats.transmitted.padding_bytes + + stream.rtp_stats.retransmitted.padding_bytes + + stream.rtp_stats.fec.padding_bytes; + *media_sent += stream.rtp_stats.MediaPayloadBytes(); } -LowRateStreamObserver::LowRateStreamObserver( - newapi::Transport* feedback_transport, - Clock* clock, - size_t number_of_streams, - bool rtx_used) - : clock_(clock), - number_of_streams_(number_of_streams), - rtx_used_(rtx_used), - test_done_(EventWrapper::Create()), - rtp_parser_(RtpHeaderParser::Create()), - feedback_transport_(feedback_transport), - receive_stats_(ReceiveStatistics::Create(clock)), - send_stream_(nullptr), +void RampUpTester::TriggerTestDone() { + VideoSendStream::Stats send_stats = send_stream_->GetStats(); + + size_t total_packets_sent = 0; + size_t total_sent = 0; + size_t padding_sent = 0; + size_t media_sent = 0; + for (uint32_t ssrc : ssrcs_) { + GetStats(send_stats.substreams[ssrc], &total_packets_sent, &total_sent, + &padding_sent, &media_sent); + } + + size_t rtx_total_packets_sent = 0; + size_t rtx_total_sent = 0; + size_t rtx_padding_sent = 0; + size_t rtx_media_sent = 0; + for (uint32_t rtx_ssrc : rtx_ssrcs_) { + GetStats(send_stats.substreams[rtx_ssrc], &total_packets_sent, &total_sent, + &padding_sent, &media_sent); + } + + ReportResult("ramp-up-total-packets-sent", total_packets_sent, "packets"); + ReportResult("ramp-up-total-sent", total_sent, "bytes"); + ReportResult("ramp-up-media-sent", media_sent, "bytes"); + ReportResult("ramp-up-padding-sent", padding_sent, "bytes"); + ReportResult("ramp-up-rtx-total-packets-sent", rtx_total_packets_sent, + "packets"); + ReportResult("ramp-up-rtx-total-sent", rtx_total_sent, "bytes"); + ReportResult("ramp-up-rtx-media-sent", rtx_media_sent, "bytes"); + ReportResult("ramp-up-rtx-padding-sent", rtx_padding_sent, "bytes"); + if (ramp_up_finished_ms_ >= 0) { + ReportResult("ramp-up-time", ramp_up_finished_ms_ - test_start_ms_, + "milliseconds"); + } +} + +void RampUpTester::PerformTest() { + if (Wait() != kEventSignaled) { + printf("Timed out while waiting for ramp-up to complete."); + return; + } + TriggerTestDone(); +} + +RampUpDownUpTester::RampUpDownUpTester(size_t num_streams, + unsigned int start_bitrate_bps, + const std::string& extension_type, + bool rtx, + bool red) + : RampUpTester(num_streams, start_bitrate_bps, extension_type, rtx, red), test_state_(kFirstRampup), state_start_ms_(clock_->TimeInMilliseconds()), - interval_start_ms_(state_start_ms_), - last_remb_bps_(0), - sent_bytes_(0), - total_overuse_bytes_(0), - suspended_in_stats_(false) { - RtpRtcp::Configuration config; - config.receive_statistics = receive_stats_.get(); - feedback_transport_.Enable(); - config.outgoing_transport = &feedback_transport_; - rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); - rtp_rtcp_->SetREMBStatus(true); - rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); - rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, - kAbsSendTimeExtensionId); - const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 10000; - remote_bitrate_estimator_.reset(new RemoteBitrateEstimatorAbsSendTime( - this, clock, kRemoteBitrateEstimatorMinBitrateBps)); + interval_start_ms_(clock_->TimeInMilliseconds()), + sent_bytes_(0) { forward_transport_config_.link_capacity_kbps = kHighBandwidthLimitBps / 1000; - forward_transport_config_.queue_length_packets = 100; // Something large. - test::DirectTransport::SetConfig(forward_transport_config_); - test::DirectTransport::SetReceiver(this); + send_transport_.SetConfig(forward_transport_config_); } -void LowRateStreamObserver::SetSendStream(VideoSendStream* send_stream) { - rtc::CritScope lock(&crit_); - send_stream_ = send_stream; -} +RampUpDownUpTester::~RampUpDownUpTester() {} -void LowRateStreamObserver::OnReceiveBitrateChanged( - const std::vector& ssrcs, - unsigned int bitrate) { - rtc::CritScope lock(&crit_); - rtp_rtcp_->SetREMBData(bitrate, ssrcs); - rtp_rtcp_->Process(); - last_remb_bps_ = bitrate; -} - -bool LowRateStreamObserver::SendRtp(const uint8_t* data, size_t length) { - rtc::CritScope lock(&crit_); - sent_bytes_ += length; - int64_t now_ms = clock_->TimeInMilliseconds(); - if (now_ms > interval_start_ms_ + 1000) { // Let at least 1 second pass. - // Verify that the send rate was about right. - unsigned int average_rate_bps = static_cast(sent_bytes_) * - 8 * 1000 / (now_ms - interval_start_ms_); - // TODO(holmer): Why is this failing? - // EXPECT_LT(average_rate_bps, last_remb_bps_ * 1.1); - if (average_rate_bps > last_remb_bps_ * 1.1) { - total_overuse_bytes_ += - sent_bytes_ - - last_remb_bps_ / 8 * (now_ms - interval_start_ms_) / 1000; +bool RampUpDownUpTester::PollStats() { + if (send_stream_) { + webrtc::VideoSendStream::Stats stats = send_stream_->GetStats(); + int transmit_bitrate_bps = 0; + for (auto it : stats.substreams) { + transmit_bitrate_bps += it.second.total_bitrate_bps; } - EvolveTestState(average_rate_bps); - interval_start_ms_ = now_ms; - sent_bytes_ = 0; + + EvolveTestState(transmit_bitrate_bps, stats.suspended); } - return test::DirectTransport::SendRtp(data, length); + + return !event_.Wait(kPollIntervalMs); } -PacketReceiver::DeliveryStatus LowRateStreamObserver::DeliverPacket( - MediaType media_type, - const uint8_t* packet, - size_t length, - const PacketTime& packet_time) { - rtc::CritScope lock(&crit_); - RTPHeader header; - EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header)); - receive_stats_->IncomingPacket(header, length, false); - remote_bitrate_estimator_->IncomingPacket( - clock_->TimeInMilliseconds(), length - header.headerLength, header, true); - if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) { - remote_bitrate_estimator_->Process(); - } - suspended_in_stats_ = send_stream_->GetStats().suspended; - return DELIVERY_OK; +Call::Config RampUpDownUpTester::GetReceiverCallConfig() { + Call::Config config; + config.bitrate_config.min_bitrate_bps = 10000; + return config; } -bool LowRateStreamObserver::SendRtcp(const uint8_t* packet, size_t length) { - return true; -} - -std::string LowRateStreamObserver::GetModifierString() { +std::string RampUpDownUpTester::GetModifierString() const { std::string str("_"); char temp_str[5]; - sprintf(temp_str, "%i", - static_cast(number_of_streams_)); + sprintf(temp_str, "%i", static_cast(num_streams_)); str += std::string(temp_str); str += "stream"; - str += (number_of_streams_ > 1 ? "s" : ""); + str += (num_streams_ > 1 ? "s" : ""); str += "_"; - str += (rtx_used_ ? "" : "no"); + str += (rtx_ ? "" : "no"); str += "rtx"; return str; } -void LowRateStreamObserver::EvolveTestState(unsigned int bitrate_bps) { +void RampUpDownUpTester::EvolveTestState(int bitrate_bps, bool suspended) { int64_t now = clock_->TimeInMilliseconds(); - rtc::CritScope lock(&crit_); - RTC_DCHECK(send_stream_ != nullptr); switch (test_state_) { case kFirstRampup: { - EXPECT_FALSE(suspended_in_stats_); + EXPECT_FALSE(suspended); if (bitrate_bps > kExpectedHighBitrateBps) { // The first ramp-up has reached the target bitrate. Change the // channel limit, and move to the next test state. forward_transport_config_.link_capacity_kbps = kLowBandwidthLimitBps / 1000; - test::DirectTransport::SetConfig(forward_transport_config_); + send_transport_.SetConfig(forward_transport_config_); test_state_ = kLowRate; webrtc::test::PrintResult("ramp_up_down_up", GetModifierString(), @@ -343,12 +346,12 @@ void LowRateStreamObserver::EvolveTestState(unsigned int bitrate_bps) { break; } case kLowRate: { - if (bitrate_bps < kExpectedLowBitrateBps && suspended_in_stats_) { + if (bitrate_bps < kExpectedLowBitrateBps && suspended) { // The ramp-down was successful. Change the channel limit back to a // high value, and move to the next test state. forward_transport_config_.link_capacity_kbps = kHighBandwidthLimitBps / 1000; - test::DirectTransport::SetConfig(forward_transport_config_); + send_transport_.SetConfig(forward_transport_config_); test_state_ = kSecondRampup; webrtc::test::PrintResult("ramp_up_down_up", GetModifierString(), @@ -363,299 +366,135 @@ void LowRateStreamObserver::EvolveTestState(unsigned int bitrate_bps) { break; } case kSecondRampup: { - if (bitrate_bps > kExpectedHighBitrateBps && !suspended_in_stats_) { + if (bitrate_bps > kExpectedHighBitrateBps && !suspended) { webrtc::test::PrintResult("ramp_up_down_up", GetModifierString(), "second_rampup", now - state_start_ms_, "ms", false); - webrtc::test::PrintResult("ramp_up_down_up", - GetModifierString(), - "total_overuse", - total_overuse_bytes_, - "bytes", - false); - test_done_->Set(); + observation_complete_->Set(); } break; } } } -EventTypeWrapper LowRateStreamObserver::Wait() { - return test_done_->Wait(test::CallTest::kLongTimeoutMs); -} - -class SendBitrateAdapter { +class RampUpTest : public test::CallTest { public: - static const int64_t kPollIntervalMs = 250; + RampUpTest() {} - SendBitrateAdapter(const Call& call, - const std::vector& ssrcs, - RemoteBitrateObserver* bitrate_observer) - : event_(false, false), - call_(call), - ssrcs_(ssrcs), - bitrate_observer_(bitrate_observer) { - RTC_DCHECK(bitrate_observer != nullptr); - poller_thread_ = ThreadWrapper::CreateThread(&SendBitrateAdapterThread, - this, "SendBitratePoller"); - bool thread_start_ok = poller_thread_->Start(); - RTC_DCHECK(thread_start_ok); + virtual ~RampUpTest() { + EXPECT_EQ(nullptr, send_stream_); + EXPECT_TRUE(receive_streams_.empty()); } - - virtual ~SendBitrateAdapter() { - event_.Set(); - poller_thread_->Stop(); - } - - private: - static bool SendBitrateAdapterThread(void* obj) { - return static_cast(obj)->PollStats(); - } - - bool PollStats() { - Call::Stats stats = call_.GetStats(); - - bitrate_observer_->OnReceiveBitrateChanged(ssrcs_, - stats.send_bandwidth_bps); - return !event_.Wait(kPollIntervalMs); - } - - rtc::Event event_; - rtc::scoped_ptr poller_thread_; - const Call& call_; - const std::vector ssrcs_; - RemoteBitrateObserver* const bitrate_observer_; }; -void RampUpTest::RunRampUpTest(size_t num_streams, - unsigned int start_bitrate_bps, - const std::string& extension_type, - bool rtx, - bool red) { - std::vector ssrcs(GenerateSsrcs(num_streams, 100)); - std::vector rtx_ssrcs(GenerateSsrcs(num_streams, 200)); - StreamObserver::SsrcMap rtx_ssrc_map; - if (rtx) { - for (size_t i = 0; i < ssrcs.size(); ++i) - rtx_ssrc_map[rtx_ssrcs[i]] = ssrcs[i]; - } - - test::DirectTransport receiver_transport; - StreamObserver stream_observer(rtx_ssrc_map, &receiver_transport, - Clock::GetRealTimeClock()); - - CreateSendConfig(num_streams, &stream_observer); - send_config_.rtp.extensions.clear(); - - rtc::scoped_ptr send_bitrate_adapter_; - - if (extension_type == RtpExtension::kAbsSendTime) { - stream_observer.SetRemoteBitrateEstimator( - new RemoteBitrateEstimatorAbsSendTime( - &stream_observer, Clock::GetRealTimeClock(), - kRemoteBitrateEstimatorMinBitrateBps)); - send_config_.rtp.extensions.push_back(RtpExtension( - extension_type.c_str(), kAbsSendTimeExtensionId)); - } else if (extension_type == RtpExtension::kTransportSequenceNumber) { - stream_observer.SetRemoteBitrateEstimator(new RemoteEstimatorProxy( - Clock::GetRealTimeClock(), stream_observer.GetPacketRouter())); - send_config_.rtp.extensions.push_back(RtpExtension( - extension_type.c_str(), kTransportSequenceNumberExtensionId)); - } else { - stream_observer.SetRemoteBitrateEstimator( - new RemoteBitrateEstimatorSingleStream( - &stream_observer, Clock::GetRealTimeClock(), - kRemoteBitrateEstimatorMinBitrateBps)); - send_config_.rtp.extensions.push_back(RtpExtension( - extension_type.c_str(), kTransmissionTimeOffsetExtensionId)); - } - - Call::Config call_config; - if (start_bitrate_bps != 0) { - call_config.bitrate_config.start_bitrate_bps = start_bitrate_bps; - stream_observer.set_start_bitrate_bps(start_bitrate_bps); - } - CreateSenderCall(call_config); - - receiver_transport.SetReceiver(sender_call_->Receiver()); - - if (num_streams == 1) { - encoder_config_.streams[0].target_bitrate_bps = 2000000; - encoder_config_.streams[0].max_bitrate_bps = 2000000; - } - - send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - send_config_.rtp.ssrcs = ssrcs; - if (rtx) { - send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; - send_config_.rtp.rtx.ssrcs = rtx_ssrcs; - } - if (red) { - send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; - send_config_.rtp.fec.red_payload_type = kRedPayloadType; - } - - if (num_streams == 1) { - // For single stream rampup until 1mbps - stream_observer.set_expected_bitrate_bps(kSingleStreamTargetBps); - } else { - // For multi stream rampup until all streams are being sent. That means - // enough birate to send all the target streams plus the min bitrate of - // the last one. - int expected_bitrate_bps = encoder_config_.streams.back().min_bitrate_bps; - for (size_t i = 0; i < encoder_config_.streams.size() - 1; ++i) { - expected_bitrate_bps += encoder_config_.streams[i].target_bitrate_bps; - } - stream_observer.set_expected_bitrate_bps(expected_bitrate_bps); - } - - CreateStreams(); - CreateFrameGeneratorCapturer(); - - if (extension_type == RtpExtension::kTransportSequenceNumber) { - send_bitrate_adapter_.reset( - new SendBitrateAdapter(*sender_call_.get(), ssrcs, &stream_observer)); - } - Start(); - - EXPECT_EQ(kEventSignaled, stream_observer.Wait()); - - // Destroy the SendBitrateAdapter (if any) to stop the poller thread in it, - // otherwise we might get a data race with the destruction of the call. - send_bitrate_adapter_.reset(); - - Stop(); - DestroyStreams(); -} - -void RampUpTest::RunRampUpDownUpTest(size_t number_of_streams, - bool rtx, - bool red) { - test::DirectTransport receiver_transport; - LowRateStreamObserver stream_observer( - &receiver_transport, Clock::GetRealTimeClock(), number_of_streams, rtx); - - Call::Config call_config; - call_config.bitrate_config.start_bitrate_bps = 60000; - CreateSenderCall(call_config); - receiver_transport.SetReceiver(sender_call_->Receiver()); - - CreateSendConfig(number_of_streams, &stream_observer); - - send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - send_config_.rtp.extensions.push_back(RtpExtension( - RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); - send_config_.suspend_below_min_bitrate = true; - - if (rtx) { - send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; - send_config_.rtp.rtx.ssrcs = GenerateSsrcs(number_of_streams, 200); - } - if (red) { - send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; - send_config_.rtp.fec.red_payload_type = kRedPayloadType; - } - - CreateStreams(); - stream_observer.SetSendStream(send_stream_); - - CreateFrameGeneratorCapturer(); - - Start(); - - EXPECT_EQ(kEventSignaled, stream_observer.Wait()); - - Stop(); - DestroyStreams(); -} - TEST_F(RampUpTest, SingleStream) { - RunRampUpTest(1, 0, RtpExtension::kTOffset, false, false); + RampUpTester test(1, 0, RtpExtension::kTOffset, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, Simulcast) { - RunRampUpTest(3, 0, RtpExtension::kTOffset, false, false); + RampUpTester test(3, 0, RtpExtension::kTOffset, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, SimulcastWithRtx) { - RunRampUpTest(3, 0, RtpExtension::kTOffset, true, false); + RampUpTester test(3, 0, RtpExtension::kTOffset, true, false); + RunBaseTest(&test); } TEST_F(RampUpTest, SimulcastByRedWithRtx) { - RunRampUpTest(3, 0, RtpExtension::kTOffset, true, true); + RampUpTester test(3, 0, RtpExtension::kTOffset, true, true); + RunBaseTest(&test); } TEST_F(RampUpTest, SingleStreamWithHighStartBitrate) { - RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kTOffset, false, - false); + RampUpTester test(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kTOffset, + false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, UpDownUpOneStream) { - RunRampUpDownUpTest(1, false, false); + RampUpDownUpTester test(1, 60000, RtpExtension::kAbsSendTime, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, UpDownUpThreeStreams) { - RunRampUpDownUpTest(3, false, false); + RampUpDownUpTester test(3, 60000, RtpExtension::kAbsSendTime, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, UpDownUpOneStreamRtx) { - RunRampUpDownUpTest(1, true, false); + RampUpDownUpTester test(1, 60000, RtpExtension::kAbsSendTime, true, false); + RunBaseTest(&test); } TEST_F(RampUpTest, UpDownUpThreeStreamsRtx) { - RunRampUpDownUpTest(3, true, false); + RampUpDownUpTester test(3, 60000, RtpExtension::kAbsSendTime, true, false); + RunBaseTest(&test); } TEST_F(RampUpTest, UpDownUpOneStreamByRedRtx) { - RunRampUpDownUpTest(1, true, true); + RampUpDownUpTester test(1, 60000, RtpExtension::kAbsSendTime, true, true); + RunBaseTest(&test); } TEST_F(RampUpTest, UpDownUpThreeStreamsByRedRtx) { - RunRampUpDownUpTest(3, true, true); + RampUpDownUpTester test(3, 60000, RtpExtension::kAbsSendTime, true, true); + RunBaseTest(&test); } TEST_F(RampUpTest, AbsSendTimeSingleStream) { - RunRampUpTest(1, 0, RtpExtension::kAbsSendTime, false, false); + RampUpTester test(1, 0, RtpExtension::kAbsSendTime, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, AbsSendTimeSimulcast) { - RunRampUpTest(3, 0, RtpExtension::kAbsSendTime, false, false); + RampUpTester test(3, 0, RtpExtension::kAbsSendTime, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, AbsSendTimeSimulcastWithRtx) { - RunRampUpTest(3, 0, RtpExtension::kAbsSendTime, true, false); + RampUpTester test(3, 0, RtpExtension::kAbsSendTime, true, false); + RunBaseTest(&test); } TEST_F(RampUpTest, AbsSendTimeSimulcastByRedWithRtx) { - RunRampUpTest(3, 0, RtpExtension::kAbsSendTime, true, true); + RampUpTester test(3, 0, RtpExtension::kAbsSendTime, true, true); + RunBaseTest(&test); } TEST_F(RampUpTest, AbsSendTimeSingleStreamWithHighStartBitrate) { - RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kAbsSendTime, - false, false); + RampUpTester test(1, 0.9 * kSingleStreamTargetBps, RtpExtension::kAbsSendTime, + false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, TransportSequenceNumberSingleStream) { - RunRampUpTest(1, 0, RtpExtension::kTransportSequenceNumber, false, false); + RampUpTester test(1, 0, RtpExtension::kTransportSequenceNumber, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, TransportSequenceNumberSimulcast) { - RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, false, false); + RampUpTester test(3, 0, RtpExtension::kTransportSequenceNumber, false, false); + RunBaseTest(&test); } TEST_F(RampUpTest, TransportSequenceNumberSimulcastWithRtx) { - RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, true, false); + RampUpTester test(3, 0, RtpExtension::kTransportSequenceNumber, true, false); + RunBaseTest(&test); } TEST_F(RampUpTest, TransportSequenceNumberSimulcastByRedWithRtx) { - RunRampUpTest(3, 0, RtpExtension::kTransportSequenceNumber, true, true); + RampUpTester test(3, 0, RtpExtension::kTransportSequenceNumber, true, true); + RunBaseTest(&test); } TEST_F(RampUpTest, TransportSequenceNumberSingleStreamWithHighStartBitrate) { - RunRampUpTest(1, 0.9 * kSingleStreamTargetBps, - RtpExtension::kTransportSequenceNumber, false, false); + RampUpTester test(1, 0.9 * kSingleStreamTargetBps, + RtpExtension::kTransportSequenceNumber, false, false); + RunBaseTest(&test); } } // namespace webrtc diff --git a/webrtc/video/rampup_tests.h b/webrtc/video/rampup_tests.h index 62edda3406..ddab712dec 100644 --- a/webrtc/video/rampup_tests.h +++ b/webrtc/video/rampup_tests.h @@ -36,133 +36,97 @@ class RtpHeaderParser; class RTPPayloadRegistry; class RtpRtcp; -class StreamObserver : public newapi::Transport, public RemoteBitrateObserver { +class RampUpTester : public test::EndToEndTest { public: - typedef std::map BytesSentMap; - typedef std::map SsrcMap; - StreamObserver(const SsrcMap& rtx_media_ssrcs, - newapi::Transport* feedback_transport, - Clock* clock); - virtual ~StreamObserver(); + RampUpTester(size_t num_streams, + unsigned int start_bitrate_bps, + const std::string& extension_type, + bool rtx, + bool red); + ~RampUpTester() override; - void set_expected_bitrate_bps(unsigned int expected_bitrate_bps); + void PerformTest() override; - void set_start_bitrate_bps(unsigned int start_bitrate_bps); + protected: + virtual bool PollStats(); - void OnReceiveBitrateChanged(const std::vector& ssrcs, - unsigned int bitrate) override; + void GetStats(const VideoSendStream::StreamStats& stream, + size_t* total_packets_sent, + size_t* total_sent, + size_t* padding_sent, + size_t* media_sent) const; - bool SendRtp(const uint8_t* packet, size_t length) override; - - bool SendRtcp(const uint8_t* packet, size_t length) override; - - EventTypeWrapper Wait(); - - void SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe); - - PacketRouter* GetPacketRouter(); - - private: void ReportResult(const std::string& measurement, size_t value, - const std::string& units); - void TriggerTestDone() EXCLUSIVE_LOCKS_REQUIRED(crit_); + const std::string& units) const; + void TriggerTestDone(); + rtc::Event event_; Clock* const clock_; - const rtc::scoped_ptr test_done_; - const rtc::scoped_ptr rtp_parser_; - rtc::scoped_ptr rtp_rtcp_; - rtc::scoped_ptr packet_router_; - internal::TransportAdapter feedback_transport_; - const rtc::scoped_ptr receive_stats_; - const rtc::scoped_ptr payload_registry_; - rtc::scoped_ptr remote_bitrate_estimator_; - - rtc::CriticalSection crit_; - unsigned int expected_bitrate_bps_ GUARDED_BY(crit_); - unsigned int start_bitrate_bps_ GUARDED_BY(crit_); - SsrcMap rtx_media_ssrcs_ GUARDED_BY(crit_); - size_t total_sent_ GUARDED_BY(crit_); - size_t padding_sent_ GUARDED_BY(crit_); - size_t rtx_media_sent_ GUARDED_BY(crit_); - int total_packets_sent_ GUARDED_BY(crit_); - int padding_packets_sent_ GUARDED_BY(crit_); - int rtx_media_packets_sent_ GUARDED_BY(crit_); - int64_t test_start_ms_ GUARDED_BY(crit_); - int64_t ramp_up_finished_ms_ GUARDED_BY(crit_); -}; - -class LowRateStreamObserver : public test::DirectTransport, - public RemoteBitrateObserver, - public PacketReceiver { - public: - LowRateStreamObserver(newapi::Transport* feedback_transport, - Clock* clock, - size_t number_of_streams, - bool rtx_used); - - virtual void SetSendStream(VideoSendStream* send_stream); - - virtual void OnReceiveBitrateChanged(const std::vector& ssrcs, - unsigned int bitrate); - - bool SendRtp(const uint8_t* data, size_t length) override; - - DeliveryStatus DeliverPacket(MediaType media_type, - const uint8_t* packet, - size_t length, - const PacketTime& packet_time) override; - - bool SendRtcp(const uint8_t* packet, size_t length) override; - - // Produces a string similar to "1stream_nortx", depending on the values of - // number_of_streams_ and rtx_used_; - std::string GetModifierString(); - - // This method defines the state machine for the ramp up-down-up test. - void EvolveTestState(unsigned int bitrate_bps); - - EventTypeWrapper Wait(); + const size_t num_streams_; + const bool rtx_; + const bool red_; + VideoSendStream* send_stream_; private: - static const unsigned int kHighBandwidthLimitBps = 80000; - static const unsigned int kExpectedHighBitrateBps = 60000; - static const unsigned int kLowBandwidthLimitBps = 20000; - static const unsigned int kExpectedLowBitrateBps = 20000; - enum TestStates { kFirstRampup, kLowRate, kSecondRampup }; + typedef std::map SsrcMap; - Clock* const clock_; - const size_t number_of_streams_; - const bool rtx_used_; - const rtc::scoped_ptr test_done_; - const rtc::scoped_ptr rtp_parser_; - const rtc::scoped_ptr payload_registry_; - rtc::scoped_ptr rtp_rtcp_; - internal::TransportAdapter feedback_transport_; - const rtc::scoped_ptr receive_stats_; - rtc::scoped_ptr remote_bitrate_estimator_; + Call::Config GetSenderCallConfig() override; + void OnStreamsCreated( + VideoSendStream* send_stream, + const std::vector& receive_streams) override; + size_t GetNumStreams() const; + void ModifyConfigs(VideoSendStream::Config* send_config, + std::vector* receive_configs, + VideoEncoderConfig* encoder_config) override; + void OnCallsCreated(Call* sender_call, Call* receiver_call) override; - rtc::CriticalSection crit_; - VideoSendStream* send_stream_ GUARDED_BY(crit_); - FakeNetworkPipe::Config forward_transport_config_ GUARDED_BY(crit_); - TestStates test_state_ GUARDED_BY(crit_); - int64_t state_start_ms_ GUARDED_BY(crit_); - int64_t interval_start_ms_ GUARDED_BY(crit_); - unsigned int last_remb_bps_ GUARDED_BY(crit_); - size_t sent_bytes_ GUARDED_BY(crit_); - size_t total_overuse_bytes_ GUARDED_BY(crit_); - bool suspended_in_stats_ GUARDED_BY(crit_); + static bool BitrateStatsPollingThread(void* obj); + + const int start_bitrate_bps_; + bool start_bitrate_verified_; + int expected_bitrate_bps_; + int64_t test_start_ms_; + int64_t ramp_up_finished_ms_; + + const std::string extension_type_; + std::vector ssrcs_; + std::vector rtx_ssrcs_; + SsrcMap rtx_ssrc_map_; + + rtc::scoped_ptr poller_thread_; + Call* sender_call_; }; -class RampUpTest : public test::CallTest { - protected: - void RunRampUpTest(size_t num_streams, +class RampUpDownUpTester : public RampUpTester { + public: + RampUpDownUpTester(size_t num_streams, unsigned int start_bitrate_bps, const std::string& extension_type, bool rtx, bool red); + ~RampUpDownUpTester() override; - void RunRampUpDownUpTest(size_t number_of_streams, bool rtx, bool red); + protected: + bool PollStats() override; + + private: + static const int kHighBandwidthLimitBps = 80000; + static const int kExpectedHighBitrateBps = 60000; + static const int kLowBandwidthLimitBps = 20000; + static const int kExpectedLowBitrateBps = 20000; + enum TestStates { kFirstRampup, kLowRate, kSecondRampup }; + + Call::Config GetReceiverCallConfig() override; + + std::string GetModifierString() const; + void EvolveTestState(int bitrate_bps, bool suspended); + + FakeNetworkPipe::Config forward_transport_config_; + TestStates test_state_; + int64_t state_start_ms_; + int64_t interval_start_ms_; + int sent_bytes_; }; } // namespace webrtc #endif // WEBRTC_VIDEO_RAMPUP_TESTS_H_ diff --git a/webrtc/video_engine/vie_channel_group.cc b/webrtc/video_engine/vie_channel_group.cc index 6553ce2e04..ed4332ab08 100644 --- a/webrtc/video_engine/vie_channel_group.cc +++ b/webrtc/video_engine/vie_channel_group.cc @@ -43,12 +43,10 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator { : observer_(observer), clock_(clock), crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps), - rbe_(new RemoteBitrateEstimatorSingleStream(observer_, - clock_, - min_bitrate_bps_)), + rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)), using_absolute_send_time_(false), - packets_since_absolute_send_time_(0) {} + packets_since_absolute_send_time_(0), + min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {} virtual ~WrappingBitrateEstimator() {} @@ -92,6 +90,12 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator { return rbe_->GetStats(output); } + void SetMinBitrate(int min_bitrate_bps) { + CriticalSectionScoped cs(crit_sect_.get()); + rbe_->SetMinBitrate(min_bitrate_bps); + min_bitrate_bps_ = min_bitrate_bps; + } + private: void PickEstimatorFromHeader(const RTPHeader& header) EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) { @@ -121,21 +125,20 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator { // Instantiate RBE for Time Offset or Absolute Send Time extensions. void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) { if (using_absolute_send_time_) { - rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_, - min_bitrate_bps_)); + rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_)); } else { - rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_, - min_bitrate_bps_)); + rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_)); } + rbe_->SetMinBitrate(min_bitrate_bps_); } RemoteBitrateObserver* observer_; Clock* clock_; rtc::scoped_ptr crit_sect_; - const uint32_t min_bitrate_bps_; rtc::scoped_ptr rbe_; bool using_absolute_send_time_; uint32_t packets_since_absolute_send_time_; + int min_bitrate_bps_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator); }; @@ -165,7 +168,8 @@ ChannelGroup::ChannelGroup(ProcessThread* process_thread) // construction. bitrate_controller_( BitrateController::CreateBitrateController(Clock::GetRealTimeClock(), - this)) { + this)), + min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) { call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get()); pacer_thread_->RegisterModule(pacer_.get()); @@ -213,8 +217,9 @@ bool ChannelGroup::CreateSendChannel(int channel_id, Clock::GetRealTimeClock(), process_thread_)); transport_feedback_adapter_->SetBitrateEstimator( new RemoteBitrateEstimatorAbsSendTime( - transport_feedback_adapter_.get(), Clock::GetRealTimeClock(), - RemoteBitrateEstimator::kDefaultMinBitrateBps)); + transport_feedback_adapter_.get(), Clock::GetRealTimeClock())); + transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate( + min_bitrate_bps_); call_stats_->RegisterStatsObserver(transport_feedback_adapter_.get()); } transport_feedback_observer = transport_feedback_adapter_.get(); @@ -364,6 +369,20 @@ void ChannelGroup::SetSyncInterface(VoEVideoSync* sync_interface) { channel.second->SetVoiceChannel(-1, sync_interface); } +void ChannelGroup::SetBweBitrates(int min_bitrate_bps, + int start_bitrate_bps, + int max_bitrate_bps) { + if (start_bitrate_bps > 0) + bitrate_controller_->SetStartBitrate(start_bitrate_bps); + bitrate_controller_->SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps); + if (remote_bitrate_estimator_.get()) + remote_bitrate_estimator_->SetMinBitrate(min_bitrate_bps); + if (transport_feedback_adapter_.get()) + transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate( + min_bitrate_bps); + min_bitrate_bps_ = min_bitrate_bps; +} + BitrateController* ChannelGroup::GetBitrateController() const { return bitrate_controller_.get(); } diff --git a/webrtc/video_engine/vie_channel_group.h b/webrtc/video_engine/vie_channel_group.h index e133d1a0b6..374bd00333 100644 --- a/webrtc/video_engine/vie_channel_group.h +++ b/webrtc/video_engine/vie_channel_group.h @@ -63,6 +63,9 @@ class ChannelGroup : public BitrateObserver { ViEChannel* GetChannel(int channel_id) const; ViEEncoder* GetEncoder(int channel_id) const; void SetSyncInterface(VoEVideoSync* sync_interface); + void SetBweBitrates(int min_bitrate_bps, + int start_bitrate_bps, + int max_bitrate_bps); void SetChannelRembStatus(bool sender, bool receiver, ViEChannel* channel); @@ -110,6 +113,7 @@ class ChannelGroup : public BitrateObserver { rtc::scoped_ptr bitrate_controller_; rtc::scoped_ptr transport_feedback_adapter_; + int min_bitrate_bps_; }; } // namespace webrtc