From ae9057831f8487fb4d798fdf34233e1c49cdc306 Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Mon, 9 Apr 2018 13:21:35 +0200 Subject: [PATCH] Removed observer from network controller interface. Moving the responsibility for calling callbacks from implementations of NetworkControllerInterface to SendSideCongestionController. This decreases the coupling and makes the callbacks more explicit. Bug: webrtc:8415 Change-Id: Ie75effbde01533106080bb6c40308b0c20064c45 Reviewed-on: https://webrtc-review.googlesource.com/66882 Commit-Queue: Sebastian Jansson Reviewed-by: Niels Moller Cr-Commit-Position: refs/heads/master@{#22793} --- .../congestion_controller/bbr/bbr_factory.cc | 3 +- .../congestion_controller/bbr/bbr_factory.h | 1 - .../bbr/bbr_network_controller.cc | 66 +++++++----- .../bbr/bbr_network_controller.h | 28 ++--- .../bbr/bbr_network_controller_unittest.cc | 54 +++++----- .../goog_cc/goog_cc_factory.cc | 3 +- .../goog_cc/goog_cc_network_control.cc | 100 +++++++++++------- .../goog_cc/goog_cc_network_control.h | 32 +++--- .../goog_cc/include/goog_cc_factory.h | 1 - .../network_control/include/network_control.h | 36 +++---- .../network_control/include/network_types.h | 14 +++ .../network_control/network_types.cc | 5 + .../test/mock_network_control.h | 5 +- .../test/network_control_tester.cc | 71 ++++++------- .../test/network_control_tester.h | 30 +----- .../include/send_side_congestion_controller.h | 2 + .../rtp/send_side_congestion_controller.cc | 52 +++++---- 17 files changed, 264 insertions(+), 239 deletions(-) diff --git a/modules/congestion_controller/bbr/bbr_factory.cc b/modules/congestion_controller/bbr/bbr_factory.cc index 2b7ed04377..3d5febac68 100644 --- a/modules/congestion_controller/bbr/bbr_factory.cc +++ b/modules/congestion_controller/bbr/bbr_factory.cc @@ -19,9 +19,8 @@ namespace webrtc { BbrNetworkControllerFactory::BbrNetworkControllerFactory() {} std::unique_ptr BbrNetworkControllerFactory::Create( - NetworkControllerObserver* observer, NetworkControllerConfig config) { - return rtc::MakeUnique(observer, config); + return rtc::MakeUnique(config); } TimeDelta BbrNetworkControllerFactory::GetProcessInterval() const { diff --git a/modules/congestion_controller/bbr/bbr_factory.h b/modules/congestion_controller/bbr/bbr_factory.h index 8e91d9fdd3..d740d69817 100644 --- a/modules/congestion_controller/bbr/bbr_factory.h +++ b/modules/congestion_controller/bbr/bbr_factory.h @@ -21,7 +21,6 @@ class BbrNetworkControllerFactory : public NetworkControllerFactoryInterface { public: BbrNetworkControllerFactory(); std::unique_ptr Create( - NetworkControllerObserver* observer, NetworkControllerConfig config) override; TimeDelta GetProcessInterval() const override; }; diff --git a/modules/congestion_controller/bbr/bbr_network_controller.cc b/modules/congestion_controller/bbr/bbr_network_controller.cc index 81ca741e84..7664cb928a 100644 --- a/modules/congestion_controller/bbr/bbr_network_controller.cc +++ b/modules/congestion_controller/bbr/bbr_network_controller.cc @@ -176,10 +176,8 @@ BbrNetworkController::DebugState::DebugState(const BbrNetworkController& sender) BbrNetworkController::DebugState::DebugState(const DebugState& state) = default; -BbrNetworkController::BbrNetworkController(NetworkControllerObserver* observer, - NetworkControllerConfig config) - : observer_(observer), - random_(10), +BbrNetworkController::BbrNetworkController(NetworkControllerConfig config) + : random_(10), max_bandwidth_(kBandwidthWindowSize, DataRate::Zero(), 0), default_bandwidth_(kInitialBandwidth), max_ack_height_(kBandwidthWindowSize, DataSize::Zero(), 0), @@ -195,7 +193,6 @@ BbrNetworkController::BbrNetworkController(NetworkControllerObserver* observer, constraints_ = config.constraints; Reset(); EnterStartupMode(); - SignalUpdatedRates(config.constraints.at_time); } BbrNetworkController::~BbrNetworkController() {} @@ -213,7 +210,7 @@ void BbrNetworkController::Reset() { EnterStartupMode(); } -void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) { +NetworkControlUpdate BbrNetworkController::CreateRateUpdate(Timestamp at_time) { DataRate bandwidth = BandwidthEstimate(); if (bandwidth.IsZero()) bandwidth = default_bandwidth_; @@ -237,7 +234,7 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) { last_update_state_.pacing_rate == pacing_rate && last_update_state_.target_rate == target_rate && last_update_state_.probing_for_bandwidth == probing_for_bandwidth) - return; + return NetworkControlUpdate(); last_update_state_.mode = mode_; last_update_state_.bandwidth = bandwidth; last_update_state_.rtt = rtt; @@ -254,6 +251,8 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) { << ", Probing:" << probing_for_bandwidth << ", pacing_gain: " << pacing_gain_; + NetworkControlUpdate update; + TargetTransferRate target_rate_msg; target_rate_msg.network_estimate.at_time = at_time; target_rate_msg.network_estimate.bandwidth = bandwidth; @@ -265,7 +264,7 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) { target_rate_msg.target_rate = target_rate; target_rate_msg.at_time = at_time; - observer_->OnTargetTransferRate(target_rate_msg); + update.target_rate = target_rate_msg; PacerConfig pacer_config; // A small time window ensures an even pacing rate. @@ -278,46 +277,56 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) { pacer_config.pad_window = DataSize::Zero(); pacer_config.at_time = at_time; - observer_->OnPacerConfig(pacer_config); + update.pacer_config = pacer_config; CongestionWindow congestion_window; congestion_window.data_window = GetCongestionWindow(); - observer_->OnCongestionWindow(congestion_window); + update.congestion_window = congestion_window; + return update; } -void BbrNetworkController::OnNetworkAvailability(NetworkAvailability msg) { +NetworkControlUpdate BbrNetworkController::OnNetworkAvailability( + NetworkAvailability msg) { Reset(); rtt_stats_.OnConnectionMigration(); - SignalUpdatedRates(msg.at_time); + return CreateRateUpdate(msg.at_time); } -void BbrNetworkController::OnNetworkRouteChange(NetworkRouteChange msg) { +NetworkControlUpdate BbrNetworkController::OnNetworkRouteChange( + NetworkRouteChange msg) { constraints_ = msg.constraints; Reset(); if (msg.starting_rate.IsFinite()) default_bandwidth_ = msg.starting_rate; rtt_stats_.OnConnectionMigration(); - SignalUpdatedRates(msg.at_time); + return CreateRateUpdate(msg.at_time); } -void BbrNetworkController::OnProcessInterval(ProcessInterval) {} +NetworkControlUpdate BbrNetworkController::OnProcessInterval( + ProcessInterval msg) { + return CreateRateUpdate(msg.at_time); +} -void BbrNetworkController::OnStreamsConfig(StreamsConfig msg) {} +NetworkControlUpdate BbrNetworkController::OnStreamsConfig(StreamsConfig msg) { + return NetworkControlUpdate(); +} -void BbrNetworkController::OnTargetRateConstraints(TargetRateConstraints msg) { +NetworkControlUpdate BbrNetworkController::OnTargetRateConstraints( + TargetRateConstraints msg) { constraints_ = msg; - SignalUpdatedRates(msg.at_time); + return CreateRateUpdate(msg.at_time); } bool BbrNetworkController::InSlowStart() const { return mode_ == STARTUP; } -void BbrNetworkController::OnSentPacket(SentPacket msg) { +NetworkControlUpdate BbrNetworkController::OnSentPacket(SentPacket msg) { last_send_time_ = msg.send_time; if (!aggregation_epoch_start_time_.IsInitialized()) { aggregation_epoch_start_time_ = msg.send_time; } + return NetworkControlUpdate(); } bool BbrNetworkController::CanSend(DataSize bytes_in_flight) { @@ -365,7 +374,7 @@ bool BbrNetworkController::IsProbingForMoreBandwidth() const { return (mode_ == PROBE_BW && pacing_gain_ > 1) || mode_ == STARTUP; } -void BbrNetworkController::OnTransportPacketsFeedback( +NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback( TransportPacketsFeedback msg) { Timestamp feedback_recv_time = msg.feedback_time; rtc::Optional last_sent_packet = @@ -443,12 +452,21 @@ void BbrNetworkController::OnTransportPacketsFeedback( CalculatePacingRate(); CalculateCongestionWindow(total_acked_size); CalculateRecoveryWindow(total_acked_size, bytes_lost, bytes_in_flight); - SignalUpdatedRates(msg.feedback_time); + return CreateRateUpdate(msg.feedback_time); } -void BbrNetworkController::OnRemoteBitrateReport(RemoteBitrateReport msg) {} -void BbrNetworkController::OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) {} -void BbrNetworkController::OnTransportLossReport(TransportLossReport msg) {} +NetworkControlUpdate BbrNetworkController::OnRemoteBitrateReport( + RemoteBitrateReport msg) { + return NetworkControlUpdate(); +} +NetworkControlUpdate BbrNetworkController::OnRoundTripTimeUpdate( + RoundTripTimeUpdate msg) { + return NetworkControlUpdate(); +} +NetworkControlUpdate BbrNetworkController::OnTransportLossReport( + TransportLossReport msg) { + return NetworkControlUpdate(); +} TimeDelta BbrNetworkController::GetMinRtt() const { return !min_rtt_.IsZero() ? min_rtt_ diff --git a/modules/congestion_controller/bbr/bbr_network_controller.h b/modules/congestion_controller/bbr/bbr_network_controller.h index be3be4976d..dc2b13c902 100644 --- a/modules/congestion_controller/bbr/bbr_network_controller.h +++ b/modules/congestion_controller/bbr/bbr_network_controller.h @@ -95,23 +95,24 @@ class BbrNetworkController : public NetworkControllerInterface { Timestamp end_of_app_limited_phase; }; - BbrNetworkController(NetworkControllerObserver* observer, - NetworkControllerConfig config); + explicit BbrNetworkController(NetworkControllerConfig config); ~BbrNetworkController() override; // NetworkControllerInterface - void OnNetworkAvailability(NetworkAvailability msg) override; - void OnNetworkRouteChange(NetworkRouteChange msg) override; - void OnProcessInterval(ProcessInterval msg) override; - void OnSentPacket(SentPacket msg) override; - void OnStreamsConfig(StreamsConfig msg) override; - void OnTargetRateConstraints(TargetRateConstraints msg) override; - void OnTransportPacketsFeedback(TransportPacketsFeedback msg) override; + NetworkControlUpdate OnNetworkAvailability(NetworkAvailability msg) override; + NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange msg) override; + NetworkControlUpdate OnProcessInterval(ProcessInterval msg) override; + NetworkControlUpdate OnSentPacket(SentPacket msg) override; + NetworkControlUpdate OnStreamsConfig(StreamsConfig msg) override; + NetworkControlUpdate OnTargetRateConstraints( + TargetRateConstraints msg) override; + NetworkControlUpdate OnTransportPacketsFeedback( + TransportPacketsFeedback msg) override; // Part of remote bitrate estimation api, not implemented for BBR - void OnRemoteBitrateReport(RemoteBitrateReport msg) override; - void OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; - void OnTransportLossReport(TransportLossReport msg) override; + NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override; + NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; + NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override; private: struct BbrControllerConfig { @@ -168,7 +169,7 @@ class BbrNetworkController : public NetworkControllerInterface { }; void Reset(); - void SignalUpdatedRates(Timestamp at_time); + NetworkControlUpdate CreateRateUpdate(Timestamp at_time); bool InSlowStart() const; bool InRecovery() const; @@ -260,7 +261,6 @@ class BbrNetworkController : public NetworkControllerInterface { void CalculateRecoveryWindow(DataSize bytes_acked, DataSize bytes_lost, DataSize bytes_in_flight); - NetworkControllerObserver* observer_; RttStats rtt_stats_; webrtc::Random random_; diff --git a/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc b/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc index cd3f50c7ca..df596eb67a 100644 --- a/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc +++ b/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc @@ -13,8 +13,8 @@ #include "modules/congestion_controller/bbr/bbr_factory.h" #include "modules/congestion_controller/bbr/bbr_network_controller.h" -#include "modules/congestion_controller/network_control/test/mock_network_control.h" #include "modules/congestion_controller/network_control/test/network_control_tester.h" +#include "test/gmock.h" #include "test/gtest.h" using testing::Field; @@ -57,6 +57,12 @@ NetworkControllerConfig InitialConfig( return config; } +ProcessInterval InitialProcessInterval() { + ProcessInterval process_interval; + process_interval.at_time = kDefaultStartTime; + return process_interval; +} + NetworkRouteChange CreateRouteChange(Timestamp at_time, DataRate start_rate, DataRate min_rate = DataRate::Zero(), @@ -77,37 +83,37 @@ class BbrNetworkControllerTest : public ::testing::Test { ~BbrNetworkControllerTest() override {} }; -TEST_F(BbrNetworkControllerTest, SendsConfigurationOnInitialization) { - StrictMock observer; - EXPECT_CALL(observer, - OnTargetTransferRate(TargetRateCloseTo(kInitialBitrate))); - EXPECT_CALL(observer, OnPacerConfig(Property(&PacerConfig::data_rate, - Ge(kInitialBitrate)))); - EXPECT_CALL(observer, - OnCongestionWindow(Field(&CongestionWindow::data_window, - Property(&DataSize::IsFinite, true)))); - +TEST_F(BbrNetworkControllerTest, SendsConfigurationOnFirstProcess) { std::unique_ptr controller_; - controller_.reset(new BbrNetworkController(&observer, InitialConfig())); - testing::Mock::VerifyAndClearExpectations(&observer); + controller_.reset(new BbrNetworkController(InitialConfig())); + + NetworkControlUpdate update = + controller_->OnProcessInterval(InitialProcessInterval()); + EXPECT_THAT(*update.target_rate, TargetRateCloseTo(kInitialBitrate)); + EXPECT_THAT(*update.pacer_config, + Property(&PacerConfig::data_rate, Ge(kInitialBitrate))); + EXPECT_THAT(*update.congestion_window, + Field(&CongestionWindow::data_window, + Property(&DataSize::IsFinite, true))); } TEST_F(BbrNetworkControllerTest, SendsConfigurationOnNetworkRouteChanged) { - StrictMock observer; - EXPECT_CALL(observer, OnTargetTransferRate(_)); - EXPECT_CALL(observer, OnPacerConfig(_)); - EXPECT_CALL(observer, OnCongestionWindow(_)); std::unique_ptr controller_; - controller_.reset(new BbrNetworkController(&observer, InitialConfig())); + controller_.reset(new BbrNetworkController(InitialConfig())); + + NetworkControlUpdate update = + controller_->OnProcessInterval(InitialProcessInterval()); + EXPECT_TRUE(update.target_rate.has_value()); + EXPECT_TRUE(update.pacer_config.has_value()); + EXPECT_TRUE(update.congestion_window.has_value()); DataRate new_bitrate = DataRate::bps(200000); - EXPECT_CALL(observer, OnTargetTransferRate(TargetRateCloseTo(new_bitrate))); - EXPECT_CALL(observer, OnPacerConfig(Property(&PacerConfig::data_rate, - Ge(kInitialBitrate)))); - EXPECT_CALL(observer, OnCongestionWindow(_)); - controller_->OnNetworkRouteChange( + update = controller_->OnNetworkRouteChange( CreateRouteChange(kDefaultStartTime, new_bitrate)); - testing::Mock::VerifyAndClearExpectations(&observer); + EXPECT_THAT(*update.target_rate, TargetRateCloseTo(new_bitrate)); + EXPECT_THAT(*update.pacer_config, + Property(&PacerConfig::data_rate, Ge(kInitialBitrate))); + EXPECT_TRUE(update.congestion_window.has_value()); } // Bandwidth estimation is updated when feedbacks are received. diff --git a/modules/congestion_controller/goog_cc/goog_cc_factory.cc b/modules/congestion_controller/goog_cc/goog_cc_factory.cc index 88d52ee604..b8ed7862df 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_factory.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_factory.cc @@ -18,10 +18,9 @@ GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory( : event_log_(event_log) {} NetworkControllerInterface::uptr GoogCcNetworkControllerFactory::Create( - NetworkControllerObserver* observer, NetworkControllerConfig config) { return rtc::MakeUnique(event_log_, - observer, config); + config); } TimeDelta GoogCcNetworkControllerFactory::GetProcessInterval() const { 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 517ef1d69e..6eff9d2ca2 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -103,12 +103,9 @@ std::vector ReceivedPacketsFeedbackAsRtp( } // namespace -GoogCcNetworkController::GoogCcNetworkController( - RtcEventLog* event_log, - NetworkControllerObserver* observer, - NetworkControllerConfig config) +GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log, + NetworkControllerConfig config) : event_log_(event_log), - observer_(observer), probe_controller_(new ProbeController()), bandwidth_estimation_( rtc::MakeUnique(event_log_)), @@ -134,11 +131,14 @@ GoogCcNetworkController::GoogCcNetworkController( GoogCcNetworkController::~GoogCcNetworkController() {} -void GoogCcNetworkController::OnNetworkAvailability(NetworkAvailability msg) { +NetworkControlUpdate GoogCcNetworkController::OnNetworkAvailability( + NetworkAvailability msg) { probe_controller_->OnNetworkAvailability(msg); + return NetworkControlUpdate(); } -void GoogCcNetworkController::OnNetworkRouteChange(NetworkRouteChange msg) { +NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange( + NetworkRouteChange msg) { int64_t min_bitrate_bps = msg.constraints.min_data_rate.bps_or(-1); int64_t max_bitrate_bps = msg.constraints.max_data_rate.bps_or(-1); int64_t start_bitrate_bps = msg.starting_rate.bps_or(-1); @@ -158,45 +158,53 @@ void GoogCcNetworkController::OnNetworkRouteChange(NetworkRouteChange msg) { probe_controller_->SetBitrates(min_bitrate_bps, start_bitrate_bps, max_bitrate_bps, msg.at_time.ms()); - MaybeTriggerOnNetworkChanged(msg.at_time); + return MaybeTriggerOnNetworkChanged(msg.at_time); } -void GoogCcNetworkController::OnProcessInterval(ProcessInterval msg) { +NetworkControlUpdate GoogCcNetworkController::OnProcessInterval( + ProcessInterval msg) { bandwidth_estimation_->UpdateEstimate(msg.at_time.ms()); rtc::Optional start_time_ms = alr_detector_->GetApplicationLimitedRegionStartTime(); probe_controller_->SetAlrStartTimeMs(start_time_ms); probe_controller_->Process(msg.at_time.ms()); - - for (const ProbeClusterConfig& probe : + NetworkControlUpdate update = MaybeTriggerOnNetworkChanged(msg.at_time); + for (const ProbeClusterConfig& config : probe_controller_->GetAndResetPendingProbes()) { - observer_->OnProbeClusterConfig(probe); + update.probe_cluster_configs.push_back(config); } - MaybeTriggerOnNetworkChanged(msg.at_time); + return update; } -void GoogCcNetworkController::OnRemoteBitrateReport(RemoteBitrateReport msg) { +NetworkControlUpdate GoogCcNetworkController::OnRemoteBitrateReport( + RemoteBitrateReport msg) { bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time.ms(), msg.bandwidth.bps()); BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(), msg.bandwidth.bps() / 1000); + return NetworkControlUpdate(); } -void GoogCcNetworkController::OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) { +NetworkControlUpdate GoogCcNetworkController::OnRoundTripTimeUpdate( + RoundTripTimeUpdate msg) { if (msg.smoothed) { delay_based_bwe_->OnRttUpdate(msg.round_trip_time.ms()); } else { bandwidth_estimation_->UpdateRtt(msg.round_trip_time.ms(), msg.receive_time.ms()); } + return NetworkControlUpdate(); } -void GoogCcNetworkController::OnSentPacket(SentPacket sent_packet) { +NetworkControlUpdate GoogCcNetworkController::OnSentPacket( + SentPacket sent_packet) { alr_detector_->OnBytesSent(sent_packet.size.bytes(), sent_packet.send_time.ms()); + return NetworkControlUpdate(); } -void GoogCcNetworkController::OnStreamsConfig(StreamsConfig msg) { +NetworkControlUpdate GoogCcNetworkController::OnStreamsConfig( + StreamsConfig msg) { probe_controller_->EnablePeriodicAlrProbing(msg.requests_alr_probing); if (msg.max_total_allocated_bitrate && *msg.max_total_allocated_bitrate != max_total_allocated_bitrate_) { @@ -217,13 +225,17 @@ void GoogCcNetworkController::OnStreamsConfig(StreamsConfig msg) { max_padding_rate_ = *msg.max_padding_rate; pacing_changed = true; } + NetworkControlUpdate update; if (pacing_changed) - UpdatePacingRates(msg.at_time); + update.pacer_config = UpdatePacingRates(msg.at_time); + return update; } -void GoogCcNetworkController::OnTargetRateConstraints( +NetworkControlUpdate GoogCcNetworkController::OnTargetRateConstraints( TargetRateConstraints constraints) { + NetworkControlUpdate update; UpdateBitrateConstraints(constraints, DataRate()); + return MaybeTriggerOnNetworkChanged(constraints.at_time); } void GoogCcNetworkController::UpdateBitrateConstraints( @@ -243,18 +255,18 @@ void GoogCcNetworkController::UpdateBitrateConstraints( if (start_bitrate_bps > 0) delay_based_bwe_->SetStartBitrate(start_bitrate_bps); delay_based_bwe_->SetMinBitrate(min_bitrate_bps); - - MaybeTriggerOnNetworkChanged(constraints.at_time); } -void GoogCcNetworkController::OnTransportLossReport(TransportLossReport msg) { +NetworkControlUpdate GoogCcNetworkController::OnTransportLossReport( + TransportLossReport msg) { int64_t total_packets_delta = msg.packets_received_delta + msg.packets_lost_delta; bandwidth_estimation_->UpdatePacketsLost( msg.packets_lost_delta, total_packets_delta, msg.receive_time.ms()); + return NetworkControlUpdate(); } -void GoogCcNetworkController::OnTransportPacketsFeedback( +NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( TransportPacketsFeedback report) { int64_t feedback_rtt = -1; for (const auto& packet_feedback : report.PacketsWithFeedback()) { @@ -294,6 +306,7 @@ void GoogCcNetworkController::OnTransportPacketsFeedback( result = delay_based_bwe_->IncomingPacketFeedbackVector( received_feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps(), report.feedback_time.ms()); + NetworkControlUpdate update; if (result.updated) { if (result.probe) { bandwidth_estimation_->SetSendBitrate(result.target_bitrate_bps); @@ -303,24 +316,26 @@ void 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. - MaybeTriggerOnNetworkChanged(report.feedback_time); + update = MaybeTriggerOnNetworkChanged(report.feedback_time); } if (result.recovered_from_overuse) { probe_controller_->SetAlrStartTimeMs(alr_start_time); probe_controller_->RequestProbe(report.feedback_time.ms()); } - MaybeUpdateCongestionWindow(); + update.congestion_window = MaybeUpdateCongestionWindow(); + return update; } -void GoogCcNetworkController::MaybeUpdateCongestionWindow() { +rtc::Optional +GoogCcNetworkController::MaybeUpdateCongestionWindow() { if (!in_cwnd_experiment_) - return; + return rtc::nullopt; // No valid RTT. Could be because send-side BWE isn't used, in which case // we don't try to limit the outstanding packets. if (!min_feedback_rtt_ms_) - return; + return rtc::nullopt; if (!last_estimate_.has_value()) - return; + return rtc::nullopt; const DataSize kMinCwnd = DataSize::bytes(2 * 1500); TimeDelta time_window = TimeDelta::ms(*min_feedback_rtt_ms_ + accepted_queue_ms_); @@ -328,12 +343,13 @@ void GoogCcNetworkController::MaybeUpdateCongestionWindow() { CongestionWindow msg; msg.enabled = true; msg.data_window = std::max(kMinCwnd, data_window); - observer_->OnCongestionWindow(msg); RTC_LOG(LS_INFO) << "Feedback rtt: " << *min_feedback_rtt_ms_ << " Bitrate: " << last_estimate_->bandwidth.bps(); + return msg; } -void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(Timestamp at_time) { +NetworkControlUpdate GoogCcNetworkController::MaybeTriggerOnNetworkChanged( + Timestamp at_time) { int32_t estimated_bitrate_bps; uint8_t fraction_loss; int64_t rtt_ms; @@ -352,8 +368,9 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(Timestamp at_time) { new_estimate.bwe_period = bwe_period; new_estimate.changed = true; last_estimate_ = new_estimate; - OnNetworkEstimate(new_estimate); + return OnNetworkEstimate(new_estimate); } + return NetworkControlUpdate(); } bool GoogCcNetworkController::GetNetworkParameters( @@ -385,11 +402,13 @@ bool GoogCcNetworkController::GetNetworkParameters( return estimate_changed; } -void GoogCcNetworkController::OnNetworkEstimate(NetworkEstimate estimate) { +NetworkControlUpdate GoogCcNetworkController::OnNetworkEstimate( + NetworkEstimate estimate) { + NetworkControlUpdate update; if (!estimate.changed) - return; + return update; - UpdatePacingRates(estimate.at_time); + update.pacer_config = UpdatePacingRates(estimate.at_time); alr_detector_->SetEstimatedBitrate(estimate.bandwidth.bps()); probe_controller_->SetEstimatedBitrate(estimate.bandwidth.bps(), estimate.at_time.ms()); @@ -400,12 +419,12 @@ void GoogCcNetworkController::OnNetworkEstimate(NetworkEstimate estimate) { // for legacy reasons includes target rate constraints. target_rate.target_rate = estimate.bandwidth; target_rate.network_estimate = estimate; - observer_->OnTargetTransferRate(target_rate); + update.target_rate = target_rate; + return update; } -void GoogCcNetworkController::UpdatePacingRates(Timestamp at_time) { - if (!last_estimate_) - return; +PacerConfig GoogCcNetworkController::UpdatePacingRates(Timestamp at_time) { + RTC_DCHECK(last_estimate_); DataRate pacing_rate = std::max(min_pacing_rate_, last_estimate_->bandwidth) * pacing_factor_; DataRate padding_rate = @@ -415,8 +434,7 @@ void GoogCcNetworkController::UpdatePacingRates(Timestamp at_time) { msg.time_window = TimeDelta::s(1); msg.data_window = pacing_rate * msg.time_window; msg.pad_window = padding_rate * msg.time_window; - observer_->OnPacerConfig(msg); + return msg; } - } // namespace webrtc_cc } // namespace webrtc 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 12e22a815b..71b74986cd 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h @@ -32,36 +32,36 @@ namespace webrtc_cc { class GoogCcNetworkController : public NetworkControllerInterface { public: GoogCcNetworkController(RtcEventLog* event_log, - NetworkControllerObserver* observer, NetworkControllerConfig config); ~GoogCcNetworkController() override; // NetworkControllerInterface - void OnNetworkAvailability(NetworkAvailability msg) override; - void OnNetworkRouteChange(NetworkRouteChange msg) override; - void OnProcessInterval(ProcessInterval msg) override; - void OnRemoteBitrateReport(RemoteBitrateReport msg) override; - void OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; - void OnSentPacket(SentPacket msg) override; - void OnStreamsConfig(StreamsConfig msg) override; - void OnTargetRateConstraints(TargetRateConstraints msg) override; - void OnTransportLossReport(TransportLossReport msg) override; - void OnTransportPacketsFeedback(TransportPacketsFeedback msg) override; + NetworkControlUpdate OnNetworkAvailability(NetworkAvailability msg) override; + NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange msg) override; + NetworkControlUpdate OnProcessInterval(ProcessInterval msg) override; + NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override; + NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; + NetworkControlUpdate OnSentPacket(SentPacket msg) override; + NetworkControlUpdate OnStreamsConfig(StreamsConfig msg) override; + NetworkControlUpdate OnTargetRateConstraints( + TargetRateConstraints msg) override; + NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override; + NetworkControlUpdate OnTransportPacketsFeedback( + TransportPacketsFeedback msg) override; private: void UpdateBitrateConstraints(TargetRateConstraints constraints, DataRate starting_rate); - void MaybeUpdateCongestionWindow(); - void MaybeTriggerOnNetworkChanged(Timestamp at_time); + rtc::Optional MaybeUpdateCongestionWindow(); + NetworkControlUpdate MaybeTriggerOnNetworkChanged(Timestamp at_time); bool GetNetworkParameters(int32_t* estimated_bitrate_bps, uint8_t* fraction_loss, int64_t* rtt_ms, Timestamp at_time); - void OnNetworkEstimate(NetworkEstimate msg); - void UpdatePacingRates(Timestamp at_time); + NetworkControlUpdate OnNetworkEstimate(NetworkEstimate msg); + PacerConfig UpdatePacingRates(Timestamp at_time); RtcEventLog* const event_log_; - NetworkControllerObserver* const observer_; const std::unique_ptr probe_controller_; diff --git a/modules/congestion_controller/goog_cc/include/goog_cc_factory.h b/modules/congestion_controller/goog_cc/include/goog_cc_factory.h index 3e48462c9b..37fbe1ab7c 100644 --- a/modules/congestion_controller/goog_cc/include/goog_cc_factory.h +++ b/modules/congestion_controller/goog_cc/include/goog_cc_factory.h @@ -21,7 +21,6 @@ class GoogCcNetworkControllerFactory public: explicit GoogCcNetworkControllerFactory(RtcEventLog*); NetworkControllerInterface::uptr Create( - NetworkControllerObserver* observer, NetworkControllerConfig config) override; TimeDelta GetProcessInterval() const override; diff --git a/modules/congestion_controller/network_control/include/network_control.h b/modules/congestion_controller/network_control/include/network_control.h index 1bff82a589..49b18ea38d 100644 --- a/modules/congestion_controller/network_control/include/network_control.h +++ b/modules/congestion_controller/network_control/include/network_control.h @@ -28,19 +28,6 @@ class TargetTransferRateObserver { virtual ~TargetTransferRateObserver() = default; }; -// NetworkControllerObserver is an interface implemented by observers of network -// controllers. It contains declarations of the possible configuration messages -// that can be sent from a network controller implementation. -class NetworkControllerObserver : public TargetTransferRateObserver { - public: - // Called when congestion window configutation is changed. - virtual void OnCongestionWindow(CongestionWindow) = 0; - // Called when pacer configuration has changed. - virtual void OnPacerConfig(PacerConfig) = 0; - // Called to indicate that a new probe should be sent. - virtual void OnProbeClusterConfig(ProbeClusterConfig) = 0; -}; - // Configuration sent to factory create function. The parameters here are // optional to use for a network controller implementation. struct NetworkControllerConfig { @@ -67,26 +54,28 @@ class NetworkControllerInterface { virtual ~NetworkControllerInterface() = default; // Called when network availabilty changes. - virtual void OnNetworkAvailability(NetworkAvailability) = 0; + virtual NetworkControlUpdate OnNetworkAvailability(NetworkAvailability) = 0; // Called when the receiving or sending endpoint changes address. - virtual void OnNetworkRouteChange(NetworkRouteChange) = 0; + virtual NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange) = 0; // Called periodically with a periodicy as specified by // NetworkControllerFactoryInterface::GetProcessInterval. - virtual void OnProcessInterval(ProcessInterval) = 0; + virtual NetworkControlUpdate OnProcessInterval(ProcessInterval) = 0; // Called when remotely calculated bitrate is received. - virtual void OnRemoteBitrateReport(RemoteBitrateReport) = 0; + virtual NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport) = 0; // Called round trip time has been calculated by protocol specific mechanisms. - virtual void OnRoundTripTimeUpdate(RoundTripTimeUpdate) = 0; + virtual NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate) = 0; // Called when a packet is sent on the network. - virtual void OnSentPacket(SentPacket) = 0; + virtual NetworkControlUpdate OnSentPacket(SentPacket) = 0; // Called when the stream specific configuration has been updated. - virtual void OnStreamsConfig(StreamsConfig) = 0; + virtual NetworkControlUpdate OnStreamsConfig(StreamsConfig) = 0; // Called when target transfer rate constraints has been changed. - virtual void OnTargetRateConstraints(TargetRateConstraints) = 0; + virtual NetworkControlUpdate OnTargetRateConstraints( + TargetRateConstraints) = 0; // Called when a protocol specific calculation of packet loss has been made. - virtual void OnTransportLossReport(TransportLossReport) = 0; + virtual NetworkControlUpdate OnTransportLossReport(TransportLossReport) = 0; // Called with per packet feedback regarding receive time. - virtual void OnTransportPacketsFeedback(TransportPacketsFeedback) = 0; + virtual NetworkControlUpdate OnTransportPacketsFeedback( + TransportPacketsFeedback) = 0; }; // NetworkControllerFactoryInterface is an interface for creating a network @@ -97,7 +86,6 @@ class NetworkControllerFactoryInterface { // Used to create a new network controller, requires an observer to be // provided to handle callbacks. virtual NetworkControllerInterface::uptr Create( - NetworkControllerObserver* observer, NetworkControllerConfig config) = 0; // Returns the interval by which the network controller expects // OnProcessInterval calls. diff --git a/modules/congestion_controller/network_control/include/network_types.h b/modules/congestion_controller/network_control/include/network_types.h index 15849c7aca..7a858eb2d6 100644 --- a/modules/congestion_controller/network_control/include/network_types.h +++ b/modules/congestion_controller/network_control/include/network_types.h @@ -63,6 +63,7 @@ struct SentPacket { }; struct PacerQueueUpdate { + Timestamp at_time; TimeDelta expected_queue_time; }; @@ -160,6 +161,19 @@ struct TargetTransferRate { NetworkEstimate network_estimate; }; +// Contains updates of network controller comand state. Using optionals to +// indicate whether a member has been updated. The array of probe clusters +// should be used to send out probes if not empty. +struct NetworkControlUpdate { + NetworkControlUpdate(); + NetworkControlUpdate(const NetworkControlUpdate&); + ~NetworkControlUpdate(); + rtc::Optional congestion_window; + rtc::Optional pacer_config; + std::vector probe_cluster_configs; + rtc::Optional target_rate; +}; + // Process control struct ProcessInterval { Timestamp at_time; diff --git a/modules/congestion_controller/network_control/network_types.cc b/modules/congestion_controller/network_control/network_types.cc index 8a0b37e49c..a786f613dc 100644 --- a/modules/congestion_controller/network_control/network_types.cc +++ b/modules/congestion_controller/network_control/network_types.cc @@ -51,4 +51,9 @@ std::vector TransportPacketsFeedback::PacketsWithFeedback() return packet_feedbacks; } +NetworkControlUpdate::NetworkControlUpdate() = default; +NetworkControlUpdate::NetworkControlUpdate(const NetworkControlUpdate&) = + default; +NetworkControlUpdate::~NetworkControlUpdate() = default; + } // namespace webrtc diff --git a/modules/congestion_controller/network_control/test/mock_network_control.h b/modules/congestion_controller/network_control/test/mock_network_control.h index 72b503442c..dddcdd1193 100644 --- a/modules/congestion_controller/network_control/test/mock_network_control.h +++ b/modules/congestion_controller/network_control/test/mock_network_control.h @@ -16,11 +16,8 @@ namespace webrtc { namespace test { -class MockNetworkControllerObserver : public NetworkControllerObserver { +class MockTargetTransferRateObserver : public TargetTransferRateObserver { public: - MOCK_METHOD1(OnCongestionWindow, void(CongestionWindow)); - MOCK_METHOD1(OnPacerConfig, void(PacerConfig)); - MOCK_METHOD1(OnProbeClusterConfig, void(ProbeClusterConfig)); MOCK_METHOD1(OnTargetTransferRate, void(TargetTransferRate)); }; } // namespace test diff --git a/modules/congestion_controller/network_control/test/network_control_tester.cc b/modules/congestion_controller/network_control/test/network_control_tester.cc index 8c0ffc06db..08d62ef15f 100644 --- a/modules/congestion_controller/network_control/test/network_control_tester.cc +++ b/modules/congestion_controller/network_control/test/network_control_tester.cc @@ -17,36 +17,33 @@ #include "rtc_base/logging.h" namespace webrtc { namespace test { - -NetworkControlState::NetworkControlState() = default; -NetworkControlState::~NetworkControlState() = default; -NetworkControlState::NetworkControlState(const NetworkControlState&) = default; - -NetworkControlCacher::NetworkControlCacher() = default; -NetworkControlCacher::~NetworkControlCacher() = default; - -void NetworkControlCacher::OnCongestionWindow(CongestionWindow msg) { - current_state_.congestion_window = msg; - RTC_LOG(LS_INFO) << "Received window=" << msg.data_window << "\n"; -} -void NetworkControlCacher::OnPacerConfig(PacerConfig msg) { - current_state_.pacer_config = msg; - RTC_LOG(LS_INFO) << "Received pacing at:" << msg.at_time - << ": rate=" << msg.data_rate() << "\n"; -} -void NetworkControlCacher::OnProbeClusterConfig(ProbeClusterConfig msg) { - current_state_.probe_config = msg; - RTC_LOG(LS_INFO) << "Received probe at:" << msg.at_time - << ": target=" << msg.target_data_rate << "\n"; -} -void NetworkControlCacher::OnTargetTransferRate(TargetTransferRate msg) { - current_state_.target_rate = msg; - RTC_LOG(LS_INFO) << "Received target at:" << msg.at_time - << ": rate=" << msg.target_rate << "\n"; +namespace { +void Update(NetworkControlUpdate* target, const NetworkControlUpdate& update) { + if (update.congestion_window) { + RTC_LOG(LS_INFO) << "Received window=" + << update.congestion_window->data_window << "\n"; + target->congestion_window = update.congestion_window; + } + if (update.pacer_config) { + RTC_LOG(LS_INFO) << "Received pacing at:" << update.pacer_config->at_time + << ": rate=" << update.pacer_config->data_rate() << "\n"; + target->pacer_config = update.pacer_config; + } + if (update.target_rate) { + RTC_LOG(LS_INFO) << "Received target at:" << update.target_rate->at_time + << ": rate=" << update.target_rate->target_rate << "\n"; + target->target_rate = update.target_rate; + } + for (const auto& probe : update.probe_cluster_configs) { + target->probe_cluster_configs.push_back(probe); + RTC_LOG(LS_INFO) << "Received probe at:" << probe.at_time + << ": target=" << probe.target_data_rate << "\n"; + } } +} // namespace SentPacket SimpleTargetRateProducer::ProduceNext( - const NetworkControlState& cache, + const NetworkControlUpdate& cache, Timestamp current_time, TimeDelta time_delta) { DataRate actual_send_rate = @@ -63,8 +60,11 @@ NetworkControllerTester::NetworkControllerTester( : current_time_(Timestamp::seconds(100000)), accumulated_delay_(TimeDelta::ms(0)) { initial_config.constraints.at_time = current_time_; - controller_ = factory->Create(&cacher_, initial_config); + controller_ = factory->Create(initial_config); process_interval_ = factory->GetProcessInterval(); + ProcessInterval interval_msg; + interval_msg.at_time = current_time_; + state_ = controller_->OnProcessInterval(interval_msg); } NetworkControllerTester::~NetworkControllerTester() = default; @@ -94,21 +94,18 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration, Timestamp last_process_time = current_time_; while (current_time_ - start_time < duration) { bool send_packet = true; - NetworkControlState control_state = cacher_.GetState(); - - if (control_state.congestion_window && - control_state.congestion_window->enabled) { + if (state_.congestion_window && state_.congestion_window->enabled) { DataSize data_in_flight = DataSize::Zero(); for (PacketResult& packet : outstanding_packets_) data_in_flight += packet.sent_packet->size; - if (data_in_flight > control_state.congestion_window->data_window) + if (data_in_flight > state_.congestion_window->data_window) send_packet = false; } if (send_packet) { SentPacket sent_packet = - next_packet(cacher_.GetState(), current_time_, packet_interval); - controller_->OnSentPacket(sent_packet); + next_packet(state_, current_time_, packet_interval); + Update(&state_, controller_->OnSentPacket(sent_packet)); outstanding_packets_.push_back(SimulateSend( sent_packet, packet_interval, propagation_delay, actual_bandwidth)); } @@ -131,13 +128,13 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration, feedback.data_in_flight = DataSize::Zero(); for (PacketResult& packet : outstanding_packets_) feedback.data_in_flight += packet.sent_packet->size; - controller_->OnTransportPacketsFeedback(feedback); + Update(&state_, controller_->OnTransportPacketsFeedback(feedback)); } current_time_ += packet_interval; if (current_time_ - last_process_time > process_interval_) { ProcessInterval interval_msg; interval_msg.at_time = current_time_; - controller_->OnProcessInterval(interval_msg); + Update(&state_, controller_->OnProcessInterval(interval_msg)); } } } diff --git a/modules/congestion_controller/network_control/test/network_control_tester.h b/modules/congestion_controller/network_control/test/network_control_tester.h index 744011ed41..857e0c5d8f 100644 --- a/modules/congestion_controller/network_control/test/network_control_tester.h +++ b/modules/congestion_controller/network_control/test/network_control_tester.h @@ -20,36 +20,14 @@ namespace webrtc { namespace test { -struct NetworkControlState { - NetworkControlState(); - NetworkControlState(const NetworkControlState&); - ~NetworkControlState(); - rtc::Optional congestion_window; - rtc::Optional pacer_config; - rtc::Optional probe_config; - rtc::Optional target_rate; -}; // Produces one packet per time delta class SimpleTargetRateProducer { public: - static SentPacket ProduceNext(const NetworkControlState& state, + static SentPacket ProduceNext(const NetworkControlUpdate& state, Timestamp current_time, TimeDelta time_delta); }; -class NetworkControlCacher : public NetworkControllerObserver { - public: - NetworkControlCacher(); - ~NetworkControlCacher() override; - void OnCongestionWindow(CongestionWindow msg) override; - void OnPacerConfig(PacerConfig msg) override; - void OnProbeClusterConfig(ProbeClusterConfig) override; - void OnTargetTransferRate(TargetTransferRate msg) override; - NetworkControlState GetState() { return current_state_; } - - private: - NetworkControlState current_state_; -}; class NetworkControllerTester { public: @@ -58,7 +36,7 @@ class NetworkControllerTester { // times (This allows the PacketProducer to be stateless). It returns a // SentPacket struct with actual send time and packet size. using PacketProducer = std::function< - SentPacket(const NetworkControlState&, Timestamp, TimeDelta)>; + SentPacket(const NetworkControlUpdate&, Timestamp, TimeDelta)>; NetworkControllerTester(NetworkControllerFactoryInterface* factory, NetworkControllerConfig initial_config); ~NetworkControllerTester(); @@ -78,19 +56,19 @@ class NetworkControllerTester { DataRate actual_bandwidth, TimeDelta propagation_delay, PacketProducer next_packet); - NetworkControlState GetState() { return cacher_.GetState(); } + NetworkControlUpdate GetState() { return state_; } private: PacketResult SimulateSend(SentPacket packet, TimeDelta time_delta, TimeDelta propagation_delay, DataRate actual_bandwidth); - NetworkControlCacher cacher_; std::unique_ptr controller_; TimeDelta process_interval_; Timestamp current_time_; TimeDelta accumulated_delay_; std::deque outstanding_packets_; + NetworkControlUpdate state_; }; } // namespace test } // namespace webrtc diff --git a/modules/congestion_controller/rtp/include/send_side_congestion_controller.h b/modules/congestion_controller/rtp/include/send_side_congestion_controller.h index db992030b7..b51f2b457e 100644 --- a/modules/congestion_controller/rtp/include/send_side_congestion_controller.h +++ b/modules/congestion_controller/rtp/include/send_side_congestion_controller.h @@ -163,6 +163,8 @@ class SendSideCongestionController int64_t now_ms) RTC_RUN_ON(task_queue_ptr_); + void PostUpdates(NetworkControlUpdate update) RTC_RUN_ON(task_queue_ptr_); + const Clock* const clock_; // PacedSender is thread safe and doesn't need protection here. PacedSender* const pacer_; diff --git a/modules/congestion_controller/rtp/send_side_congestion_controller.cc b/modules/congestion_controller/rtp/send_side_congestion_controller.cc index 4e1a1b1209..47ec85adfd 100644 --- a/modules/congestion_controller/rtp/send_side_congestion_controller.cc +++ b/modules/congestion_controller/rtp/send_side_congestion_controller.cc @@ -156,17 +156,16 @@ static PeriodicTask* StartPeriodicTask(rtc::TaskQueue* task_queue, } // namespace namespace send_side_cc_internal { - -class ControlHandler : public NetworkControllerObserver { +class ControlHandler { public: ControlHandler(NetworkChangedObserver* observer, PacerController* pacer_controller, const Clock* clock); - void OnCongestionWindow(CongestionWindow window) override; - void OnPacerConfig(PacerConfig config) override; - void OnProbeClusterConfig(ProbeClusterConfig config) override; - void OnTargetTransferRate(TargetTransferRate target_rate) override; + void OnCongestionWindow(CongestionWindow window); + void OnPacerConfig(PacerConfig config); + void OnProbeClusterConfig(ProbeClusterConfig config); + void OnTargetTransferRate(TargetTransferRate target_rate); void OnNetworkAvailability(NetworkAvailability msg); void OnPacerQueueUpdate(PacerQueueUpdate msg); @@ -350,7 +349,6 @@ SendSideCongestionController::SendSideCongestionController( task_queue_ptr_ = task_queue_.get(); initial_config_.constraints = ConvertConstraints(min_bitrate_bps, max_bitrate_bps, clock_); - initial_config_.stream_based_config = StreamsConfig(); RTC_DCHECK(start_bitrate_bps > 0); initial_config_.starting_bandwidth = DataRate::bps(start_bitrate_bps); } @@ -388,18 +386,15 @@ void SendSideCongestionController::MaybeRecreateControllers() { if (!controller_ || (feedback_only_controller != feedback_only_controller_)) { if (feedback_only_controller) { RTC_LOG(LS_INFO) << "Creating feedback based only controller"; - controller_ = controller_factory_with_feedback_->Create( - control_handler_.get(), initial_config_); + controller_ = controller_factory_with_feedback_->Create(initial_config_); process_interval_ = controller_factory_with_feedback_->GetProcessInterval(); } else { RTC_LOG(LS_INFO) << "Creating fallback controller"; - controller_ = controller_factory_fallback_->Create(control_handler_.get(), - initial_config_); + controller_ = controller_factory_fallback_->Create(initial_config_); process_interval_ = controller_factory_fallback_->GetProcessInterval(); } feedback_only_controller_ = feedback_only_controller; - UpdateStreamsConfig(); UpdateControllerWithTimeInterval(); StartProcessPeriodicTasks(); } @@ -442,7 +437,7 @@ void SendSideCongestionController::SetBweBitrates(int min_bitrate_bps, task_queue_->PostTask([this, constraints, start_bitrate_bps]() { RTC_DCHECK_RUN_ON(task_queue_ptr_); if (controller_) { - controller_->OnTargetRateConstraints(constraints); + PostUpdates(controller_->OnTargetRateConstraints(constraints)); } else { initial_config_.constraints = constraints; if (start_bitrate_bps > 0) @@ -485,7 +480,7 @@ void SendSideCongestionController::OnNetworkRouteChanged( start_bitrate_bps > 0 ? DataRate::bps(start_bitrate_bps) : DataRate(); task_queue_->PostTask([this, msg]() { RTC_DCHECK_RUN_ON(task_queue_ptr_); - controller_->OnNetworkRouteChange(msg); + PostUpdates(controller_->OnNetworkRouteChange(msg)); pacer_controller_->OnNetworkRouteChange(msg); }); } @@ -535,7 +530,7 @@ void SendSideCongestionController::EnablePeriodicAlrProbing(bool enable) { void SendSideCongestionController::UpdateStreamsConfig() { streams_config_.at_time = Timestamp::ms(clock_->TimeInMilliseconds()); if (controller_) - controller_->OnStreamsConfig(streams_config_); + PostUpdates(controller_->OnStreamsConfig(streams_config_)); } TransportFeedbackObserver* @@ -553,7 +548,7 @@ void SendSideCongestionController::SignalNetworkState(NetworkState state) { RTC_DCHECK_RUN_ON(task_queue_ptr_); network_available_ = msg.network_available; if (controller_) { - controller_->OnNetworkAvailability(msg); + PostUpdates(controller_->OnNetworkAvailability(msg)); pacer_controller_->OnNetworkAvailability(msg); control_handler_->OnNetworkAvailability(msg); } else { @@ -579,7 +574,7 @@ void SendSideCongestionController::OnSentPacket( task_queue_->PostTask([this, msg]() { RTC_DCHECK_RUN_ON(task_queue_ptr_); if (controller_) - controller_->OnSentPacket(msg); + PostUpdates(controller_->OnSentPacket(msg)); }); } } @@ -594,7 +589,7 @@ void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, task_queue_->PostTask([this, report]() { RTC_DCHECK_RUN_ON(task_queue_ptr_); if (controller_) - controller_->OnRoundTripTimeUpdate(report); + PostUpdates(controller_->OnRoundTripTimeUpdate(report)); }); } @@ -639,7 +634,7 @@ void SendSideCongestionController::UpdateControllerWithTimeInterval() { if (controller_) { ProcessInterval msg; msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds()); - controller_->OnProcessInterval(msg); + PostUpdates(controller_->OnProcessInterval(msg)); } } @@ -687,7 +682,7 @@ void SendSideCongestionController::OnTransportFeedback( task_queue_->PostTask([this, msg]() { RTC_DCHECK_RUN_ON(task_queue_ptr_); if (controller_) - controller_->OnTransportPacketsFeedback(msg); + PostUpdates(controller_->OnTransportPacketsFeedback(msg)); }); } } @@ -702,6 +697,17 @@ void SendSideCongestionController::MaybeUpdateOutstandingData() { }); } +void SendSideCongestionController::PostUpdates(NetworkControlUpdate update) { + if (update.congestion_window) + control_handler_->OnCongestionWindow(*update.congestion_window); + if (update.pacer_config) + control_handler_->OnPacerConfig(*update.pacer_config); + for (const auto& probe : update.probe_cluster_configs) + control_handler_->OnProbeClusterConfig(probe); + if (update.target_rate) + control_handler_->OnTargetTransferRate(*update.target_rate); +} + std::vector SendSideCongestionController::GetTransportFeedbackVector() const { RTC_DCHECK_RUNS_SERIALIZED(&worker_race_); @@ -745,7 +751,7 @@ void SendSideCongestionController::OnReceivedEstimatedBitrate( task_queue_->PostTask([this, msg]() { RTC_DCHECK_RUN_ON(task_queue_ptr_); if (controller_) - controller_->OnRemoteBitrateReport(msg); + PostUpdates(controller_->OnRemoteBitrateReport(msg)); }); } @@ -765,7 +771,7 @@ void SendSideCongestionController::OnReceivedRtcpReceiverReport( report.round_trip_time = TimeDelta::ms(rtt_ms); report.smoothed = false; if (controller_) - controller_->OnRoundTripTimeUpdate(report); + PostUpdates(controller_->OnRoundTripTimeUpdate(report)); }); } @@ -809,7 +815,7 @@ void SendSideCongestionController::OnReceivedRtcpReceiverReportBlocks( msg.start_time = last_report_block_time_; msg.end_time = now; if (controller_) - controller_->OnTransportLossReport(msg); + PostUpdates(controller_->OnTransportLossReport(msg)); last_report_block_time_ = now; } } // namespace webrtc_cc