From da2ec405906b0c42240d80ffe9df1470d7883fa5 Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Thu, 2 Aug 2018 16:27:28 +0200 Subject: [PATCH] Always sends probes when they are generated. This changes makes the usage of the new probe controller reflect how the old probe controller was used. That is probes are now sent as soon as they are generated. This is to avoid regressions in performance doe to the timing of the sent probes. Bug: chromium:868776 Change-Id: I722585689258c9b01e8f1dc47249b284a05a2793 Reviewed-on: https://webrtc-review.googlesource.com/91441 Commit-Queue: Sebastian Jansson Reviewed-by: Philip Eliasson Cr-Commit-Position: refs/heads/master@{#24175} --- .../congestion_controller/goog_cc/BUILD.gn | 1 + .../goog_cc/goog_cc_network_control.cc | 148 +++++++----- .../goog_cc/goog_cc_network_control.h | 13 +- .../goog_cc/probe_controller.cc | 84 +++---- .../goog_cc/probe_controller.h | 42 ++-- .../goog_cc/probe_controller_unittest.cc | 219 ++++++++---------- .../include/send_side_congestion_controller.h | 3 +- .../send_side_congestion_controller.cc | 36 ++- 8 files changed, 283 insertions(+), 263 deletions(-) diff --git a/modules/congestion_controller/goog_cc/BUILD.gn b/modules/congestion_controller/goog_cc/BUILD.gn index 2f89e18dd9..9da2123342 100644 --- a/modules/congestion_controller/goog_cc/BUILD.gn +++ b/modules/congestion_controller/goog_cc/BUILD.gn @@ -135,6 +135,7 @@ rtc_source_set("probe_controller") { "../../../logging:rtc_event_pacing", "../../../rtc_base:checks", "../../../rtc_base:rtc_base_approved", + "../../../rtc_base/system:unused", "../../../system_wrappers:field_trial_api", "../../../system_wrappers:metrics_api", "//third_party/abseil-cpp/absl/types:optional", 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 845ffb8f7f..ef000126b5 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -122,16 +122,18 @@ GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log, delay_based_bwe_(new DelayBasedBwe(event_log_)), acknowledged_bitrate_estimator_( absl::make_unique()), + initial_config_(config), last_bandwidth_(config.starting_bandwidth), - pacing_factor_(kDefaultPaceMultiplier), - min_pacing_rate_(DataRate::Zero()), - max_padding_rate_(DataRate::Zero()), + pacing_factor_(config.stream_based_config.pacing_factor.value_or( + kDefaultPaceMultiplier)), + min_pacing_rate_(config.stream_based_config.min_pacing_rate.value_or( + DataRate::Zero())), + max_padding_rate_(config.stream_based_config.max_padding_rate.value_or( + DataRate::Zero())), max_total_allocated_bitrate_(DataRate::Zero()), in_cwnd_experiment_(CwndExperimentEnabled()), accepted_queue_ms_(kDefaultAcceptedQueueMs) { delay_based_bwe_->SetMinBitrate(congestion_controller::GetMinBitrateBps()); - UpdateBitrateConstraints(config.constraints, config.starting_bandwidth); - OnStreamsConfig(config.stream_based_config); if (in_cwnd_experiment_ && !ReadCwndExperimentParameter(&accepted_queue_ms_)) { RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment " @@ -144,8 +146,9 @@ GoogCcNetworkController::~GoogCcNetworkController() {} NetworkControlUpdate GoogCcNetworkController::OnNetworkAvailability( NetworkAvailability msg) { - probe_controller_->OnNetworkAvailability(msg); - return NetworkControlUpdate(); + NetworkControlUpdate update; + update.probe_cluster_configs = probe_controller_->OnNetworkAvailability(msg); + return update; } NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange( @@ -166,24 +169,46 @@ NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange( delay_based_bwe_->SetMinBitrate(min_bitrate_bps); probe_controller_->Reset(msg.at_time.ms()); - probe_controller_->SetBitrates(min_bitrate_bps, start_bitrate_bps, - max_bitrate_bps, msg.at_time.ms()); - - return MaybeTriggerOnNetworkChanged(msg.at_time); + NetworkControlUpdate update; + update.probe_cluster_configs = probe_controller_->SetBitrates( + min_bitrate_bps, start_bitrate_bps, max_bitrate_bps, msg.at_time.ms()); + MaybeTriggerOnNetworkChanged(&update, msg.at_time); + return update; } NetworkControlUpdate GoogCcNetworkController::OnProcessInterval( ProcessInterval msg) { + NetworkControlUpdate update; + if (initial_config_) { + update.probe_cluster_configs = UpdateBitrateConstraints( + initial_config_->constraints, initial_config_->starting_bandwidth); + update.pacer_config = GetPacingRates(msg.at_time); + + probe_controller_->EnablePeriodicAlrProbing( + initial_config_->stream_based_config.requests_alr_probing); + absl::optional total_bitrate = + initial_config_->stream_based_config.max_total_allocated_bitrate; + if (total_bitrate) { + auto probes = probe_controller_->OnMaxTotalAllocatedBitrate( + total_bitrate->bps(), msg.at_time.ms()); + update.probe_cluster_configs.insert(update.probe_cluster_configs.end(), + probes.begin(), probes.end()); + + max_total_allocated_bitrate_ = *total_bitrate; + } + initial_config_.reset(); + } + bandwidth_estimation_->UpdateEstimate(msg.at_time.ms()); absl::optional start_time_ms = alr_detector_->GetApplicationLimitedRegionStartTime(); probe_controller_->SetAlrStartTimeMs(start_time_ms); - probe_controller_->Process(msg.at_time.ms()); - NetworkControlUpdate update = MaybeTriggerOnNetworkChanged(msg.at_time); - for (const ProbeClusterConfig& config : - probe_controller_->GetAndResetPendingProbes()) { - update.probe_cluster_configs.push_back(config); - } + + auto probes = probe_controller_->Process(msg.at_time.ms()); + update.probe_cluster_configs.insert(update.probe_cluster_configs.end(), + probes.begin(), probes.end()); + + MaybeTriggerOnNetworkChanged(&update, msg.at_time); return update; } @@ -216,11 +241,13 @@ NetworkControlUpdate GoogCcNetworkController::OnSentPacket( NetworkControlUpdate GoogCcNetworkController::OnStreamsConfig( StreamsConfig msg) { + NetworkControlUpdate update; probe_controller_->EnablePeriodicAlrProbing(msg.requests_alr_probing); if (msg.max_total_allocated_bitrate && *msg.max_total_allocated_bitrate != max_total_allocated_bitrate_) { - probe_controller_->OnMaxTotalAllocatedBitrate( - msg.max_total_allocated_bitrate->bps(), msg.at_time.ms()); + update.probe_cluster_configs = + probe_controller_->OnMaxTotalAllocatedBitrate( + msg.max_total_allocated_bitrate->bps(), msg.at_time.ms()); max_total_allocated_bitrate_ = *msg.max_total_allocated_bitrate; } bool pacing_changed = false; @@ -236,19 +263,22 @@ NetworkControlUpdate GoogCcNetworkController::OnStreamsConfig( max_padding_rate_ = *msg.max_padding_rate; pacing_changed = true; } - NetworkControlUpdate update; if (pacing_changed) - update.pacer_config = UpdatePacingRates(msg.at_time); + update.pacer_config = GetPacingRates(msg.at_time); return update; } NetworkControlUpdate GoogCcNetworkController::OnTargetRateConstraints( TargetRateConstraints constraints) { - UpdateBitrateConstraints(constraints, absl::nullopt); - return MaybeTriggerOnNetworkChanged(constraints.at_time); + NetworkControlUpdate update; + update.probe_cluster_configs = + UpdateBitrateConstraints(constraints, absl::nullopt); + MaybeTriggerOnNetworkChanged(&update, constraints.at_time); + return update; } -void GoogCcNetworkController::UpdateBitrateConstraints( +std::vector +GoogCcNetworkController::UpdateBitrateConstraints( TargetRateConstraints constraints, absl::optional starting_rate) { int64_t min_bitrate_bps = GetBpsOrDefault(constraints.min_data_rate, 0); @@ -257,14 +287,16 @@ void GoogCcNetworkController::UpdateBitrateConstraints( ClampBitrates(&start_bitrate_bps, &min_bitrate_bps, &max_bitrate_bps); - probe_controller_->SetBitrates(min_bitrate_bps, start_bitrate_bps, - max_bitrate_bps, constraints.at_time.ms()); + std::vector probes(probe_controller_->SetBitrates( + min_bitrate_bps, start_bitrate_bps, max_bitrate_bps, + constraints.at_time.ms())); bandwidth_estimation_->SetBitrates(start_bitrate_bps, min_bitrate_bps, max_bitrate_bps); if (start_bitrate_bps > 0) delay_based_bwe_->SetStartBitrate(start_bitrate_bps); delay_based_bwe_->SetMinBitrate(min_bitrate_bps); + return probes; } NetworkControlUpdate GoogCcNetworkController::OnTransportLossReport( @@ -326,11 +358,13 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time.ms(), result.target_bitrate_bps); // Update the estimate in the ProbeController, in case we want to probe. - update = MaybeTriggerOnNetworkChanged(report.feedback_time); + MaybeTriggerOnNetworkChanged(&update, report.feedback_time); } if (result.recovered_from_overuse) { probe_controller_->SetAlrStartTimeMs(alr_start_time); - probe_controller_->RequestProbe(report.feedback_time.ms()); + auto probes = probe_controller_->RequestProbe(report.feedback_time.ms()); + update.probe_cluster_configs.insert(update.probe_cluster_configs.end(), + probes.begin(), probes.end()); } update.congestion_window = MaybeUpdateCongestionWindow(); return update; @@ -351,7 +385,7 @@ NetworkControlUpdate GoogCcNetworkController::GetNetworkState( TimeDelta::ms(delay_based_bwe_->GetExpectedBwePeriodMs()); update.target_rate->at_time = at_time; update.target_rate->target_rate = bandwidth; - update.pacer_config = UpdatePacingRates(at_time); + update.pacer_config = GetPacingRates(at_time); update.congestion_window = current_data_window_; return update; } @@ -381,7 +415,8 @@ GoogCcNetworkController::MaybeUpdateCongestionWindow() { return data_window; } -NetworkControlUpdate GoogCcNetworkController::MaybeTriggerOnNetworkChanged( +void GoogCcNetworkController::MaybeTriggerOnNetworkChanged( + NetworkControlUpdate* update, Timestamp at_time) { int32_t estimated_bitrate_bps; uint8_t fraction_loss; @@ -390,19 +425,33 @@ NetworkControlUpdate GoogCcNetworkController::MaybeTriggerOnNetworkChanged( bool estimate_changed = GetNetworkParameters( &estimated_bitrate_bps, &fraction_loss, &rtt_ms, at_time); if (estimate_changed) { + alr_detector_->SetEstimatedBitrate(estimated_bitrate_bps); + + DataRate bandwidth = DataRate::bps(estimated_bitrate_bps); + last_bandwidth_ = bandwidth; + TimeDelta bwe_period = TimeDelta::ms(delay_based_bwe_->GetExpectedBwePeriodMs()); - NetworkEstimate new_estimate; - new_estimate.at_time = at_time; - new_estimate.round_trip_time = TimeDelta::ms(rtt_ms); - new_estimate.bandwidth = DataRate::bps(estimated_bitrate_bps); - new_estimate.loss_rate_ratio = fraction_loss / 255.0f; - new_estimate.bwe_period = bwe_period; - last_bandwidth_ = new_estimate.bandwidth; - return OnNetworkEstimate(new_estimate); + TargetTransferRate target_rate; + target_rate.at_time = at_time; + // Set the target rate to the full estimated bandwidth since the estimation + // for legacy reasons includes target rate constraints. + target_rate.target_rate = bandwidth; + + target_rate.network_estimate.at_time = at_time; + target_rate.network_estimate.round_trip_time = TimeDelta::ms(rtt_ms); + target_rate.network_estimate.bandwidth = bandwidth; + target_rate.network_estimate.loss_rate_ratio = fraction_loss / 255.0f; + target_rate.network_estimate.bwe_period = bwe_period; + update->target_rate = target_rate; + + auto probes = + probe_controller_->SetEstimatedBitrate(bandwidth.bps(), at_time.ms()); + update->probe_cluster_configs.insert(update->probe_cluster_configs.end(), + probes.begin(), probes.end()); + update->pacer_config = GetPacingRates(at_time); } - return NetworkControlUpdate(); } bool GoogCcNetworkController::GetNetworkParameters( @@ -434,26 +483,7 @@ bool GoogCcNetworkController::GetNetworkParameters( return estimate_changed; } -NetworkControlUpdate GoogCcNetworkController::OnNetworkEstimate( - NetworkEstimate estimate) { - NetworkControlUpdate update; - update.pacer_config = UpdatePacingRates(estimate.at_time); - alr_detector_->SetEstimatedBitrate(estimate.bandwidth.bps()); - probe_controller_->SetEstimatedBitrate(estimate.bandwidth.bps(), - estimate.at_time.ms()); - - TargetTransferRate target_rate; - target_rate.at_time = estimate.at_time; - // Set the target rate to the full estimated bandwidth since the estimation - // for legacy reasons includes target rate constraints. - target_rate.target_rate = estimate.bandwidth; - target_rate.network_estimate = estimate; - update.target_rate = target_rate; - return update; -} - -PacerConfig GoogCcNetworkController::UpdatePacingRates( - Timestamp at_time) const { +PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const { DataRate pacing_rate = std::max(min_pacing_rate_, last_bandwidth_) * pacing_factor_; DataRate padding_rate = std::min(max_padding_rate_, last_bandwidth_); 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 186f50cef3..88b487402b 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h @@ -52,16 +52,17 @@ class GoogCcNetworkController : public NetworkControllerInterface { NetworkControlUpdate GetNetworkState(Timestamp at_time) const; private: - void UpdateBitrateConstraints(TargetRateConstraints constraints, - absl::optional starting_rate); + std::vector UpdateBitrateConstraints( + TargetRateConstraints constraints, + absl::optional starting_rate); absl::optional MaybeUpdateCongestionWindow(); - NetworkControlUpdate MaybeTriggerOnNetworkChanged(Timestamp at_time); + void MaybeTriggerOnNetworkChanged(NetworkControlUpdate* update, + Timestamp at_time); bool GetNetworkParameters(int32_t* estimated_bitrate_bps, uint8_t* fraction_loss, int64_t* rtt_ms, Timestamp at_time); - NetworkControlUpdate OnNetworkEstimate(NetworkEstimate msg); - PacerConfig UpdatePacingRates(Timestamp at_time) const; + PacerConfig GetPacingRates(Timestamp at_time) const; RtcEventLog* const event_log_; @@ -72,6 +73,8 @@ class GoogCcNetworkController : public NetworkControllerInterface { std::unique_ptr delay_based_bwe_; std::unique_ptr acknowledged_bitrate_estimator_; + absl::optional initial_config_; + std::deque feedback_rtts_; absl::optional min_feedback_rtt_ms_; diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc index 37763b4e6e..c2a8e023d7 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.cc +++ b/modules/congestion_controller/goog_cc/probe_controller.cc @@ -83,10 +83,11 @@ ProbeController::ProbeController() : enable_periodic_alr_probing_(false) { ProbeController::~ProbeController() {} -void ProbeController::SetBitrates(int64_t min_bitrate_bps, - int64_t start_bitrate_bps, - int64_t max_bitrate_bps, - int64_t at_time_ms) { +std::vector ProbeController::SetBitrates( + int64_t min_bitrate_bps, + int64_t start_bitrate_bps, + int64_t max_bitrate_bps, + int64_t at_time_ms) { if (start_bitrate_bps > 0) { start_bitrate_bps_ = start_bitrate_bps; estimated_bitrate_bps_ = start_bitrate_bps; @@ -102,7 +103,7 @@ void ProbeController::SetBitrates(int64_t min_bitrate_bps, switch (state_) { case State::kInit: if (network_available_) - InitiateExponentialProbing(at_time_ms); + return InitiateExponentialProbing(at_time_ms); break; case State::kWaitingForProbingResult: @@ -125,13 +126,14 @@ void ProbeController::SetBitrates(int64_t min_bitrate_bps, RTC_HISTOGRAM_COUNTS_10000("WebRTC.BWE.MidCallProbing.Initiated", max_bitrate_bps_ / 1000); - InitiateProbing(at_time_ms, {max_bitrate_bps}, false); + return InitiateProbing(at_time_ms, {max_bitrate_bps}, false); } break; } + return std::vector(); } -void ProbeController::OnMaxTotalAllocatedBitrate( +std::vector ProbeController::OnMaxTotalAllocatedBitrate( int64_t max_total_allocated_bitrate, int64_t at_time_ms) { // TODO(philipel): Should |max_total_allocated_bitrate| be used as a limit for @@ -142,11 +144,13 @@ void ProbeController::OnMaxTotalAllocatedBitrate( (max_bitrate_bps_ <= 0 || estimated_bitrate_bps_ < max_bitrate_bps_) && estimated_bitrate_bps_ < max_total_allocated_bitrate) { max_total_allocated_bitrate_ = max_total_allocated_bitrate; - InitiateProbing(at_time_ms, {max_total_allocated_bitrate}, false); + return InitiateProbing(at_time_ms, {max_total_allocated_bitrate}, false); } + return std::vector(); } -void ProbeController::OnNetworkAvailability(NetworkAvailability msg) { +std::vector ProbeController::OnNetworkAvailability( + NetworkAvailability msg) { network_available_ = msg.network_available; if (!network_available_ && state_ == State::kWaitingForProbingResult) { @@ -155,22 +159,25 @@ void ProbeController::OnNetworkAvailability(NetworkAvailability msg) { } if (network_available_ && state_ == State::kInit && start_bitrate_bps_ > 0) - InitiateExponentialProbing(msg.at_time.ms()); + return InitiateExponentialProbing(msg.at_time.ms()); + return std::vector(); } -void ProbeController::InitiateExponentialProbing(int64_t at_time_ms) { +std::vector ProbeController::InitiateExponentialProbing( + int64_t at_time_ms) { RTC_DCHECK(network_available_); RTC_DCHECK(state_ == State::kInit); RTC_DCHECK_GT(start_bitrate_bps_, 0); // When probing at 1.8 Mbps ( 6x 300), this represents a threshold of // 1.2 Mbps to continue probing. - InitiateProbing(at_time_ms, {3 * start_bitrate_bps_, 6 * start_bitrate_bps_}, - true); + return InitiateProbing( + at_time_ms, {3 * start_bitrate_bps_, 6 * start_bitrate_bps_}, true); } -void ProbeController::SetEstimatedBitrate(int64_t bitrate_bps, - int64_t at_time_ms) { +std::vector ProbeController::SetEstimatedBitrate( + int64_t bitrate_bps, + int64_t at_time_ms) { int64_t now_ms = at_time_ms; if (mid_call_probing_waiting_for_result_ && @@ -181,7 +188,7 @@ void ProbeController::SetEstimatedBitrate(int64_t bitrate_bps, bitrate_bps / 1000); mid_call_probing_waiting_for_result_ = false; } - + std::vector pending_probes; if (state_ == State::kWaitingForProbingResult) { // Continue probing if probing results indicate channel has greater // capacity. @@ -192,7 +199,7 @@ void ProbeController::SetEstimatedBitrate(int64_t bitrate_bps, if (min_bitrate_to_probe_further_bps_ != kExponentialProbingDisabled && bitrate_bps > min_bitrate_to_probe_further_bps_) { // Double the probing bitrate. - InitiateProbing(now_ms, {2 * bitrate_bps}, true); + pending_probes = InitiateProbing(now_ms, {2 * bitrate_bps}, true); } } @@ -202,6 +209,7 @@ void ProbeController::SetEstimatedBitrate(int64_t bitrate_bps, } estimated_bitrate_bps_ = bitrate_bps; + return pending_probes; } void ProbeController::EnablePeriodicAlrProbing(bool enable) { @@ -216,7 +224,8 @@ void ProbeController::SetAlrEndedTimeMs(int64_t alr_end_time_ms) { alr_end_time_ms_.emplace(alr_end_time_ms); } -void ProbeController::RequestProbe(int64_t at_time_ms) { +std::vector ProbeController::RequestProbe( + int64_t at_time_ms) { // Called once we have returned to normal state after a large drop in // estimated bandwidth. The current response is to initiate a single probe // session (if not already probing) at the previous bitrate. @@ -243,11 +252,12 @@ void ProbeController::RequestProbe(int64_t at_time_ms) { RTC_HISTOGRAM_COUNTS_10000( "WebRTC.BWE.BweDropProbingIntervalInS", (at_time_ms - last_bwe_drop_probing_time_ms_) / 1000); - InitiateProbing(at_time_ms, {suggested_probe_bps}, false); + return InitiateProbing(at_time_ms, {suggested_probe_bps}, false); last_bwe_drop_probing_time_ms_ = at_time_ms; } } } + return std::vector(); } void ProbeController::Reset(int64_t at_time_ms) { @@ -267,7 +277,7 @@ void ProbeController::Reset(int64_t at_time_ms) { max_total_allocated_bitrate_ = 0; } -void ProbeController::Process(int64_t at_time_ms) { +std::vector ProbeController::Process(int64_t at_time_ms) { int64_t now_ms = at_time_ms; if (now_ms - time_last_probing_initiated_ms_ > @@ -281,32 +291,25 @@ void ProbeController::Process(int64_t at_time_ms) { } } - if (state_ != State::kProbingComplete || !enable_periodic_alr_probing_) - return; - - // Probe bandwidth periodically when in ALR state. - if (alr_start_time_ms_ && estimated_bitrate_bps_ > 0) { - int64_t next_probe_time_ms = - std::max(*alr_start_time_ms_, time_last_probing_initiated_ms_) + - kAlrPeriodicProbingIntervalMs; - if (now_ms >= next_probe_time_ms) { - InitiateProbing(now_ms, {estimated_bitrate_bps_ * 2}, true); + if (enable_periodic_alr_probing_ && state_ == State::kProbingComplete) { + // Probe bandwidth periodically when in ALR state. + if (alr_start_time_ms_ && estimated_bitrate_bps_ > 0) { + int64_t next_probe_time_ms = + std::max(*alr_start_time_ms_, time_last_probing_initiated_ms_) + + kAlrPeriodicProbingIntervalMs; + if (now_ms >= next_probe_time_ms) { + return InitiateProbing(now_ms, {estimated_bitrate_bps_ * 2}, true); + } } } + return std::vector(); } -std::vector ProbeController::GetAndResetPendingProbes() { - if (pending_probes_.empty()) - return std::vector(); - std::vector pending_probes; - pending_probes_.swap(pending_probes); - return pending_probes; -} - -void ProbeController::InitiateProbing( +std::vector ProbeController::InitiateProbing( int64_t now_ms, std::initializer_list bitrates_to_probe, bool probe_further) { + std::vector pending_probes; for (int64_t bitrate : bitrates_to_probe) { RTC_DCHECK_GT(bitrate, 0); int64_t max_probe_bitrate_bps = @@ -321,7 +324,7 @@ void ProbeController::InitiateProbing( config.target_data_rate = DataRate::bps(rtc::dchecked_cast(bitrate)); config.target_duration = TimeDelta::ms(kMinProbeDurationMs); config.target_probe_count = kMinProbePacketsSent; - pending_probes_.push_back(config); + pending_probes.push_back(config); } time_last_probing_initiated_ms_ = now_ms; if (probe_further) { @@ -332,6 +335,7 @@ void ProbeController::InitiateProbing( state_ = State::kProbingComplete; min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled; } + return pending_probes; } } // namespace webrtc diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h index 9f8e8ad5b5..6b6d4ae8b4 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.h +++ b/modules/congestion_controller/goog_cc/probe_controller.h @@ -19,6 +19,7 @@ #include "absl/types/optional.h" #include "api/transport/network_control.h" #include "rtc_base/constructormagic.h" +#include "rtc_base/system/unused.h" namespace webrtc { @@ -32,34 +33,39 @@ class ProbeController { ProbeController(); ~ProbeController(); - void SetBitrates(int64_t min_bitrate_bps, - int64_t start_bitrate_bps, - int64_t max_bitrate_bps, - int64_t at_time_ms); + RTC_WARN_UNUSED_RESULT std::vector SetBitrates( + int64_t min_bitrate_bps, + int64_t start_bitrate_bps, + int64_t max_bitrate_bps, + int64_t at_time_ms); // The total bitrate, as opposed to the max bitrate, is the sum of the // configured bitrates for all active streams. - void OnMaxTotalAllocatedBitrate(int64_t max_total_allocated_bitrate, - int64_t at_time_ms); + RTC_WARN_UNUSED_RESULT std::vector + OnMaxTotalAllocatedBitrate(int64_t max_total_allocated_bitrate, + int64_t at_time_ms); - void OnNetworkAvailability(NetworkAvailability msg); + RTC_WARN_UNUSED_RESULT std::vector OnNetworkAvailability( + NetworkAvailability msg); - void SetEstimatedBitrate(int64_t bitrate_bps, int64_t at_time_ms); + RTC_WARN_UNUSED_RESULT std::vector SetEstimatedBitrate( + int64_t bitrate_bps, + int64_t at_time_ms); void EnablePeriodicAlrProbing(bool enable); void SetAlrStartTimeMs(absl::optional alr_start_time); void SetAlrEndedTimeMs(int64_t alr_end_time); - void RequestProbe(int64_t at_time_ms); + RTC_WARN_UNUSED_RESULT std::vector RequestProbe( + int64_t at_time_ms); // Resets the ProbeController to a state equivalent to as if it was just // created EXCEPT for |enable_periodic_alr_probing_|. void Reset(int64_t at_time_ms); - void Process(int64_t at_time_ms); - - std::vector GetAndResetPendingProbes(); + RTC_WARN_UNUSED_RESULT std::vector Process( + int64_t at_time_ms); private: enum class State { @@ -71,10 +77,12 @@ class ProbeController { kProbingComplete, }; - void InitiateExponentialProbing(int64_t at_time_ms); - void InitiateProbing(int64_t now_ms, - std::initializer_list bitrates_to_probe, - bool probe_further); + RTC_WARN_UNUSED_RESULT std::vector + InitiateExponentialProbing(int64_t at_time_ms); + RTC_WARN_UNUSED_RESULT std::vector InitiateProbing( + int64_t now_ms, + std::initializer_list bitrates_to_probe, + bool probe_further); bool network_available_; State state_; @@ -97,8 +105,6 @@ class ProbeController { int64_t mid_call_probing_bitrate_bps_; int64_t mid_call_probing_succcess_threshold_; - std::vector pending_probes_; - RTC_DISALLOW_COPY_AND_ASSIGN(ProbeController); }; diff --git a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc index ffa131d594..bb2221580d 100644 --- a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc +++ b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc @@ -47,11 +47,11 @@ class ProbeControllerTest : public ::testing::Test { } ~ProbeControllerTest() override {} - void SetNetworkAvailable(bool available) { + std::vector SetNetworkAvailable(bool available) { NetworkAvailability msg; msg.at_time = Timestamp::ms(NowMs()); msg.network_available = available; - probe_controller_->OnNetworkAvailability(msg); + return probe_controller_->OnNetworkAvailability(msg); } int64_t NowMs() { return clock_.TimeInMilliseconds(); } @@ -61,183 +61,165 @@ class ProbeControllerTest : public ::testing::Test { }; TEST_F(ProbeControllerTest, InitiatesProbingAtStart) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - EXPECT_GE(probe_controller_->GetAndResetPendingProbes().size(), 2u); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_GE(probes.size(), 2u); } TEST_F(ProbeControllerTest, ProbeOnlyWhenNetworkIsUp) { SetNetworkAvailable(false); - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 0u); - SetNetworkAvailable(true); - EXPECT_GE(probe_controller_->GetAndResetPendingProbes().size(), 2u); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_EQ(probes.size(), 0u); + probes = SetNetworkAvailable(true); + EXPECT_GE(probes.size(), 2u); } TEST_F(ProbeControllerTest, InitiatesProbingOnMaxBitrateIncrease) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); // Long enough to time out exponential probing. clock_.AdvanceTimeMilliseconds(kExponentialProbingTimeoutMs); - probe_controller_->SetEstimatedBitrate(kStartBitrateBps, NowMs()); - probe_controller_->Process(NowMs()); - EXPECT_GE(probe_controller_->GetAndResetPendingProbes().size(), 2u); - - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps + 100, NowMs()); - - EXPECT_EQ( - probe_controller_->GetAndResetPendingProbes()[0].target_data_rate.bps(), - kMaxBitrateBps + 100); + probes = probe_controller_->SetEstimatedBitrate(kStartBitrateBps, NowMs()); + probes = probe_controller_->Process(NowMs()); + probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps + 100, NowMs()); + EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100); } TEST_F(ProbeControllerTest, InitiatesProbingOnMaxBitrateIncreaseAtMaxBitrate) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); // Long enough to time out exponential probing. clock_.AdvanceTimeMilliseconds(kExponentialProbingTimeoutMs); - probe_controller_->SetEstimatedBitrate(kStartBitrateBps, NowMs()); - probe_controller_->Process(NowMs()); - EXPECT_GE(probe_controller_->GetAndResetPendingProbes().size(), 2u); - - probe_controller_->SetEstimatedBitrate(kMaxBitrateBps, NowMs()); - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps + 100, NowMs()); - EXPECT_EQ( - probe_controller_->GetAndResetPendingProbes()[0].target_data_rate.bps(), - kMaxBitrateBps + 100); + probes = probe_controller_->SetEstimatedBitrate(kStartBitrateBps, NowMs()); + probes = probe_controller_->Process(NowMs()); + probes = probe_controller_->SetEstimatedBitrate(kMaxBitrateBps, NowMs()); + probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps + 100, NowMs()); + EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100); } TEST_F(ProbeControllerTest, TestExponentialProbing) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - probe_controller_->GetAndResetPendingProbes(); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); // Repeated probe should only be sent when estimated bitrate climbs above // 0.7 * 6 * kStartBitrateBps = 1260. - probe_controller_->SetEstimatedBitrate(1000, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 0u); + probes = probe_controller_->SetEstimatedBitrate(1000, NowMs()); + EXPECT_EQ(probes.size(), 0u); - probe_controller_->SetEstimatedBitrate(1800, NowMs()); - EXPECT_EQ( - probe_controller_->GetAndResetPendingProbes()[0].target_data_rate.bps(), - 2 * 1800); + probes = probe_controller_->SetEstimatedBitrate(1800, NowMs()); + EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * 1800); } TEST_F(ProbeControllerTest, TestExponentialProbingTimeout) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - probe_controller_->GetAndResetPendingProbes(); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); // Advance far enough to cause a time out in waiting for probing result. clock_.AdvanceTimeMilliseconds(kExponentialProbingTimeoutMs); - probe_controller_->Process(NowMs()); + probes = probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(1800, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 0u); + probes = probe_controller_->SetEstimatedBitrate(1800, NowMs()); + EXPECT_EQ(probes.size(), 0u); } TEST_F(ProbeControllerTest, RequestProbeInAlr) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - EXPECT_GE(probe_controller_->GetAndResetPendingProbes().size(), 2u); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_GE(probes.size(), 2u); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); probe_controller_->SetAlrStartTimeMs(clock_.TimeInMilliseconds()); clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1); - probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(250, NowMs()); - probe_controller_->RequestProbe(NowMs()); + probes = probe_controller_->Process(NowMs()); + probes = probe_controller_->SetEstimatedBitrate(250, NowMs()); + probes = probe_controller_->RequestProbe(NowMs()); - std::vector probes = - probe_controller_->GetAndResetPendingProbes(); EXPECT_EQ(probes.size(), 1u); EXPECT_EQ(probes[0].target_data_rate.bps(), 0.85 * 500); } TEST_F(ProbeControllerTest, RequestProbeWhenAlrEndedRecently) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 2u); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_EQ(probes.size(), 2u); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); probe_controller_->SetAlrStartTimeMs(absl::nullopt); clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1); - probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(250, NowMs()); + probes = probe_controller_->Process(NowMs()); + probes = probe_controller_->SetEstimatedBitrate(250, NowMs()); probe_controller_->SetAlrEndedTimeMs(clock_.TimeInMilliseconds()); clock_.AdvanceTimeMilliseconds(kAlrEndedTimeoutMs - 1); - probe_controller_->RequestProbe(NowMs()); + probes = probe_controller_->RequestProbe(NowMs()); - std::vector probes = - probe_controller_->GetAndResetPendingProbes(); EXPECT_EQ(probes.size(), 1u); EXPECT_EQ(probes[0].target_data_rate.bps(), 0.85 * 500); } TEST_F(ProbeControllerTest, RequestProbeWhenAlrNotEndedRecently) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 2u); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_EQ(probes.size(), 2u); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); probe_controller_->SetAlrStartTimeMs(absl::nullopt); clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1); - probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(250, NowMs()); + probes = probe_controller_->Process(NowMs()); + probes = probe_controller_->SetEstimatedBitrate(250, NowMs()); probe_controller_->SetAlrEndedTimeMs(clock_.TimeInMilliseconds()); clock_.AdvanceTimeMilliseconds(kAlrEndedTimeoutMs + 1); - probe_controller_->RequestProbe(NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 0u); + probes = probe_controller_->RequestProbe(NowMs()); + EXPECT_EQ(probes.size(), 0u); } TEST_F(ProbeControllerTest, RequestProbeWhenBweDropNotRecent) { - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 2u); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_EQ(probes.size(), 2u); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); probe_controller_->SetAlrStartTimeMs(clock_.TimeInMilliseconds()); clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1); - probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(250, NowMs()); + probes = probe_controller_->Process(NowMs()); + probes = probe_controller_->SetEstimatedBitrate(250, NowMs()); clock_.AdvanceTimeMilliseconds(kBitrateDropTimeoutMs + 1); - probe_controller_->RequestProbe(NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 0u); + probes = probe_controller_->RequestProbe(NowMs()); + EXPECT_EQ(probes.size(), 0u); } TEST_F(ProbeControllerTest, PeriodicProbing) { probe_controller_->EnablePeriodicAlrProbing(true); - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 2u); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_EQ(probes.size(), 2u); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); int64_t start_time = clock_.TimeInMilliseconds(); // Expect the controller to send a new probe after 5s has passed. probe_controller_->SetAlrStartTimeMs(start_time); clock_.AdvanceTimeMilliseconds(5000); - probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - - std::vector probes = - probe_controller_->GetAndResetPendingProbes(); + probes = probe_controller_->Process(NowMs()); EXPECT_EQ(probes.size(), 1u); EXPECT_EQ(probes[0].target_data_rate.bps(), 1000); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); + // The following probe should be sent at 10s into ALR. probe_controller_->SetAlrStartTimeMs(start_time); clock_.AdvanceTimeMilliseconds(4000); - probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 0u); + probes = probe_controller_->Process(NowMs()); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); + EXPECT_EQ(probes.size(), 0u); probe_controller_->SetAlrStartTimeMs(start_time); clock_.AdvanceTimeMilliseconds(1000); - probe_controller_->Process(NowMs()); - probe_controller_->SetEstimatedBitrate(500, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 1u); + probes = probe_controller_->Process(NowMs()); + EXPECT_EQ(probes.size(), 1u); + probes = probe_controller_->SetEstimatedBitrate(500, NowMs()); + EXPECT_EQ(probes.size(), 0u); } TEST_F(ProbeControllerTest, PeriodicProbingAfterReset) { @@ -246,42 +228,39 @@ TEST_F(ProbeControllerTest, PeriodicProbingAfterReset) { probe_controller_->SetAlrStartTimeMs(alr_start_time); probe_controller_->EnablePeriodicAlrProbing(true); - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); + auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); probe_controller_->Reset(NowMs()); clock_.AdvanceTimeMilliseconds(10000); - probe_controller_->Process(NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 2u); + probes = probe_controller_->Process(NowMs()); + // Since bitrates are not yet set, no probe is sent event though we are in ALR + // mode. + EXPECT_EQ(probes.size(), 0u); - probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, - kMaxBitrateBps, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 2u); + probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps, NowMs()); + EXPECT_EQ(probes.size(), 2u); // Make sure we use |kStartBitrateBps| as the estimated bitrate // until SetEstimatedBitrate is called with an updated estimate. clock_.AdvanceTimeMilliseconds(10000); - probe_controller_->Process(NowMs()); - EXPECT_EQ( - probe_controller_->GetAndResetPendingProbes()[0].target_data_rate.bps(), - kStartBitrateBps * 2); + probes = probe_controller_->Process(NowMs()); + EXPECT_EQ(probes[0].target_data_rate.bps(), kStartBitrateBps * 2); } TEST_F(ProbeControllerTest, TestExponentialProbingOverflow) { const int64_t kMbpsMultiplier = 1000000; - probe_controller_->SetBitrates(kMinBitrateBps, 10 * kMbpsMultiplier, - 100 * kMbpsMultiplier, NowMs()); - - probe_controller_->SetEstimatedBitrate(60 * kMbpsMultiplier, NowMs()); - + auto probes = probe_controller_->SetBitrates( + kMinBitrateBps, 10 * kMbpsMultiplier, 100 * kMbpsMultiplier, NowMs()); // Verify that probe bitrate is capped at the specified max bitrate. - EXPECT_EQ( - probe_controller_->GetAndResetPendingProbes()[2].target_data_rate.bps(), - 100 * kMbpsMultiplier); - + probes = + probe_controller_->SetEstimatedBitrate(60 * kMbpsMultiplier, NowMs()); + EXPECT_EQ(probes[0].target_data_rate.bps(), 100 * kMbpsMultiplier); // Verify that repeated probes aren't sent. - probe_controller_->SetEstimatedBitrate(100 * kMbpsMultiplier, NowMs()); - EXPECT_EQ(probe_controller_->GetAndResetPendingProbes().size(), 0u); + probes = + probe_controller_->SetEstimatedBitrate(100 * kMbpsMultiplier, NowMs()); + EXPECT_EQ(probes.size(), 0u); } } // namespace test diff --git a/modules/congestion_controller/include/send_side_congestion_controller.h b/modules/congestion_controller/include/send_side_congestion_controller.h index f4270eadcc..9d4f852686 100644 --- a/modules/congestion_controller/include/send_side_congestion_controller.h +++ b/modules/congestion_controller/include/send_side_congestion_controller.h @@ -132,7 +132,8 @@ class SendSideCongestionController uint8_t fraction_loss, int64_t rtt); void LimitOutstandingBytes(size_t num_outstanding_bytes); - void SendPendingProbes() RTC_EXCLUSIVE_LOCKS_REQUIRED(&probe_lock_); + void SendProbes(std::vector probe_configs) + RTC_EXCLUSIVE_LOCKS_REQUIRED(&probe_lock_); const Clock* const clock_; rtc::CriticalSection observer_lock_; Observer* observer_ RTC_GUARDED_BY(observer_lock_); diff --git a/modules/congestion_controller/send_side_congestion_controller.cc b/modules/congestion_controller/send_side_congestion_controller.cc index 12cfb4d55f..0439c1d567 100644 --- a/modules/congestion_controller/send_side_congestion_controller.cc +++ b/modules/congestion_controller/send_side_congestion_controller.cc @@ -200,10 +200,9 @@ void SendSideCongestionController::SetBweBitrates(int min_bitrate_bps, { rtc::CritScope cs(&probe_lock_); - probe_controller_->SetBitrates(min_bitrate_bps, start_bitrate_bps, - max_bitrate_bps, - clock_->TimeInMilliseconds()); - SendPendingProbes(); + SendProbes(probe_controller_->SetBitrates( + min_bitrate_bps, start_bitrate_bps, max_bitrate_bps, + clock_->TimeInMilliseconds())); } { @@ -223,9 +222,8 @@ void SendSideCongestionController::SetAllocatedSendBitrateLimits( pacer_->SetSendBitrateLimits(min_send_bitrate_bps, max_padding_bitrate_bps); rtc::CritScope cs(&probe_lock_); - probe_controller_->OnMaxTotalAllocatedBitrate(max_total_bitrate_bps, - clock_->TimeInMilliseconds()); - SendPendingProbes(); + SendProbes(probe_controller_->OnMaxTotalAllocatedBitrate( + max_total_bitrate_bps, clock_->TimeInMilliseconds())); } // TODO(holmer): Split this up and use SetBweBitrates in combination with @@ -255,10 +253,9 @@ void SendSideCongestionController::OnNetworkRouteChanged( { rtc::CritScope cs(&probe_lock_); probe_controller_->Reset(clock_->TimeInMilliseconds()); - probe_controller_->SetBitrates(min_bitrate_bps, bitrate_bps, - max_bitrate_bps, - clock_->TimeInMilliseconds()); - SendPendingProbes(); + SendProbes(probe_controller_->SetBitrates(min_bitrate_bps, bitrate_bps, + max_bitrate_bps, + clock_->TimeInMilliseconds())); } MaybeTriggerOnNetworkChanged(); @@ -321,8 +318,7 @@ void SendSideCongestionController::SignalNetworkState(NetworkState state) { NetworkAvailability msg; msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds()); msg.network_available = state == kNetworkUp; - probe_controller_->OnNetworkAvailability(msg); - SendPendingProbes(); + SendProbes(probe_controller_->OnNetworkAvailability(msg)); } MaybeTriggerOnNetworkChanged(); } @@ -355,8 +351,9 @@ int64_t SendSideCongestionController::TimeUntilNextProcess() { return bitrate_controller_->TimeUntilNextProcess(); } -void SendSideCongestionController::SendPendingProbes() { - for (auto probe_config : probe_controller_->GetAndResetPendingProbes()) { +void SendSideCongestionController::SendProbes( + std::vector probe_configs) { + for (auto probe_config : probe_configs) { pacer_->CreateProbeCluster(probe_config.target_data_rate.bps()); } } @@ -382,8 +379,7 @@ void SendSideCongestionController::Process() { rtc::CritScope cs(&probe_lock_); probe_controller_->SetAlrStartTimeMs( pacer_->GetApplicationLimitedRegionStartTime()); - probe_controller_->Process(clock_->TimeInMilliseconds()); - SendPendingProbes(); + SendProbes(probe_controller_->Process(clock_->TimeInMilliseconds())); } MaybeTriggerOnNetworkChanged(); } @@ -437,7 +433,7 @@ void SendSideCongestionController::OnTransportFeedback( rtc::CritScope cs(&probe_lock_); probe_controller_->SetAlrStartTimeMs( pacer_->GetApplicationLimitedRegionStartTime()); - probe_controller_->RequestProbe(clock_->TimeInMilliseconds()); + SendProbes(probe_controller_->RequestProbe(clock_->TimeInMilliseconds())); } if (in_cwnd_experiment_) { LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes()); @@ -501,8 +497,8 @@ void SendSideCongestionController::MaybeTriggerOnNetworkChanged() { pacer_->SetEstimatedBitrate(bitrate_bps); { rtc::CritScope cs(&probe_lock_); - probe_controller_->SetEstimatedBitrate(bitrate_bps, - clock_->TimeInMilliseconds()); + SendProbes(probe_controller_->SetEstimatedBitrate( + bitrate_bps, clock_->TimeInMilliseconds())); } retransmission_rate_limiter_->SetMaxRate(bitrate_bps); }