diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc index bcfc131f7a..5554127923 100644 --- a/call/rtp_transport_controller_send.cc +++ b/call/rtp_transport_controller_send.cc @@ -65,8 +65,9 @@ const RtpKeepAliveConfig& RtpTransportControllerSend::keepalive_config() const { void RtpTransportControllerSend::SetAllocatedSendBitrateLimits( int min_send_bitrate_bps, int max_padding_bitrate_bps, - int total_bitrate_bps) { + int max_total_bitrate_bps) { pacer_.SetSendBitrateLimits(min_send_bitrate_bps, max_padding_bitrate_bps); + send_side_cc_->SetMaxTotalAllocatedBitrate(max_total_bitrate_bps); } void RtpTransportControllerSend::SetKeepAliveConfig( diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h index a7c291c544..d786edbc9e 100644 --- a/call/rtp_transport_controller_send.h +++ b/call/rtp_transport_controller_send.h @@ -46,7 +46,7 @@ class RtpTransportControllerSend : public RtpTransportControllerSendInterface { void SetAllocatedSendBitrateLimits(int min_send_bitrate_bps, int max_padding_bitrate_bps, - int total_bitrate_bps) override; + int max_total_bitrate_bps) override; void SetKeepAliveConfig(const RtpKeepAliveConfig& config); void SetPacingFactor(float pacing_factor) override; 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 d07bc34017..4e42a5148e 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -190,7 +190,12 @@ void GoogCcNetworkController::OnSentPacket(SentPacket sent_packet) { void 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_) { + 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; if (msg.pacing_factor && *msg.pacing_factor != pacing_factor_) { pacing_factor_ = *msg.pacing_factor; 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 47ae0842d9..c22596a4f4 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h @@ -80,6 +80,7 @@ class GoogCcNetworkController : public NetworkControllerInterface { double pacing_factor_; DataRate min_pacing_rate_; DataRate max_padding_rate_; + DataRate max_total_allocated_bitrate_; bool in_cwnd_experiment_; int64_t accepted_queue_ms_; diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc index b2570323b0..2f1b5b8061 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.cc +++ b/modules/congestion_controller/goog_cc/probe_controller.cc @@ -133,6 +133,18 @@ void ProbeController::SetBitrates(int64_t min_bitrate_bps, } } +void 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 + // ALR probing? + if (estimated_bitrate_bps_ != 0 && + estimated_bitrate_bps_ < max_bitrate_bps_ && + estimated_bitrate_bps_ < max_total_allocated_bitrate) { + InitiateProbing(at_time_ms, {max_total_allocated_bitrate}, false); + } +} + void ProbeController::OnNetworkAvailability(NetworkAvailability msg) { network_available_ = msg.network_available; if (network_available_ && state_ == State::kInit && start_bitrate_bps_ > 0) diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h index 23fc4f7c49..5649a99b11 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.h +++ b/modules/congestion_controller/goog_cc/probe_controller.h @@ -37,6 +37,11 @@ class ProbeController { 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); + void OnNetworkAvailability(NetworkAvailability msg); void SetEstimatedBitrate(int64_t bitrate_bps, int64_t at_time_ms); diff --git a/modules/congestion_controller/include/send_side_congestion_controller.h b/modules/congestion_controller/include/send_side_congestion_controller.h index 30bc0a991a..1f579f8c45 100644 --- a/modules/congestion_controller/include/send_side_congestion_controller.h +++ b/modules/congestion_controller/include/send_side_congestion_controller.h @@ -67,6 +67,9 @@ class SendSideCongestionController void SetBweBitrates(int min_bitrate_bps, int start_bitrate_bps, int max_bitrate_bps) override; + + void SetMaxTotalAllocatedBitrate(int max_total_allocated_bitrate) override; + // Resets the BWE state. Note the first argument is the bitrate_bps. void OnNetworkRouteChanged(const rtc::NetworkRoute& network_route, int bitrate_bps, diff --git a/modules/congestion_controller/include/send_side_congestion_controller_interface.h b/modules/congestion_controller/include/send_side_congestion_controller_interface.h index f03ffff8c8..0ff3f96277 100644 --- a/modules/congestion_controller/include/send_side_congestion_controller_interface.h +++ b/modules/congestion_controller/include/send_side_congestion_controller_interface.h @@ -49,6 +49,7 @@ class SendSideCongestionControllerInterface : public CallStatsObserver, virtual void SetBweBitrates(int min_bitrate_bps, int start_bitrate_bps, int max_bitrate_bps) = 0; + virtual void SetMaxTotalAllocatedBitrate(int total_bitrate_bps) = 0; virtual void OnNetworkRouteChanged(const rtc::NetworkRoute& network_route, int bitrate_bps, int min_bitrate_bps, diff --git a/modules/congestion_controller/network_control/include/network_types.h b/modules/congestion_controller/network_control/include/network_types.h index 1df3c4e856..bb3637fc87 100644 --- a/modules/congestion_controller/network_control/include/network_types.h +++ b/modules/congestion_controller/network_control/include/network_types.h @@ -33,6 +33,7 @@ struct StreamsConfig { rtc::Optional pacing_factor; rtc::Optional min_pacing_rate; rtc::Optional max_padding_rate; + rtc::Optional max_total_allocated_bitrate; }; struct TargetRateConstraints { diff --git a/modules/congestion_controller/probe_controller.cc b/modules/congestion_controller/probe_controller.cc index 8e6ae7cca1..381eaa2a0b 100644 --- a/modules/congestion_controller/probe_controller.cc +++ b/modules/congestion_controller/probe_controller.cc @@ -125,6 +125,19 @@ void ProbeController::SetBitrates(int64_t min_bitrate_bps, } } +void ProbeController::OnMaxTotalAllocatedBitrate( + int64_t max_total_allocated_bitrate) { + rtc::CritScope cs(&critsect_); + // TODO(philipel): Should |max_total_allocated_bitrate| be used as a limit for + // ALR probing? + if (estimated_bitrate_bps_ != 0 && + estimated_bitrate_bps_ < max_bitrate_bps_ && + estimated_bitrate_bps_ < max_total_allocated_bitrate) { + InitiateProbing(clock_->TimeInMilliseconds(), {max_total_allocated_bitrate}, + false); + } +} + void ProbeController::OnNetworkStateChanged(NetworkState network_state) { rtc::CritScope cs(&critsect_); network_state_ = network_state; diff --git a/modules/congestion_controller/probe_controller.h b/modules/congestion_controller/probe_controller.h index cd0e9b1b57..7c64b4ce10 100644 --- a/modules/congestion_controller/probe_controller.h +++ b/modules/congestion_controller/probe_controller.h @@ -32,6 +32,10 @@ class ProbeController { int64_t start_bitrate_bps, int64_t max_bitrate_bps); + // 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); + void OnNetworkStateChanged(NetworkState state); void SetEstimatedBitrate(int64_t bitrate_bps); diff --git a/modules/congestion_controller/probe_controller_unittest.cc b/modules/congestion_controller/probe_controller_unittest.cc index da333d3c1d..796599aabe 100644 --- a/modules/congestion_controller/probe_controller_unittest.cc +++ b/modules/congestion_controller/probe_controller_unittest.cc @@ -45,6 +45,7 @@ class LegacyProbeControllerTest : public ::testing::Test { } ~LegacyProbeControllerTest() override {} + const int64_t kMbpsMultiplier = 1000000; SimulatedClock clock_; NiceMock pacer_; std::unique_ptr probe_controller_; @@ -253,7 +254,6 @@ TEST_F(LegacyProbeControllerTest, PeriodicProbingAfterReset) { } TEST_F(LegacyProbeControllerTest, TestExponentialProbingOverflow) { - const int64_t kMbpsMultiplier = 1000000; probe_controller_->SetBitrates(kMinBitrateBps, 10 * kMbpsMultiplier, 100 * kMbpsMultiplier); @@ -267,5 +267,23 @@ TEST_F(LegacyProbeControllerTest, TestExponentialProbingOverflow) { probe_controller_->SetEstimatedBitrate(100 * kMbpsMultiplier); } +TEST_F(LegacyProbeControllerTest, TotalBitrateProbing) { + probe_controller_->SetBitrates(kMinBitrateBps, 1 * kMbpsMultiplier, + 2 * kMbpsMultiplier); + + EXPECT_CALL(pacer_, CreateProbeCluster(1 * kMbpsMultiplier)); + probe_controller_->SetEstimatedBitrate(500000); + probe_controller_->OnMaxTotalAllocatedBitrate(1 * kMbpsMultiplier); +} + +TEST_F(LegacyProbeControllerTest, TotalBitrateNoProbing) { + probe_controller_->SetBitrates(kMinBitrateBps, 1 * kMbpsMultiplier, + 2 * kMbpsMultiplier); + + EXPECT_CALL(pacer_, CreateProbeCluster(_)).Times(0); + probe_controller_->SetEstimatedBitrate(500000); + probe_controller_->OnMaxTotalAllocatedBitrate(250000); +} + } // 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 6266f09867..b69f5c0a82 100644 --- a/modules/congestion_controller/rtp/include/send_side_congestion_controller.h +++ b/modules/congestion_controller/rtp/include/send_side_congestion_controller.h @@ -80,6 +80,9 @@ class SendSideCongestionController void SetBweBitrates(int min_bitrate_bps, int start_bitrate_bps, int max_bitrate_bps) override; + + void SetMaxTotalAllocatedBitrate(int max_total_allocated_bitrate) override; + // Resets the BWE state. Note the first argument is the bitrate_bps. void OnNetworkRouteChanged(const rtc::NetworkRoute& network_route, int bitrate_bps, diff --git a/modules/congestion_controller/rtp/send_side_congestion_controller.cc b/modules/congestion_controller/rtp/send_side_congestion_controller.cc index 95cbd98fe8..844d2b1895 100644 --- a/modules/congestion_controller/rtp/send_side_congestion_controller.cc +++ b/modules/congestion_controller/rtp/send_side_congestion_controller.cc @@ -340,6 +340,15 @@ void SendSideCongestionController::SetBweBitrates(int min_bitrate_bps, WaitOnTask([this, msg]() { controller_->OnTargetRateConstraints(msg); }); } +void SendSideCongestionController::SetMaxTotalAllocatedBitrate( + int max_total_allocated_bitrate) { + WaitOnTask([this, max_total_allocated_bitrate]() { + streams_config_.max_total_allocated_bitrate = + DataRate::bps(max_total_allocated_bitrate); + UpdateStreamsConfig(); + }); +} + // TODO(holmer): Split this up and use SetBweBitrates in combination with // OnNetworkRouteChanged. void SendSideCongestionController::OnNetworkRouteChanged( diff --git a/modules/congestion_controller/send_side_congestion_controller.cc b/modules/congestion_controller/send_side_congestion_controller.cc index 2548da9fa0..33bd60ec51 100644 --- a/modules/congestion_controller/send_side_congestion_controller.cc +++ b/modules/congestion_controller/send_side_congestion_controller.cc @@ -190,6 +190,11 @@ void SendSideCongestionController::SetBweBitrates(int min_bitrate_bps, MaybeTriggerOnNetworkChanged(); } +void SendSideCongestionController::SetMaxTotalAllocatedBitrate( + int total_bitrate_bps) { + probe_controller_->OnMaxTotalAllocatedBitrate(total_bitrate_bps); +} + // TODO(holmer): Split this up and use SetBweBitrates in combination with // OnNetworkRouteChanged. void SendSideCongestionController::OnNetworkRouteChanged(