Converts const methods in BitrateAllocator to non-member functions.

Also cleaning up finished TransmissionMaxBitrateMultiplier trial.

Bug: webrtc:9883
Change-Id: I049f0e8e3051f91b57201e9ce750427018c74bfa
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153889
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Ying Wang <yinwa@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29302}
diff --git a/call/bitrate_allocator.cc b/call/bitrate_allocator.cc
index 989f70c..7d9e5cb 100644
--- a/call/bitrate_allocator.cc
+++ b/call/bitrate_allocator.cc
@@ -29,6 +29,7 @@
 namespace webrtc {
 
 namespace {
+using bitrate_allocator_impl::AllocatableTrack;
 
 // Allow packets to be transmitted in up to 2 times max video bitrate if the
 // bandwidth estimate allows it.
@@ -50,6 +51,305 @@
   return media_bitrate / static_cast<double>(allocated_bitrate);
 }
 
+bool EnoughBitrateForAllObservers(
+    const std::vector<AllocatableTrack>& allocatable_tracks,
+    uint32_t bitrate,
+    uint32_t sum_min_bitrates) {
+  if (bitrate < sum_min_bitrates)
+    return false;
+
+  uint32_t extra_bitrate_per_observer =
+      (bitrate - sum_min_bitrates) /
+      static_cast<uint32_t>(allocatable_tracks.size());
+  for (const auto& observer_config : allocatable_tracks) {
+    if (observer_config.config.min_bitrate_bps + extra_bitrate_per_observer <
+        observer_config.MinBitrateWithHysteresis()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// Splits |bitrate| evenly to observers already in |allocation|.
+// |include_zero_allocations| decides if zero allocations should be part of
+// the distribution or not. The allowed max bitrate is |max_multiplier| x
+// observer max bitrate.
+void DistributeBitrateEvenly(
+    const std::vector<AllocatableTrack>& allocatable_tracks,
+    uint32_t bitrate,
+    bool include_zero_allocations,
+    int max_multiplier,
+    std::map<BitrateAllocatorObserver*, int>* allocation) {
+  RTC_DCHECK_EQ(allocation->size(), allocatable_tracks.size());
+
+  std::multimap<uint32_t, const AllocatableTrack*> list_max_bitrates;
+  for (const auto& observer_config : allocatable_tracks) {
+    if (include_zero_allocations ||
+        allocation->at(observer_config.observer) != 0) {
+      list_max_bitrates.insert(
+          {observer_config.config.max_bitrate_bps, &observer_config});
+    }
+  }
+  auto it = list_max_bitrates.begin();
+  while (it != list_max_bitrates.end()) {
+    RTC_DCHECK_GT(bitrate, 0);
+    uint32_t extra_allocation =
+        bitrate / static_cast<uint32_t>(list_max_bitrates.size());
+    uint32_t total_allocation =
+        extra_allocation + allocation->at(it->second->observer);
+    bitrate -= extra_allocation;
+    if (total_allocation > max_multiplier * it->first) {
+      // There is more than we can fit for this observer, carry over to the
+      // remaining observers.
+      bitrate += total_allocation - max_multiplier * it->first;
+      total_allocation = max_multiplier * it->first;
+    }
+    // Finally, update the allocation for this observer.
+    allocation->at(it->second->observer) = total_allocation;
+    it = list_max_bitrates.erase(it);
+  }
+}
+
+// From the available |bitrate|, each observer will be allocated a
+// proportional amount based upon its bitrate priority. If that amount is
+// more than the observer's capacity, it will be allocated its capacity, and
+// the excess bitrate is still allocated proportionally to other observers.
+// Allocating the proportional amount means an observer with twice the
+// bitrate_priority of another will be allocated twice the bitrate.
+void DistributeBitrateRelatively(
+    const std::vector<AllocatableTrack>& allocatable_tracks,
+    uint32_t remaining_bitrate,
+    const std::map<BitrateAllocatorObserver*, int>& observers_capacities,
+    std::map<BitrateAllocatorObserver*, int>* allocation) {
+  RTC_DCHECK_EQ(allocation->size(), allocatable_tracks.size());
+  RTC_DCHECK_EQ(observers_capacities.size(), allocatable_tracks.size());
+
+  struct PriorityRateObserverConfig {
+    BitrateAllocatorObserver* allocation_key;
+    // The amount of bitrate bps that can be allocated to this observer.
+    int capacity_bps;
+    double bitrate_priority;
+  };
+
+  double bitrate_priority_sum = 0;
+  std::vector<PriorityRateObserverConfig> priority_rate_observers;
+  for (const auto& observer_config : allocatable_tracks) {
+    priority_rate_observers.push_back(PriorityRateObserverConfig{
+        observer_config.observer,
+        observers_capacities.at(observer_config.observer),
+        observer_config.config.bitrate_priority});
+    bitrate_priority_sum += observer_config.config.bitrate_priority;
+  }
+
+  // Iterate in the order observers can be allocated their full capacity.
+
+  // We want to sort by which observers will be allocated their full capacity
+  // first. By dividing each observer's capacity by its bitrate priority we
+  // are "normalizing" the capacity of an observer by the rate it will be
+  // filled. This is because the amount allocated is based upon bitrate
+  // priority. We allocate twice as much bitrate to an observer with twice the
+  // bitrate priority of another.
+  absl::c_sort(priority_rate_observers, [](const auto& a, const auto& b) {
+    return a.capacity_bps / a.bitrate_priority <
+           b.capacity_bps / b.bitrate_priority;
+  });
+  size_t i;
+  for (i = 0; i < priority_rate_observers.size(); ++i) {
+    const auto& priority_rate_observer = priority_rate_observers[i];
+    // We allocate the full capacity to an observer only if its relative
+    // portion from the remaining bitrate is sufficient to allocate its full
+    // capacity. This means we aren't greedily allocating the full capacity, but
+    // that it is only done when there is also enough bitrate to allocate the
+    // proportional amounts to all other observers.
+    double observer_share =
+        priority_rate_observer.bitrate_priority / bitrate_priority_sum;
+    double allocation_bps = observer_share * remaining_bitrate;
+    bool enough_bitrate = allocation_bps >= priority_rate_observer.capacity_bps;
+    if (!enough_bitrate)
+      break;
+    allocation->at(priority_rate_observer.allocation_key) +=
+        priority_rate_observer.capacity_bps;
+    remaining_bitrate -= priority_rate_observer.capacity_bps;
+    bitrate_priority_sum -= priority_rate_observer.bitrate_priority;
+  }
+
+  // From the remaining bitrate, allocate the proportional amounts to the
+  // observers that aren't allocated their max capacity.
+  for (; i < priority_rate_observers.size(); ++i) {
+    const auto& priority_rate_observer = priority_rate_observers[i];
+    double fraction_allocated =
+        priority_rate_observer.bitrate_priority / bitrate_priority_sum;
+    allocation->at(priority_rate_observer.allocation_key) +=
+        fraction_allocated * remaining_bitrate;
+  }
+}
+
+// Allocates bitrate to observers when there isn't enough to allocate the
+// minimum to all observers.
+std::map<BitrateAllocatorObserver*, int> LowRateAllocation(
+    const std::vector<AllocatableTrack>& allocatable_tracks,
+    uint32_t bitrate) {
+  std::map<BitrateAllocatorObserver*, int> allocation;
+  // Start by allocating bitrate to observers enforcing a min bitrate, hence
+  // remaining_bitrate might turn negative.
+  int64_t remaining_bitrate = bitrate;
+  for (const auto& observer_config : allocatable_tracks) {
+    int32_t allocated_bitrate = 0;
+    if (observer_config.config.enforce_min_bitrate)
+      allocated_bitrate = observer_config.config.min_bitrate_bps;
+
+    allocation[observer_config.observer] = allocated_bitrate;
+    remaining_bitrate -= allocated_bitrate;
+  }
+
+  // Allocate bitrate to all previously active streams.
+  if (remaining_bitrate > 0) {
+    for (const auto& observer_config : allocatable_tracks) {
+      if (observer_config.config.enforce_min_bitrate ||
+          observer_config.LastAllocatedBitrate() == 0)
+        continue;
+
+      uint32_t required_bitrate = observer_config.MinBitrateWithHysteresis();
+      if (remaining_bitrate >= required_bitrate) {
+        allocation[observer_config.observer] = required_bitrate;
+        remaining_bitrate -= required_bitrate;
+      }
+    }
+  }
+
+  // Allocate bitrate to previously paused streams.
+  if (remaining_bitrate > 0) {
+    for (const auto& observer_config : allocatable_tracks) {
+      if (observer_config.LastAllocatedBitrate() != 0)
+        continue;
+
+      // Add a hysteresis to avoid toggling.
+      uint32_t required_bitrate = observer_config.MinBitrateWithHysteresis();
+      if (remaining_bitrate >= required_bitrate) {
+        allocation[observer_config.observer] = required_bitrate;
+        remaining_bitrate -= required_bitrate;
+      }
+    }
+  }
+
+  // Split a possible remainder evenly on all streams with an allocation.
+  if (remaining_bitrate > 0)
+    DistributeBitrateEvenly(allocatable_tracks, remaining_bitrate, false, 1,
+                            &allocation);
+
+  RTC_DCHECK_EQ(allocation.size(), allocatable_tracks.size());
+  return allocation;
+}
+
+// Allocates bitrate to all observers when the available bandwidth is enough
+// to allocate the minimum to all observers but not enough to allocate the
+// max bitrate of each observer.
+
+// Allocates the bitrate based on the bitrate priority of each observer. This
+// bitrate priority defines the priority for bitrate to be allocated to that
+// observer in relation to other observers. For example with two observers, if
+// observer 1 had a bitrate_priority = 1.0, and observer 2 has a
+// bitrate_priority = 2.0, the expected behavior is that observer 2 will be
+// allocated twice the bitrate as observer 1 above the each observer's
+// min_bitrate_bps values, until one of the observers hits its max_bitrate_bps.
+std::map<BitrateAllocatorObserver*, int> NormalRateAllocation(
+    const std::vector<AllocatableTrack>& allocatable_tracks,
+    uint32_t bitrate,
+    uint32_t sum_min_bitrates) {
+  std::map<BitrateAllocatorObserver*, int> allocation;
+  std::map<BitrateAllocatorObserver*, int> observers_capacities;
+  for (const auto& observer_config : allocatable_tracks) {
+    allocation[observer_config.observer] =
+        observer_config.config.min_bitrate_bps;
+    observers_capacities[observer_config.observer] =
+        observer_config.config.max_bitrate_bps -
+        observer_config.config.min_bitrate_bps;
+  }
+
+  bitrate -= sum_min_bitrates;
+
+  // TODO(srte): Implement fair sharing between prioritized streams, currently
+  // they are treated on a first come first serve basis.
+  for (const auto& observer_config : allocatable_tracks) {
+    int64_t priority_margin = observer_config.config.priority_bitrate_bps -
+                              allocation[observer_config.observer];
+    if (priority_margin > 0 && bitrate > 0) {
+      int64_t extra_bitrate = std::min<int64_t>(priority_margin, bitrate);
+      allocation[observer_config.observer] +=
+          rtc::dchecked_cast<int>(extra_bitrate);
+      observers_capacities[observer_config.observer] -= extra_bitrate;
+      bitrate -= extra_bitrate;
+    }
+  }
+
+  // From the remaining bitrate, allocate a proportional amount to each observer
+  // above the min bitrate already allocated.
+  if (bitrate > 0)
+    DistributeBitrateRelatively(allocatable_tracks, bitrate,
+                                observers_capacities, &allocation);
+
+  return allocation;
+}
+
+// Allocates bitrate to observers when there is enough available bandwidth
+// for all observers to be allocated their max bitrate.
+std::map<BitrateAllocatorObserver*, int> MaxRateAllocation(
+    const std::vector<AllocatableTrack>& allocatable_tracks,
+    uint32_t bitrate,
+    uint32_t sum_max_bitrates) {
+  std::map<BitrateAllocatorObserver*, int> allocation;
+
+  for (const auto& observer_config : allocatable_tracks) {
+    allocation[observer_config.observer] =
+        observer_config.config.max_bitrate_bps;
+    bitrate -= observer_config.config.max_bitrate_bps;
+  }
+  DistributeBitrateEvenly(allocatable_tracks, bitrate, true,
+                          kTransmissionMaxBitrateMultiplier, &allocation);
+  return allocation;
+}
+
+// Allocates zero bitrate to all observers.
+std::map<BitrateAllocatorObserver*, int> ZeroRateAllocation(
+    const std::vector<AllocatableTrack>& allocatable_tracks) {
+  std::map<BitrateAllocatorObserver*, int> allocation;
+  for (const auto& observer_config : allocatable_tracks)
+    allocation[observer_config.observer] = 0;
+  return allocation;
+}
+
+std::map<BitrateAllocatorObserver*, int> AllocateBitrates(
+    const std::vector<AllocatableTrack>& allocatable_tracks,
+    uint32_t bitrate) {
+  if (allocatable_tracks.empty())
+    return std::map<BitrateAllocatorObserver*, int>();
+
+  if (bitrate == 0)
+    return ZeroRateAllocation(allocatable_tracks);
+
+  uint32_t sum_min_bitrates = 0;
+  uint32_t sum_max_bitrates = 0;
+  for (const auto& observer_config : allocatable_tracks) {
+    sum_min_bitrates += observer_config.config.min_bitrate_bps;
+    sum_max_bitrates += observer_config.config.max_bitrate_bps;
+  }
+
+  // Not enough for all observers to get an allocation, allocate according to:
+  // enforced min bitrate -> allocated bitrate previous round -> restart paused
+  // streams.
+  if (!EnoughBitrateForAllObservers(allocatable_tracks, bitrate,
+                                    sum_min_bitrates))
+    return LowRateAllocation(allocatable_tracks, bitrate);
+
+  // All observers will get their min bitrate plus a share of the rest. This
+  // share is allocated to each observer based on its bitrate_priority.
+  if (bitrate <= sum_max_bitrates)
+    return NormalRateAllocation(allocatable_tracks, bitrate, sum_min_bitrates);
+
+  // All observers will get up to transmission_max_bitrate_multiplier_ x max.
+  return MaxRateAllocation(allocatable_tracks, bitrate, sum_max_bitrates);
+}
+
 }  // namespace
 
 BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer)
@@ -61,9 +361,7 @@
       last_rtt_(0),
       last_bwe_period_ms_(1000),
       num_pause_events_(0),
-      last_bwe_log_time_(0),
-      transmission_max_bitrate_multiplier_(
-          GetTransmissionMaxBitrateMultiplier()) {
+      last_bwe_log_time_(0) {
   sequenced_checker_.Detach();
 }
 
@@ -77,20 +375,6 @@
   last_non_zero_bitrate_bps_ = start_rate_bps;
 }
 
-// static
-uint8_t BitrateAllocator::GetTransmissionMaxBitrateMultiplier() {
-  uint64_t multiplier = strtoul(webrtc::field_trial::FindFullName(
-                                    "WebRTC-TransmissionMaxBitrateMultiplier")
-                                    .c_str(),
-                                nullptr, 10);
-  if (multiplier > 0 && multiplier <= kTransmissionMaxBitrateMultiplier) {
-    RTC_LOG(LS_INFO) << "TransmissionMaxBitrateMultiplier is set to "
-                     << multiplier;
-    return static_cast<uint8_t>(multiplier);
-  }
-  return kTransmissionMaxBitrateMultiplier;
-}
-
 void BitrateAllocator::OnNetworkEstimateChanged(TargetTransferRate msg) {
   RTC_DCHECK_RUN_ON(&sequenced_checker_);
   last_target_bps_ = msg.target_rate.bps();
@@ -111,9 +395,9 @@
     last_bwe_log_time_ = now;
   }
 
-  ObserverAllocation allocation = AllocateBitrates(last_target_bps_);
-  ObserverAllocation stable_bitrate_allocation =
-      AllocateBitrates(last_stable_target_bps_);
+  auto allocation = AllocateBitrates(allocatable_tracks_, last_target_bps_);
+  auto stable_bitrate_allocation =
+      AllocateBitrates(allocatable_tracks_, last_stable_target_bps_);
 
   for (auto& config : allocatable_tracks_) {
     uint32_t allocated_bitrate = allocation[config.observer];
@@ -176,9 +460,9 @@
   if (last_target_bps_ > 0) {
     // Calculate a new allocation and update all observers.
 
-    ObserverAllocation allocation = AllocateBitrates(last_target_bps_);
-    ObserverAllocation stable_bitrate_allocation =
-        AllocateBitrates(last_stable_target_bps_);
+    auto allocation = AllocateBitrates(allocatable_tracks_, last_target_bps_);
+    auto stable_bitrate_allocation =
+        AllocateBitrates(allocatable_tracks_, last_stable_target_bps_);
     for (auto& config : allocatable_tracks_) {
       uint32_t allocated_bitrate = allocation[config.observer];
       uint32_t allocated_stable_bitrate =
@@ -275,157 +559,8 @@
   }
 }
 
-BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates(
-    uint32_t bitrate) const {
-  if (allocatable_tracks_.empty())
-    return ObserverAllocation();
-
-  if (bitrate == 0)
-    return ZeroRateAllocation();
-
-  uint32_t sum_min_bitrates = 0;
-  uint32_t sum_max_bitrates = 0;
-  for (const auto& observer_config : allocatable_tracks_) {
-    sum_min_bitrates += observer_config.config.min_bitrate_bps;
-    sum_max_bitrates += observer_config.config.max_bitrate_bps;
-  }
-
-  // Not enough for all observers to get an allocation, allocate according to:
-  // enforced min bitrate -> allocated bitrate previous round -> restart paused
-  // streams.
-  if (!EnoughBitrateForAllObservers(bitrate, sum_min_bitrates))
-    return LowRateAllocation(bitrate);
-
-  // All observers will get their min bitrate plus a share of the rest. This
-  // share is allocated to each observer based on its bitrate_priority.
-  if (bitrate <= sum_max_bitrates)
-    return NormalRateAllocation(bitrate, sum_min_bitrates);
-
-  // All observers will get up to transmission_max_bitrate_multiplier_ x max.
-  return MaxRateAllocation(bitrate, sum_max_bitrates);
-}
-
-BitrateAllocator::ObserverAllocation BitrateAllocator::ZeroRateAllocation()
+uint32_t bitrate_allocator_impl::AllocatableTrack::LastAllocatedBitrate()
     const {
-  ObserverAllocation allocation;
-  for (const auto& observer_config : allocatable_tracks_)
-    allocation[observer_config.observer] = 0;
-  return allocation;
-}
-
-BitrateAllocator::ObserverAllocation BitrateAllocator::LowRateAllocation(
-    uint32_t bitrate) const {
-  ObserverAllocation allocation;
-  // Start by allocating bitrate to observers enforcing a min bitrate, hence
-  // remaining_bitrate might turn negative.
-  int64_t remaining_bitrate = bitrate;
-  for (const auto& observer_config : allocatable_tracks_) {
-    int32_t allocated_bitrate = 0;
-    if (observer_config.config.enforce_min_bitrate)
-      allocated_bitrate = observer_config.config.min_bitrate_bps;
-
-    allocation[observer_config.observer] = allocated_bitrate;
-    remaining_bitrate -= allocated_bitrate;
-  }
-
-  // Allocate bitrate to all previously active streams.
-  if (remaining_bitrate > 0) {
-    for (const auto& observer_config : allocatable_tracks_) {
-      if (observer_config.config.enforce_min_bitrate ||
-          observer_config.LastAllocatedBitrate() == 0)
-        continue;
-
-      uint32_t required_bitrate = observer_config.MinBitrateWithHysteresis();
-      if (remaining_bitrate >= required_bitrate) {
-        allocation[observer_config.observer] = required_bitrate;
-        remaining_bitrate -= required_bitrate;
-      }
-    }
-  }
-
-  // Allocate bitrate to previously paused streams.
-  if (remaining_bitrate > 0) {
-    for (const auto& observer_config : allocatable_tracks_) {
-      if (observer_config.LastAllocatedBitrate() != 0)
-        continue;
-
-      // Add a hysteresis to avoid toggling.
-      uint32_t required_bitrate = observer_config.MinBitrateWithHysteresis();
-      if (remaining_bitrate >= required_bitrate) {
-        allocation[observer_config.observer] = required_bitrate;
-        remaining_bitrate -= required_bitrate;
-      }
-    }
-  }
-
-  // Split a possible remainder evenly on all streams with an allocation.
-  if (remaining_bitrate > 0)
-    DistributeBitrateEvenly(remaining_bitrate, false, 1, &allocation);
-
-  RTC_DCHECK_EQ(allocation.size(), allocatable_tracks_.size());
-  return allocation;
-}
-
-// Allocates the bitrate based on the bitrate priority of each observer. This
-// bitrate priority defines the priority for bitrate to be allocated to that
-// observer in relation to other observers. For example with two observers, if
-// observer 1 had a bitrate_priority = 1.0, and observer 2 has a
-// bitrate_priority = 2.0, the expected behavior is that observer 2 will be
-// allocated twice the bitrate as observer 1 above the each observer's
-// min_bitrate_bps values, until one of the observers hits its max_bitrate_bps.
-BitrateAllocator::ObserverAllocation BitrateAllocator::NormalRateAllocation(
-    uint32_t bitrate,
-    uint32_t sum_min_bitrates) const {
-  ObserverAllocation allocation;
-  ObserverAllocation observers_capacities;
-  for (const auto& observer_config : allocatable_tracks_) {
-    allocation[observer_config.observer] =
-        observer_config.config.min_bitrate_bps;
-    observers_capacities[observer_config.observer] =
-        observer_config.config.max_bitrate_bps -
-        observer_config.config.min_bitrate_bps;
-  }
-
-  bitrate -= sum_min_bitrates;
-
-  // TODO(srte): Implement fair sharing between prioritized streams, currently
-  // they are treated on a first come first serve basis.
-  for (const auto& observer_config : allocatable_tracks_) {
-    int64_t priority_margin = observer_config.config.priority_bitrate_bps -
-                              allocation[observer_config.observer];
-    if (priority_margin > 0 && bitrate > 0) {
-      int64_t extra_bitrate = std::min<int64_t>(priority_margin, bitrate);
-      allocation[observer_config.observer] +=
-          rtc::dchecked_cast<int>(extra_bitrate);
-      observers_capacities[observer_config.observer] -= extra_bitrate;
-      bitrate -= extra_bitrate;
-    }
-  }
-
-  // From the remaining bitrate, allocate a proportional amount to each observer
-  // above the min bitrate already allocated.
-  if (bitrate > 0)
-    DistributeBitrateRelatively(bitrate, observers_capacities, &allocation);
-
-  return allocation;
-}
-
-BitrateAllocator::ObserverAllocation BitrateAllocator::MaxRateAllocation(
-    uint32_t bitrate,
-    uint32_t sum_max_bitrates) const {
-  ObserverAllocation allocation;
-
-  for (const auto& observer_config : allocatable_tracks_) {
-    allocation[observer_config.observer] =
-        observer_config.config.max_bitrate_bps;
-    bitrate -= observer_config.config.max_bitrate_bps;
-  }
-  DistributeBitrateEvenly(bitrate, true, transmission_max_bitrate_multiplier_,
-                          &allocation);
-  return allocation;
-}
-
-uint32_t BitrateAllocator::AllocatableTrack::LastAllocatedBitrate() const {
   // Return the configured minimum bitrate for newly added observers, to avoid
   // requiring an extra high bitrate for the observer to get an allocated
   // bitrate.
@@ -433,7 +568,8 @@
                                      : allocated_bitrate_bps;
 }
 
-uint32_t BitrateAllocator::AllocatableTrack::MinBitrateWithHysteresis() const {
+uint32_t bitrate_allocator_impl::AllocatableTrack::MinBitrateWithHysteresis()
+    const {
   uint32_t min_bitrate = config.min_bitrate_bps;
   if (LastAllocatedBitrate() == 0) {
     min_bitrate += std::max(static_cast<uint32_t>(kToggleFactor * min_bitrate),
@@ -451,132 +587,4 @@
   return min_bitrate;
 }
 
-void BitrateAllocator::DistributeBitrateEvenly(
-    uint32_t bitrate,
-    bool include_zero_allocations,
-    int max_multiplier,
-    ObserverAllocation* allocation) const {
-  RTC_DCHECK_EQ(allocation->size(), allocatable_tracks_.size());
-
-  ObserverSortingMap list_max_bitrates;
-  for (const auto& observer_config : allocatable_tracks_) {
-    if (include_zero_allocations ||
-        allocation->at(observer_config.observer) != 0) {
-      list_max_bitrates.insert(std::pair<uint32_t, const AllocatableTrack*>(
-          observer_config.config.max_bitrate_bps, &observer_config));
-    }
-  }
-  auto it = list_max_bitrates.begin();
-  while (it != list_max_bitrates.end()) {
-    RTC_DCHECK_GT(bitrate, 0);
-    uint32_t extra_allocation =
-        bitrate / static_cast<uint32_t>(list_max_bitrates.size());
-    uint32_t total_allocation =
-        extra_allocation + allocation->at(it->second->observer);
-    bitrate -= extra_allocation;
-    if (total_allocation > max_multiplier * it->first) {
-      // There is more than we can fit for this observer, carry over to the
-      // remaining observers.
-      bitrate += total_allocation - max_multiplier * it->first;
-      total_allocation = max_multiplier * it->first;
-    }
-    // Finally, update the allocation for this observer.
-    allocation->at(it->second->observer) = total_allocation;
-    it = list_max_bitrates.erase(it);
-  }
-}
-
-bool BitrateAllocator::EnoughBitrateForAllObservers(
-    uint32_t bitrate,
-    uint32_t sum_min_bitrates) const {
-  if (bitrate < sum_min_bitrates)
-    return false;
-
-  uint32_t extra_bitrate_per_observer =
-      (bitrate - sum_min_bitrates) /
-      static_cast<uint32_t>(allocatable_tracks_.size());
-  for (const auto& observer_config : allocatable_tracks_) {
-    if (observer_config.config.min_bitrate_bps + extra_bitrate_per_observer <
-        observer_config.MinBitrateWithHysteresis()) {
-      return false;
-    }
-  }
-  return true;
-}
-
-void BitrateAllocator::DistributeBitrateRelatively(
-    uint32_t remaining_bitrate,
-    const ObserverAllocation& observers_capacities,
-    ObserverAllocation* allocation) const {
-  RTC_DCHECK_EQ(allocation->size(), allocatable_tracks_.size());
-  RTC_DCHECK_EQ(observers_capacities.size(), allocatable_tracks_.size());
-
-  struct PriorityRateObserverConfig {
-    PriorityRateObserverConfig(BitrateAllocatorObserver* allocation_key,
-                               uint32_t capacity_bps,
-                               double bitrate_priority)
-        : allocation_key(allocation_key),
-          capacity_bps(capacity_bps),
-          bitrate_priority(bitrate_priority) {}
-
-    BitrateAllocatorObserver* allocation_key;
-    // The amount of bitrate bps that can be allocated to this observer.
-    uint32_t capacity_bps;
-    double bitrate_priority;
-
-    // We want to sort by which observers will be allocated their full capacity
-    // first. By dividing each observer's capacity by its bitrate priority we
-    // are "normalizing" the capacity of an observer by the rate it will be
-    // filled. This is because the amount allocated is based upon bitrate
-    // priority. We allocate twice as much bitrate to an observer with twice the
-    // bitrate priority of another.
-    bool operator<(const PriorityRateObserverConfig& other) const {
-      return capacity_bps / bitrate_priority <
-             other.capacity_bps / other.bitrate_priority;
-    }
-  };
-
-  double bitrate_priority_sum = 0;
-  std::vector<PriorityRateObserverConfig> priority_rate_observers;
-  for (const auto& observer_config : allocatable_tracks_) {
-    uint32_t capacity_bps = observers_capacities.at(observer_config.observer);
-    priority_rate_observers.emplace_back(
-        observer_config.observer, capacity_bps,
-        observer_config.config.bitrate_priority);
-    bitrate_priority_sum += observer_config.config.bitrate_priority;
-  }
-
-  // Iterate in the order observers can be allocated their full capacity.
-  std::sort(priority_rate_observers.begin(), priority_rate_observers.end());
-  size_t i;
-  for (i = 0; i < priority_rate_observers.size(); ++i) {
-    const auto& priority_rate_observer = priority_rate_observers[i];
-    // We allocate the full capacity to an observer only if its relative
-    // portion from the remaining bitrate is sufficient to allocate its full
-    // capacity. This means we aren't greedily allocating the full capacity, but
-    // that it is only done when there is also enough bitrate to allocate the
-    // proportional amounts to all other observers.
-    double observer_share =
-        priority_rate_observer.bitrate_priority / bitrate_priority_sum;
-    double allocation_bps = observer_share * remaining_bitrate;
-    bool enough_bitrate = allocation_bps >= priority_rate_observer.capacity_bps;
-    if (!enough_bitrate)
-      break;
-    allocation->at(priority_rate_observer.allocation_key) +=
-        priority_rate_observer.capacity_bps;
-    remaining_bitrate -= priority_rate_observer.capacity_bps;
-    bitrate_priority_sum -= priority_rate_observer.bitrate_priority;
-  }
-
-  // From the remaining bitrate, allocate the proportional amounts to the
-  // observers that aren't allocated their max capacity.
-  for (; i < priority_rate_observers.size(); ++i) {
-    const auto& priority_rate_observer = priority_rate_observers[i];
-    double fraction_allocated =
-        priority_rate_observer.bitrate_priority / bitrate_priority_sum;
-    allocation->at(priority_rate_observer.allocation_key) +=
-        fraction_allocated * remaining_bitrate;
-  }
-}
-
 }  // namespace webrtc
diff --git a/call/bitrate_allocator.h b/call/bitrate_allocator.h
index b7d77d9..8d9a1ad 100644
--- a/call/bitrate_allocator.h
+++ b/call/bitrate_allocator.h
@@ -74,6 +74,26 @@
   virtual ~BitrateAllocatorInterface() = default;
 };
 
+namespace bitrate_allocator_impl {
+struct AllocatableTrack {
+  AllocatableTrack(BitrateAllocatorObserver* observer,
+                   MediaStreamAllocationConfig allocation_config)
+      : observer(observer),
+        config(allocation_config),
+        allocated_bitrate_bps(-1),
+        media_ratio(1.0) {}
+  BitrateAllocatorObserver* observer;
+  MediaStreamAllocationConfig config;
+  int64_t allocated_bitrate_bps;
+  double media_ratio;  // Part of the total bitrate used for media [0.0, 1.0].
+
+  uint32_t LastAllocatedBitrate() const;
+  // The minimum bitrate required by this observer, including
+  // enable-hysteresis if the observer is in a paused state.
+  uint32_t MinBitrateWithHysteresis() const;
+};
+}  // namespace bitrate_allocator_impl
+
 // Usage: this class will register multiple RtcpBitrateObserver's one at each
 // RTCP module. It will aggregate the results and run one bandwidth estimation
 // and push the result to the encoders via BitrateAllocatorObserver(s).
@@ -116,76 +136,12 @@
   int GetStartBitrate(BitrateAllocatorObserver* observer) const override;
 
  private:
-  struct AllocatableTrack {
-    AllocatableTrack(BitrateAllocatorObserver* observer,
-                     MediaStreamAllocationConfig allocation_config)
-        : observer(observer),
-          config(allocation_config),
-          allocated_bitrate_bps(-1),
-          media_ratio(1.0) {}
-    BitrateAllocatorObserver* observer;
-    MediaStreamAllocationConfig config;
-    int64_t allocated_bitrate_bps;
-    double media_ratio;  // Part of the total bitrate used for media [0.0, 1.0].
-
-    uint32_t LastAllocatedBitrate() const;
-    // The minimum bitrate required by this observer, including
-    // enable-hysteresis if the observer is in a paused state.
-    uint32_t MinBitrateWithHysteresis() const;
-  };
+  using AllocatableTrack = bitrate_allocator_impl::AllocatableTrack;
 
   // Calculates the minimum requested send bitrate and max padding bitrate and
   // calls LimitObserver::OnAllocationLimitsChanged.
   void UpdateAllocationLimits() RTC_RUN_ON(&sequenced_checker_);
 
-  typedef std::multimap<uint32_t, const AllocatableTrack*> ObserverSortingMap;
-  typedef std::map<BitrateAllocatorObserver*, int> ObserverAllocation;
-
-  ObserverAllocation AllocateBitrates(uint32_t bitrate) const
-      RTC_RUN_ON(&sequenced_checker_);
-
-  // Allocates zero bitrate to all observers.
-  ObserverAllocation ZeroRateAllocation() const RTC_RUN_ON(&sequenced_checker_);
-  // Allocates bitrate to observers when there isn't enough to allocate the
-  // minimum to all observers.
-  ObserverAllocation LowRateAllocation(uint32_t bitrate) const
-      RTC_RUN_ON(&sequenced_checker_);
-  // Allocates bitrate to all observers when the available bandwidth is enough
-  // to allocate the minimum to all observers but not enough to allocate the
-  // max bitrate of each observer.
-  ObserverAllocation NormalRateAllocation(uint32_t bitrate,
-                                          uint32_t sum_min_bitrates) const
-      RTC_RUN_ON(&sequenced_checker_);
-  // Allocates bitrate to observers when there is enough available bandwidth
-  // for all observers to be allocated their max bitrate.
-  ObserverAllocation MaxRateAllocation(uint32_t bitrate,
-                                       uint32_t sum_max_bitrates) const
-      RTC_RUN_ON(&sequenced_checker_);
-
-  // Splits |bitrate| evenly to observers already in |allocation|.
-  // |include_zero_allocations| decides if zero allocations should be part of
-  // the distribution or not. The allowed max bitrate is |max_multiplier| x
-  // observer max bitrate.
-  void DistributeBitrateEvenly(uint32_t bitrate,
-                               bool include_zero_allocations,
-                               int max_multiplier,
-                               ObserverAllocation* allocation) const
-      RTC_RUN_ON(&sequenced_checker_);
-  bool EnoughBitrateForAllObservers(uint32_t bitrate,
-                                    uint32_t sum_min_bitrates) const
-      RTC_RUN_ON(&sequenced_checker_);
-
-  // From the available |bitrate|, each observer will be allocated a
-  // proportional amount based upon its bitrate priority. If that amount is
-  // more than the observer's capacity, it will be allocated its capacity, and
-  // the excess bitrate is still allocated proportionally to other observers.
-  // Allocating the proportional amount means an observer with twice the
-  // bitrate_priority of another will be allocated twice the bitrate.
-  void DistributeBitrateRelatively(
-      uint32_t bitrate,
-      const ObserverAllocation& observers_capacities,
-      ObserverAllocation* allocation) const RTC_RUN_ON(&sequenced_checker_);
-
   // Allow packets to be transmitted in up to 2 times max video bitrate if the
   // bandwidth estimate allows it.
   // TODO(bugs.webrtc.org/8541): May be worth to refactor to keep this logic in
@@ -207,7 +163,6 @@
   int num_pause_events_ RTC_GUARDED_BY(&sequenced_checker_);
   int64_t last_bwe_log_time_ RTC_GUARDED_BY(&sequenced_checker_);
   BitrateAllocationLimits current_limits_ RTC_GUARDED_BY(&sequenced_checker_);
-  const uint8_t transmission_max_bitrate_multiplier_;
 };
 
 }  // namespace webrtc