diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc index c37c978dd0..4566984ee7 100644 --- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc +++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc @@ -38,7 +38,7 @@ AcknowledgedBitrateEstimator::~AcknowledgedBitrateEstimator() {} AcknowledgedBitrateEstimator::AcknowledgedBitrateEstimator( const WebRtcKeyValueConfig* key_value_config, std::unique_ptr bitrate_estimator) - : bitrate_estimator_(std::move(bitrate_estimator)) {} + : in_alr_(false), bitrate_estimator_(std::move(bitrate_estimator)) {} void AcknowledgedBitrateEstimator::IncomingPacketFeedbackVector( const std::vector& packet_feedback_vector) { @@ -50,7 +50,8 @@ void AcknowledgedBitrateEstimator::IncomingPacketFeedbackVector( MaybeExpectFastRateChange(packet.send_time_ms); int acknowledged_estimate = rtc::dchecked_cast(packet.payload_size); acknowledged_estimate += packet.unacknowledged_data; - bitrate_estimator_->Update(packet.arrival_time_ms, acknowledged_estimate); + bitrate_estimator_->Update(packet.arrival_time_ms, acknowledged_estimate, + in_alr_); } } } @@ -80,6 +81,10 @@ void AcknowledgedBitrateEstimator::SetAlrEndedTimeMs( alr_ended_time_ms_.emplace(alr_ended_time_ms); } +void AcknowledgedBitrateEstimator::SetAlr(bool in_alr) { + in_alr_ = in_alr; +} + void AcknowledgedBitrateEstimator::MaybeExpectFastRateChange( int64_t packet_send_time_ms) { if (alr_ended_time_ms_ && packet_send_time_ms > *alr_ended_time_ms_) { diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h index 343cef9335..986d17a24c 100644 --- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h +++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h @@ -39,11 +39,13 @@ class AcknowledgedBitrateEstimator { absl::optional PeekBps() const; absl::optional bitrate() const; absl::optional PeekRate() const; + void SetAlr(bool in_alr); void SetAlrEndedTimeMs(int64_t alr_ended_time_ms); private: void MaybeExpectFastRateChange(int64_t packet_arrival_time_ms); absl::optional alr_ended_time_ms_; + bool in_alr_; std::unique_ptr bitrate_estimator_; }; diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc index df6ad54e98..f406d97c36 100644 --- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc +++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc @@ -36,7 +36,7 @@ constexpr size_t kPayloadSize = 10; class MockBitrateEstimator : public BitrateEstimator { public: using BitrateEstimator::BitrateEstimator; - MOCK_METHOD2(Update, void(int64_t now_ms, int bytes)); + MOCK_METHOD3(Update, void(int64_t now_ms, int bytes, bool in_alr)); MOCK_CONST_METHOD0(bitrate_bps, absl::optional()); MOCK_METHOD0(ExpectFastRateChange, void()); }; @@ -77,25 +77,25 @@ TEST(TestAcknowledgedBitrateEstimator, DontAddPacketsWhichAreNotInSendHistory) { std::vector packet_feedback_vector; packet_feedback_vector.push_back( PacketFeedback(kFirstArrivalTimeMs, kSequenceNumber)); - EXPECT_CALL(*states.mock_bitrate_estimator, Update(_, _)).Times(0); + EXPECT_CALL(*states.mock_bitrate_estimator, Update(_, _, _)).Times(0); states.acknowledged_bitrate_estimator->IncomingPacketFeedbackVector( packet_feedback_vector); } -TEST(TestAcknowledgedBitrateEstimator, UpdateBandwith) { +TEST(TestAcknowledgedBitrateEstimator, UpdateBandwidth) { auto states = CreateTestStates(); auto packet_feedback_vector = CreateFeedbackVector(); { InSequence dummy; - EXPECT_CALL( - *states.mock_bitrate_estimator, - Update(packet_feedback_vector[0].arrival_time_ms, - static_cast(packet_feedback_vector[0].payload_size))) + EXPECT_CALL(*states.mock_bitrate_estimator, + Update(packet_feedback_vector[0].arrival_time_ms, + static_cast(packet_feedback_vector[0].payload_size), + /*in_alr*/ false)) .Times(1); - EXPECT_CALL( - *states.mock_bitrate_estimator, - Update(packet_feedback_vector[1].arrival_time_ms, - static_cast(packet_feedback_vector[1].payload_size))) + EXPECT_CALL(*states.mock_bitrate_estimator, + Update(packet_feedback_vector[1].arrival_time_ms, + static_cast(packet_feedback_vector[1].payload_size), + /*in_alr*/ false)) .Times(1); } states.acknowledged_bitrate_estimator->IncomingPacketFeedbackVector( @@ -107,17 +107,17 @@ TEST(TestAcknowledgedBitrateEstimator, ExpectFastRateChangeWhenLeftAlr) { auto packet_feedback_vector = CreateFeedbackVector(); { InSequence dummy; - EXPECT_CALL( - *states.mock_bitrate_estimator, - Update(packet_feedback_vector[0].arrival_time_ms, - static_cast(packet_feedback_vector[0].payload_size))) + EXPECT_CALL(*states.mock_bitrate_estimator, + Update(packet_feedback_vector[0].arrival_time_ms, + static_cast(packet_feedback_vector[0].payload_size), + /*in_alr*/ false)) .Times(1); EXPECT_CALL(*states.mock_bitrate_estimator, ExpectFastRateChange()) .Times(1); - EXPECT_CALL( - *states.mock_bitrate_estimator, - Update(packet_feedback_vector[1].arrival_time_ms, - static_cast(packet_feedback_vector[1].payload_size))) + EXPECT_CALL(*states.mock_bitrate_estimator, + Update(packet_feedback_vector[1].arrival_time_ms, + static_cast(packet_feedback_vector[1].payload_size), + /*in_alr*/ false)) .Times(1); } states.acknowledged_bitrate_estimator->SetAlrEndedTimeMs(kFirstArrivalTimeMs + diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.cc b/modules/congestion_controller/goog_cc/bitrate_estimator.cc index 4ac65dd2e4..a2c9857ccc 100644 --- a/modules/congestion_controller/goog_cc/bitrate_estimator.cc +++ b/modules/congestion_controller/goog_cc/bitrate_estimator.cc @@ -42,6 +42,7 @@ BitrateEstimator::BitrateEstimator(const WebRtcKeyValueConfig* key_value_config) kMinRateWindowMs, kMaxRateWindowMs), uncertainty_scale_("scale", 10.0), + uncertainty_scale_in_alr_("scale_alr", 10.0), uncertainty_symmetry_cap_("symmetry_cap", DataRate::Zero()), estimate_floor_("floor", DataRate::Zero()), current_window_ms_(0), @@ -49,15 +50,15 @@ BitrateEstimator::BitrateEstimator(const WebRtcKeyValueConfig* key_value_config) bitrate_estimate_kbps_(-1.0f), bitrate_estimate_var_(50.0f) { // E.g WebRTC-BweThroughputWindowConfig/initial_window_ms:350,window_ms:250/ - ParseFieldTrial( - {&initial_window_ms_, &noninitial_window_ms_, &uncertainty_scale_, - &uncertainty_symmetry_cap_, &estimate_floor_}, - key_value_config->Lookup(kBweThroughputWindowConfig)); + ParseFieldTrial({&initial_window_ms_, &noninitial_window_ms_, + &uncertainty_scale_, &uncertainty_scale_in_alr_, + &uncertainty_symmetry_cap_, &estimate_floor_}, + key_value_config->Lookup(kBweThroughputWindowConfig)); } BitrateEstimator::~BitrateEstimator() = default; -void BitrateEstimator::Update(int64_t now_ms, int bytes) { +void BitrateEstimator::Update(int64_t now_ms, int bytes, bool in_alr) { int rate_window_ms = noninitial_window_ms_.Get(); // We use a larger window at the beginning to get a more stable sample that // we can use to initialize the estimate. @@ -75,9 +76,13 @@ void BitrateEstimator::Update(int64_t now_ms, int bytes) { // current estimate. With low values of uncertainty_symmetry_cap_ we add more // uncertainty to increases than to decreases. For higher values we approach // symmetry. + float scale = uncertainty_scale_; + if (in_alr && bitrate_sample_kbps < bitrate_estimate_kbps_) { + // Optionally use higher uncertainty for samples obtained during ALR. + scale = uncertainty_scale_in_alr_; + } float sample_uncertainty = - uncertainty_scale_ * - std::abs(bitrate_estimate_kbps_ - bitrate_sample_kbps) / + scale * std::abs(bitrate_estimate_kbps_ - bitrate_sample_kbps) / (bitrate_estimate_kbps_ + std::min(bitrate_sample_kbps, uncertainty_symmetry_cap_.Get().kbps())); diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.h b/modules/congestion_controller/goog_cc/bitrate_estimator.h index 33866a7482..0ef429b16e 100644 --- a/modules/congestion_controller/goog_cc/bitrate_estimator.h +++ b/modules/congestion_controller/goog_cc/bitrate_estimator.h @@ -29,7 +29,7 @@ class BitrateEstimator { public: explicit BitrateEstimator(const WebRtcKeyValueConfig* key_value_config); virtual ~BitrateEstimator(); - virtual void Update(int64_t now_ms, int bytes); + virtual void Update(int64_t now_ms, int bytes, bool in_alr); virtual absl::optional bitrate_bps() const; absl::optional PeekBps() const; @@ -42,6 +42,7 @@ class BitrateEstimator { FieldTrialConstrained initial_window_ms_; FieldTrialConstrained noninitial_window_ms_; FieldTrialParameter uncertainty_scale_; + FieldTrialParameter uncertainty_scale_in_alr_; FieldTrialParameter uncertainty_symmetry_cap_; FieldTrialParameter estimate_floor_; int64_t current_window_ms_; diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc index 72f4048d3a..95bbf56d7d 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -261,6 +261,9 @@ NetworkControlUpdate GoogCcNetworkController::OnSentPacket( SentPacket sent_packet) { alr_detector_->OnBytesSent(sent_packet.size.bytes(), sent_packet.send_time.ms()); + acknowledged_bitrate_estimator_->SetAlr( + alr_detector_->GetApplicationLimitedRegionStartTime().has_value()); + if (!first_packet_sent_) { first_packet_sent_ = true; // Initialize feedback time to send time to allow estimation of RTT until @@ -507,12 +510,12 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( absl::optional alr_start_time = alr_detector_->GetApplicationLimitedRegionStartTime(); - if (previously_in_alr && !alr_start_time.has_value()) { + if (previously_in_alr_ && !alr_start_time.has_value()) { int64_t now_ms = report.feedback_time.ms(); acknowledged_bitrate_estimator_->SetAlrEndedTimeMs(now_ms); probe_controller_->SetAlrEndedTimeMs(now_ms); } - previously_in_alr = alr_start_time.has_value(); + previously_in_alr_ = alr_start_time.has_value(); acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector( received_feedback_vector); auto acknowledged_bitrate = acknowledged_bitrate_estimator_->bitrate(); diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.h b/modules/congestion_controller/goog_cc/goog_cc_network_control.h index 5314a57726..ef75d7a849 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h @@ -129,7 +129,7 @@ class GoogCcNetworkController : public NetworkControllerInterface { DataRate max_padding_rate_; DataRate max_total_allocated_bitrate_; - bool previously_in_alr = false; + bool previously_in_alr_ = false; absl::optional current_data_window_;