Using struct for bitrate allocation limits.

Bug: webrtc:9883
Change-Id: I855c29808ffa14626d78842491fdf81cd00589e6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153344
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29227}
diff --git a/api/transport/network_types.h b/api/transport/network_types.h
index 038f151..c8c6d3c 100644
--- a/api/transport/network_types.h
+++ b/api/transport/network_types.h
@@ -24,6 +24,19 @@
 
 // Configuration
 
+// Represents constraints and rates related to the currently enabled streams.
+// This is used as input to the congestion controller via the StreamsConfig
+// struct.
+struct BitrateAllocationLimits {
+  // The total minimum send bitrate required by all sending streams.
+  DataRate min_allocatable_rate = DataRate::Zero();
+  // The total maximum allocatable bitrate for all currently available streams.
+  DataRate max_allocatable_rate = DataRate::Zero();
+  // The max bitrate to use for padding. The sum of the per-stream max padding
+  // rate.
+  DataRate max_padding_rate = DataRate::Zero();
+};
+
 // Use StreamsConfig for information about streams that is required for specific
 // adjustments to the algorithms in network controllers. Especially useful
 // for experiments.
@@ -35,6 +48,7 @@
   absl::optional<bool> requests_alr_probing;
   absl::optional<double> pacing_factor;
 
+  // TODO(srte): Use BitrateAllocationLimits here.
   absl::optional<DataRate> min_total_allocated_bitrate;
   absl::optional<DataRate> max_padding_rate;
   absl::optional<DataRate> max_total_allocated_bitrate;
diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc
index 3bb16c7..a61ce22 100644
--- a/audio/audio_send_stream_unittest.cc
+++ b/audio/audio_send_stream_unittest.cc
@@ -88,10 +88,7 @@
 
 class MockLimitObserver : public BitrateAllocator::LimitObserver {
  public:
-  MOCK_METHOD3(OnAllocationLimitsChanged,
-               void(uint32_t min_send_bitrate_bps,
-                    uint32_t max_padding_bitrate_bps,
-                    uint32_t total_bitrate_bps));
+  MOCK_METHOD1(OnAllocationLimitsChanged, void(BitrateAllocationLimits));
 };
 
 std::unique_ptr<MockAudioEncoder> SetupAudioEncoderMock(
diff --git a/call/BUILD.gn b/call/BUILD.gn
index 61034d2..cf70067 100644
--- a/call/BUILD.gn
+++ b/call/BUILD.gn
@@ -197,6 +197,7 @@
   ]
   deps = [
     "../api:bitrate_allocation",
+    "../api/transport:network_control",
     "../api/units:data_rate",
     "../api/units:time_delta",
     "../rtc_base:checks",
diff --git a/call/bitrate_allocator.cc b/call/bitrate_allocator.cc
index a5259f2..c13848f 100644
--- a/call/bitrate_allocator.cc
+++ b/call/bitrate_allocator.cc
@@ -63,9 +63,6 @@
       num_pause_events_(0),
       clock_(clock),
       last_bwe_log_time_(0),
-      total_requested_padding_bitrate_(0),
-      total_requested_min_bitrate_(0),
-      total_requested_max_bitrate_(0),
       transmission_max_bitrate_multiplier_(
           GetTransmissionMaxBitrateMultiplier()) {
   sequenced_checker_.Detach();
@@ -226,40 +223,35 @@
 }
 
 void BitrateAllocator::UpdateAllocationLimits() {
-  uint32_t total_requested_padding_bitrate = 0;
-  uint32_t total_requested_min_bitrate = 0;
-  uint32_t total_requested_max_bitrate = 0;
+  BitrateAllocationLimits limits;
   for (const auto& config : allocatable_tracks_) {
     uint32_t stream_padding = config.config.pad_up_bitrate_bps;
     if (config.config.enforce_min_bitrate) {
-      total_requested_min_bitrate += config.config.min_bitrate_bps;
+      limits.min_allocatable_rate +=
+          DataRate::bps(config.config.min_bitrate_bps);
     } else if (config.allocated_bitrate_bps == 0) {
       stream_padding =
           std::max(config.MinBitrateWithHysteresis(), stream_padding);
     }
-    total_requested_padding_bitrate += stream_padding;
-    total_requested_max_bitrate += config.config.max_bitrate_bps;
+    limits.max_padding_rate += DataRate::bps(stream_padding);
+    limits.max_allocatable_rate += DataRate::bps(config.config.max_bitrate_bps);
   }
 
-  if (total_requested_padding_bitrate == total_requested_padding_bitrate_ &&
-      total_requested_min_bitrate == total_requested_min_bitrate_ &&
-      total_requested_max_bitrate == total_requested_max_bitrate_) {
+  if (limits.min_allocatable_rate == current_limits_.min_allocatable_rate &&
+      limits.max_allocatable_rate == current_limits_.max_allocatable_rate &&
+      limits.max_padding_rate == current_limits_.max_padding_rate) {
     return;
   }
-
-  total_requested_min_bitrate_ = total_requested_min_bitrate;
-  total_requested_padding_bitrate_ = total_requested_padding_bitrate;
-  total_requested_max_bitrate_ = total_requested_max_bitrate;
+  current_limits_ = limits;
 
   RTC_LOG(LS_INFO) << "UpdateAllocationLimits : total_requested_min_bitrate: "
-                   << total_requested_min_bitrate
-                   << "bps, total_requested_padding_bitrate: "
-                   << total_requested_padding_bitrate
-                   << "bps, total_requested_max_bitrate: "
-                   << total_requested_max_bitrate << "bps";
-  limit_observer_->OnAllocationLimitsChanged(total_requested_min_bitrate,
-                                             total_requested_padding_bitrate,
-                                             total_requested_max_bitrate);
+                   << ToString(limits.min_allocatable_rate)
+                   << ", total_requested_padding_bitrate: "
+                   << ToString(limits.max_padding_rate)
+                   << ", total_requested_max_bitrate: "
+                   << ToString(limits.max_allocatable_rate);
+
+  limit_observer_->OnAllocationLimitsChanged(limits);
 }
 
 void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) {
diff --git a/call/bitrate_allocator.h b/call/bitrate_allocator.h
index 769ab0f..a4ef032 100644
--- a/call/bitrate_allocator.h
+++ b/call/bitrate_allocator.h
@@ -20,6 +20,7 @@
 #include <vector>
 
 #include "api/call/bitrate_allocation.h"
+#include "api/transport/network_types.h"
 #include "rtc_base/synchronization/sequence_checker.h"
 
 namespace webrtc {
@@ -82,9 +83,7 @@
   // bitrate and max padding bitrate is changed.
   class LimitObserver {
    public:
-    virtual void OnAllocationLimitsChanged(uint32_t min_send_bitrate_bps,
-                                           uint32_t max_padding_bitrate_bps,
-                                           uint32_t total_bitrate_bps) = 0;
+    virtual void OnAllocationLimitsChanged(BitrateAllocationLimits limits) = 0;
 
    protected:
     virtual ~LimitObserver() = default;
@@ -214,9 +213,7 @@
   int num_pause_events_ RTC_GUARDED_BY(&sequenced_checker_);
   Clock* const clock_ RTC_GUARDED_BY(&sequenced_checker_);
   int64_t last_bwe_log_time_ RTC_GUARDED_BY(&sequenced_checker_);
-  uint32_t total_requested_padding_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
-  uint32_t total_requested_min_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
-  uint32_t total_requested_max_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
+  BitrateAllocationLimits current_limits_ RTC_GUARDED_BY(&sequenced_checker_);
   const uint8_t transmission_max_bitrate_multiplier_;
 };
 
diff --git a/call/bitrate_allocator_unittest.cc b/call/bitrate_allocator_unittest.cc
index 6857d22..5cdbc38 100644
--- a/call/bitrate_allocator_unittest.cc
+++ b/call/bitrate_allocator_unittest.cc
@@ -19,24 +19,34 @@
 #include "test/gtest.h"
 
 using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Field;
 using ::testing::NiceMock;
 
 namespace webrtc {
-// Emulating old interface for test suite compatibility.
-// TODO(srte): Update tests to reflect new interface.
-class LimitObserverWrapper : public BitrateAllocator::LimitObserver {
- public:
-  virtual void OnAllocationLimitsChanged(uint32_t min_send_bitrate_bps,
-                                         uint32_t max_padding_bitrate_bps,
-                                         uint32_t total_bitrate_bps) = 0;
-};
 
-class MockLimitObserver : public LimitObserverWrapper {
+auto AllocationLimitsEq(uint32_t min_allocatable_rate_bps,
+                        uint32_t max_padding_rate_bps,
+                        uint32_t max_allocatable_rate_bps) {
+  return AllOf(Field(&BitrateAllocationLimits::min_allocatable_rate,
+                     DataRate::bps(min_allocatable_rate_bps)),
+               Field(&BitrateAllocationLimits::max_allocatable_rate,
+                     DataRate::bps(max_allocatable_rate_bps)),
+               Field(&BitrateAllocationLimits::max_padding_rate,
+                     DataRate::bps(max_padding_rate_bps)));
+}
+
+auto AllocationLimitsEq(uint32_t min_allocatable_rate_bps,
+                        uint32_t max_padding_rate_bps) {
+  return AllOf(Field(&BitrateAllocationLimits::min_allocatable_rate,
+                     DataRate::bps(min_allocatable_rate_bps)),
+               Field(&BitrateAllocationLimits::max_padding_rate,
+                     DataRate::bps(max_padding_rate_bps)));
+}
+
+class MockLimitObserver : public BitrateAllocator::LimitObserver {
  public:
-  MOCK_METHOD3(OnAllocationLimitsChanged,
-               void(uint32_t min_send_bitrate_bps,
-                    uint32_t max_padding_bitrate_bps,
-                    uint32_t total_bitrate_bps));
+  MOCK_METHOD1(OnAllocationLimitsChanged, void(BitrateAllocationLimits));
 };
 
 class TestBitrateObserver : public BitrateAllocatorObserver {
@@ -161,8 +171,8 @@
   const uint32_t kMaxBitrateBps = 1500000;
 
   EXPECT_CALL(limit_observer_,
-              OnAllocationLimitsChanged(kMinSendBitrateBps, kPadUpToBitrateBps,
-                                        kMaxBitrateBps));
+              OnAllocationLimitsChanged(AllocationLimitsEq(
+                  kMinSendBitrateBps, kPadUpToBitrateBps, kMaxBitrateBps)));
   AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
               kPadUpToBitrateBps, true, kDefaultBitratePriority);
   EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
@@ -175,12 +185,12 @@
   EXPECT_EQ(3000000, allocator_->GetStartBitrate(&bitrate_observer));
 
   // Expect |max_padding_bitrate_bps| to change to 0 if the observer is updated.
-  EXPECT_CALL(limit_observer_,
-              OnAllocationLimitsChanged(kMinSendBitrateBps, 0, _));
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
+                                   AllocationLimitsEq(kMinSendBitrateBps, 0)));
   AddObserver(&bitrate_observer, kMinSendBitrateBps, 4000000, 0, true,
               kDefaultBitratePriority);
-  EXPECT_CALL(limit_observer_,
-              OnAllocationLimitsChanged(kMinSendBitrateBps, 0, _));
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
+                                   AllocationLimitsEq(kMinSendBitrateBps, 0)));
   EXPECT_EQ(4000000, allocator_->GetStartBitrate(&bitrate_observer));
 
   AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps, 0, true,
@@ -199,16 +209,17 @@
   const uint32_t kObs1MaxBitrateBps = 300000;
   const uint32_t kObs2MaxBitrateBps = 300000;
 
-  EXPECT_CALL(
-      limit_observer_,
-      OnAllocationLimitsChanged(kObs1StartBitrateBps, 0, kObs1MaxBitrateBps));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(
+                  kObs1StartBitrateBps, 0, kObs1MaxBitrateBps)));
   AddObserver(&bitrate_observer_1, kObs1StartBitrateBps, kObs1MaxBitrateBps, 0,
               true, kDefaultBitratePriority);
   EXPECT_EQ(static_cast<int>(kObs1MaxBitrateBps),
             allocator_->GetStartBitrate(&bitrate_observer_1));
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
-                                   kObs1StartBitrateBps + kObs2StartBitrateBps,
-                                   0, kObs1MaxBitrateBps + kObs2MaxBitrateBps));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(
+                  kObs1StartBitrateBps + kObs2StartBitrateBps, 0,
+                  kObs1MaxBitrateBps + kObs2MaxBitrateBps)));
   AddObserver(&bitrate_observer_2, kObs2StartBitrateBps, kObs2MaxBitrateBps, 0,
               true, kDefaultBitratePriority);
   EXPECT_EQ(static_cast<int>(kObs2StartBitrateBps),
@@ -256,11 +267,12 @@
   const uint32_t kMaxBitrateBps = 1500000;
 
   EXPECT_CALL(limit_observer_,
-              OnAllocationLimitsChanged(kMinSendBitrateBps, kPadUpToBitrateBps,
-                                        kMaxBitrateBps));
+              OnAllocationLimitsChanged(AllocationLimitsEq(
+                  kMinSendBitrateBps, kPadUpToBitrateBps, kMaxBitrateBps)));
   AddObserver(&bitrate_observer, kMinSendBitrateBps, kMaxBitrateBps,
               kPadUpToBitrateBps, true, kDefaultBitratePriority);
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, _));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(0, 0)));
   allocator_->RemoveObserver(&bitrate_observer);
 }
 
@@ -293,8 +305,10 @@
   TestBitrateObserver bitrate_observer_1;
   // Expect OnAllocationLimitsChanged with |min_send_bitrate_bps| = 0 since
   // AddObserver is called with |enforce_min_bitrate| = false.
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, _));
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 120000, _));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(0, 0)));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(0, 120000)));
   AddObserver(&bitrate_observer_1, 100000, 400000, 0, false, "",
               kDefaultBitratePriority);
   EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
@@ -307,7 +321,8 @@
   allocator_->OnNetworkChanged(10000, 0, 0, kDefaultProbingIntervalMs);
   EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
 
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, _));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(0, 0)));
   allocator_->RemoveObserver(&bitrate_observer_1);
 }
 
@@ -385,7 +400,8 @@
   // Expect OnAllocationLimitsChanged with |min_send_bitrate_bps| = 0 since
   // AddObserver is called with |enforce_min_bitrate| = false.
   TestBitrateObserver bitrate_observer;
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, kMaxBitrateBps));
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
+                                   AllocationLimitsEq(0, 0, kMaxBitrateBps)));
   AddObserver(&bitrate_observer, kMinBitrateBps, kMaxBitrateBps, 0, false, "",
               kDefaultBitratePriority);
   EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
@@ -409,8 +425,8 @@
   const uint32_t kMinStartBitrateWithProtectionBps =
       static_cast<uint32_t>(kMinStartBitrateBps * (1 + kProtectionRatio));
   EXPECT_CALL(limit_observer_,
-              OnAllocationLimitsChanged(0, kMinStartBitrateWithProtectionBps,
-                                        kMaxBitrateBps));
+              OnAllocationLimitsChanged(AllocationLimitsEq(
+                  0, kMinStartBitrateWithProtectionBps, kMaxBitrateBps)));
   allocator_->OnNetworkChanged(kMinStartBitrateBps + 1000, 0, fraction_loss,
                                kDefaultProbingIntervalMs);
   EXPECT_EQ(0u, bitrate_observer.last_bitrate_bps_);
@@ -420,7 +436,8 @@
   EXPECT_EQ(0u, bitrate_observer.last_bitrate_bps_);
 
   // Just enough to enable video again.
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, kMaxBitrateBps));
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(
+                                   AllocationLimitsEq(0, 0, kMaxBitrateBps)));
   allocator_->OnNetworkChanged(kMinStartBitrateWithProtectionBps, 0,
                                fraction_loss, kDefaultProbingIntervalMs);
   EXPECT_EQ(kMinStartBitrateWithProtectionBps,
@@ -437,7 +454,8 @@
                                kDefaultProbingIntervalMs);
   EXPECT_EQ(kMinStartBitrateBps, bitrate_observer.last_bitrate_bps_);
 
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0, 0));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(0, 0, 0)));
   allocator_->RemoveObserver(&bitrate_observer);
 }
 
@@ -449,8 +467,8 @@
   const uint32_t kMaxBitrateBps = 400000;
 
   // Register |bitrate_observer| and expect total allocation limits to change.
-  EXPECT_CALL(limit_observer_,
-              OnAllocationLimitsChanged(kMinBitrateBps, 0, kMaxBitrateBps))
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(AllocationLimitsEq(
+                                   kMinBitrateBps, 0, kMaxBitrateBps)))
       .Times(1);
   MediaStreamAllocationConfig allocation_config = DefaultConfig();
   allocation_config.min_bitrate_bps = kMinBitrateBps;
@@ -460,19 +478,19 @@
   // Observer uses 20% of it's allocated bitrate for protection.
   bitrate_observer.SetBitrateProtectionRatio(/*protection_ratio=*/0.2);
   // Total allocation limits are unaffected by the protection rate change.
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_, _, _)).Times(0);
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_)).Times(0);
   allocator_->OnNetworkChanged(200000u, 0, 100, kDefaultProbingIntervalMs);
 
   // Observer uses 0% of it's allocated bitrate for protection.
   bitrate_observer.SetBitrateProtectionRatio(/*protection_ratio=*/0.0);
   // Total allocation limits are unaffected by the protection rate change.
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_, _, _)).Times(0);
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_)).Times(0);
   allocator_->OnNetworkChanged(200000u, 0, 100, kDefaultProbingIntervalMs);
 
   // Observer again uses 20% of it's allocated bitrate for protection.
   bitrate_observer.SetBitrateProtectionRatio(/*protection_ratio=*/0.2);
   // Total allocation limits are unaffected by the protection rate change.
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_, _, _)).Times(0);
+  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(_)).Times(0);
   allocator_->OnNetworkChanged(200000u, 0, 100, kDefaultProbingIntervalMs);
 }
 
@@ -562,7 +580,8 @@
 
 TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
   TestBitrateObserver bitrate_observer_1;
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000, 0, _));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(50000, 0)));
 
   AddObserver(&bitrate_observer_1, 50000, 400000, 0, true,
               kDefaultBitratePriority);
@@ -575,7 +594,8 @@
 
   TestBitrateObserver bitrate_observer_2;
   // Adding an observer while the network is down should not affect the limits.
-  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000 + 50000, 0, _));
+  EXPECT_CALL(limit_observer_,
+              OnAllocationLimitsChanged(AllocationLimitsEq(50000 + 50000, 0)));
   AddObserver(&bitrate_observer_2, 50000, 400000, 0, true,
               kDefaultBitratePriority);
 
diff --git a/call/call.cc b/call/call.cc
index 940c1a3..90208fc 100644
--- a/call/call.cc
+++ b/call/call.cc
@@ -230,9 +230,7 @@
   void OnStartRateUpdate(DataRate start_rate) override;
 
   // Implements BitrateAllocator::LimitObserver.
-  void OnAllocationLimitsChanged(uint32_t min_send_bitrate_bps,
-                                 uint32_t max_padding_bitrate_bps,
-                                 uint32_t total_bitrate_bps) override;
+  void OnAllocationLimitsChanged(BitrateAllocationLimits limits) override;
 
   void SetClientBitratePreferences(const BitrateSettings& preferences) override;
 
@@ -1113,19 +1111,16 @@
   pacer_bitrate_kbps_counter_.Add(pacer_bitrate_bps / 1000);
 }
 
-void Call::OnAllocationLimitsChanged(uint32_t min_send_bitrate_bps,
-                                     uint32_t max_padding_bitrate_bps,
-                                     uint32_t total_bitrate_bps) {
+void Call::OnAllocationLimitsChanged(BitrateAllocationLimits limits) {
   RTC_DCHECK(network_queue()->IsCurrent());
   RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
 
-  transport_send_ptr_->SetAllocatedSendBitrateLimits(
-      min_send_bitrate_bps, max_padding_bitrate_bps, total_bitrate_bps);
+  transport_send_ptr_->SetAllocatedSendBitrateLimits(limits);
 
-  min_allocated_send_bitrate_bps_ = min_send_bitrate_bps;
+  min_allocated_send_bitrate_bps_ = limits.min_allocatable_rate.bps();
 
   rtc::CritScope lock(&bitrate_crit_);
-  configured_max_padding_bitrate_bps_ = max_padding_bitrate_bps;
+  configured_max_padding_bitrate_bps_ = limits.max_padding_rate.bps();
 }
 
 void Call::ConfigureSync(const std::string& sync_group) {
diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc
index 41954b9..36385d0 100644
--- a/call/rtp_transport_controller_send.cc
+++ b/call/rtp_transport_controller_send.cc
@@ -184,15 +184,11 @@
 }
 
 void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
-    int min_send_bitrate_bps,
-    int max_padding_bitrate_bps,
-    int max_total_bitrate_bps) {
+    BitrateAllocationLimits limits) {
   RTC_DCHECK_RUN_ON(&task_queue_);
-  streams_config_.min_total_allocated_bitrate =
-      DataRate::bps(min_send_bitrate_bps);
-  streams_config_.max_padding_rate = DataRate::bps(max_padding_bitrate_bps);
-  streams_config_.max_total_allocated_bitrate =
-      DataRate::bps(max_total_bitrate_bps);
+  streams_config_.min_total_allocated_bitrate = limits.min_allocatable_rate;
+  streams_config_.max_padding_rate = limits.max_padding_rate;
+  streams_config_.max_total_allocated_bitrate = limits.max_allocatable_rate;
   UpdateStreamsConfig();
 }
 void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h
index 75e29e4..c9944a75 100644
--- a/call/rtp_transport_controller_send.h
+++ b/call/rtp_transport_controller_send.h
@@ -79,9 +79,7 @@
   TransportFeedbackObserver* transport_feedback_observer() override;
   RtpPacketSender* packet_sender() override;
 
-  void SetAllocatedSendBitrateLimits(int min_send_bitrate_bps,
-                                     int max_padding_bitrate_bps,
-                                     int max_total_bitrate_bps) override;
+  void SetAllocatedSendBitrateLimits(BitrateAllocationLimits limits) override;
 
   void SetPacingFactor(float pacing_factor) override;
   void SetQueueTimeLimit(int limit_ms) override;
diff --git a/call/rtp_transport_controller_send_interface.h b/call/rtp_transport_controller_send_interface.h
index 1ad2b63..7567703 100644
--- a/call/rtp_transport_controller_send_interface.h
+++ b/call/rtp_transport_controller_send_interface.h
@@ -123,15 +123,8 @@
 
   // SetAllocatedSendBitrateLimits sets bitrates limits imposed by send codec
   // settings.
-  // |min_send_bitrate_bps| is the total minimum send bitrate required by all
-  // sending streams.  This is the minimum bitrate the PacedSender will use.
-  // |max_padding_bitrate_bps| is the max
-  // bitrate the send streams request for padding. This can be higher than the
-  // current network estimate and tells the PacedSender how much it should max
-  // pad unless there is real packets to send.
-  virtual void SetAllocatedSendBitrateLimits(int min_send_bitrate_bps,
-                                             int max_padding_bitrate_bps,
-                                             int total_bitrate_bps) = 0;
+  virtual void SetAllocatedSendBitrateLimits(
+      BitrateAllocationLimits limits) = 0;
 
   virtual void SetPacingFactor(float pacing_factor) = 0;
   virtual void SetQueueTimeLimit(int limit_ms) = 0;
diff --git a/call/test/mock_rtp_transport_controller_send.h b/call/test/mock_rtp_transport_controller_send.h
index a418ad9..b6948f4 100644
--- a/call/test/mock_rtp_transport_controller_send.h
+++ b/call/test/mock_rtp_transport_controller_send.h
@@ -49,7 +49,7 @@
                NetworkStateEstimateObserver*());
   MOCK_METHOD0(transport_feedback_observer, TransportFeedbackObserver*());
   MOCK_METHOD0(packet_sender, RtpPacketSender*());
-  MOCK_METHOD3(SetAllocatedSendBitrateLimits, void(int, int, int));
+  MOCK_METHOD1(SetAllocatedSendBitrateLimits, void(BitrateAllocationLimits));
   MOCK_METHOD1(SetPacingFactor, void(float));
   MOCK_METHOD1(SetQueueTimeLimit, void(int));
   MOCK_METHOD1(RegisterPacketFeedbackObserver, void(PacketFeedbackObserver*));