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); }