Index: webrtc/call/bitrate_allocator.cc |
diff --git a/webrtc/call/bitrate_allocator.cc b/webrtc/call/bitrate_allocator.cc |
index 4c8d2a0c441bb20f41d7dd7ac30eb4a2110a85d2..5b1d07ee040cb21862de253931d9daaa7928c702 100644 |
--- a/webrtc/call/bitrate_allocator.cc |
+++ b/webrtc/call/bitrate_allocator.cc |
@@ -14,6 +14,7 @@ |
#include <algorithm> |
#include <utility> |
+#include "webrtc/base/checks.h" |
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" |
namespace webrtc { |
@@ -24,8 +25,7 @@ const int kTransmissionMaxBitrateMultiplier = 2; |
const int kDefaultBitrateBps = 300000; |
BitrateAllocator::BitrateAllocator() |
- : bitrate_observers_(), |
- bitrate_observers_modified_(false), |
+ : bitrate_observer_configs_(), |
enforce_min_bitrate_(true), |
last_bitrate_bps_(kDefaultBitrateBps), |
last_fraction_loss_(0), |
@@ -38,8 +38,9 @@ uint32_t BitrateAllocator::OnNetworkChanged(uint32_t bitrate, |
last_bitrate_bps_ = bitrate; |
last_fraction_loss_ = fraction_loss; |
last_rtt_ = rtt; |
+ |
uint32_t allocated_bitrate_bps = 0; |
- ObserverBitrateMap allocation = AllocateBitrates(); |
+ ObserverAllocation allocation = AllocateBitrates(); |
for (const auto& kv : allocation) { |
kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
allocated_bitrate_bps += kv.second; |
@@ -47,46 +48,32 @@ uint32_t BitrateAllocator::OnNetworkChanged(uint32_t bitrate, |
return allocated_bitrate_bps; |
} |
-BitrateAllocator::ObserverBitrateMap BitrateAllocator::AllocateBitrates() { |
- if (bitrate_observers_.empty()) |
- return ObserverBitrateMap(); |
- |
- uint32_t sum_min_bitrates = 0; |
- for (const auto& observer : bitrate_observers_) |
- sum_min_bitrates += observer.second.min_bitrate; |
- if (last_bitrate_bps_ == 0) |
- return ZeroRateAllocation(); |
- else if (last_bitrate_bps_ <= sum_min_bitrates) |
- return LowRateAllocation(last_bitrate_bps_); |
- else |
- return NormalRateAllocation(last_bitrate_bps_, sum_min_bitrates); |
-} |
- |
int BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, |
uint32_t min_bitrate_bps, |
- uint32_t max_bitrate_bps) { |
+ uint32_t max_bitrate_bps, |
+ bool enforce_min_bitrate) { |
rtc::CritScope lock(&crit_sect_); |
+ // TODO(mflodman): Enforce this per observer. |
+ EnforceMinBitrate(enforce_min_bitrate); |
- BitrateObserverConfList::iterator it = |
- FindObserverConfigurationPair(observer); |
+ auto it = FindObserverConfig(observer); |
// Allow the max bitrate to be exceeded for FEC and retransmissions. |
// TODO(holmer): We have to get rid of this hack as it makes it difficult to |
// properly allocate bitrate. The allocator should instead distribute any |
// extra bitrate after all streams have maxed out. |
max_bitrate_bps *= kTransmissionMaxBitrateMultiplier; |
- if (it != bitrate_observers_.end()) { |
+ if (it != bitrate_observer_configs_.end()) { |
// Update current configuration. |
- it->second.min_bitrate = min_bitrate_bps; |
- it->second.max_bitrate = max_bitrate_bps; |
+ it->min_bitrate_bps = min_bitrate_bps; |
+ it->max_bitrate_bps = max_bitrate_bps; |
} else { |
// Add new settings. |
- bitrate_observers_.push_back(BitrateObserverConfiguration( |
- observer, BitrateConfiguration(min_bitrate_bps, max_bitrate_bps))); |
- bitrate_observers_modified_ = true; |
+ bitrate_observer_configs_.push_back(ObserverConfig( |
+ observer, min_bitrate_bps, max_bitrate_bps, enforce_min_bitrate)); |
} |
- ObserverBitrateMap allocation = AllocateBitrates(); |
+ ObserverAllocation allocation = AllocateBitrates(); |
int new_observer_bitrate_bps = 0; |
for (auto& kv : allocation) { |
kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
@@ -98,60 +85,74 @@ int BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, |
void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { |
rtc::CritScope lock(&crit_sect_); |
- BitrateObserverConfList::iterator it = |
- FindObserverConfigurationPair(observer); |
- if (it != bitrate_observers_.end()) { |
- bitrate_observers_.erase(it); |
- bitrate_observers_modified_ = true; |
+ auto it = FindObserverConfig(observer); |
+ if (it != bitrate_observer_configs_.end()) { |
+ bitrate_observer_configs_.erase(it); |
} |
} |
-BitrateAllocator::BitrateObserverConfList::iterator |
-BitrateAllocator::FindObserverConfigurationPair( |
+void BitrateAllocator::EnforceMinBitrate(bool enforce_min_bitrate) { |
+ enforce_min_bitrate_ = enforce_min_bitrate; |
+} |
+ |
+BitrateAllocator::ObserverConfigList::iterator |
+BitrateAllocator::FindObserverConfig( |
const BitrateAllocatorObserver* observer) { |
- for (auto it = bitrate_observers_.begin(); it != bitrate_observers_.end(); |
- ++it) { |
- if (it->first == observer) |
+ for (auto it = bitrate_observer_configs_.begin(); |
+ it != bitrate_observer_configs_.end(); ++it) { |
+ if (it->observer == observer) |
return it; |
} |
- return bitrate_observers_.end(); |
+ return bitrate_observer_configs_.end(); |
} |
-void BitrateAllocator::EnforceMinBitrate(bool enforce_min_bitrate) { |
- rtc::CritScope lock(&crit_sect_); |
- enforce_min_bitrate_ = enforce_min_bitrate; |
+BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates() { |
+ if (bitrate_observer_configs_.empty()) |
+ return ObserverAllocation(); |
+ |
+ if (last_bitrate_bps_ == 0) |
+ return ZeroRateAllocation(); |
+ |
+ uint32_t sum_min_bitrates = 0; |
+ for (const auto& observer_config : bitrate_observer_configs_) |
+ sum_min_bitrates += observer_config.min_bitrate_bps; |
+ if (last_bitrate_bps_ <= sum_min_bitrates) |
+ return LowRateAllocation(last_bitrate_bps_); |
+ |
+ return NormalRateAllocation(last_bitrate_bps_, sum_min_bitrates); |
} |
-BitrateAllocator::ObserverBitrateMap BitrateAllocator::NormalRateAllocation( |
+BitrateAllocator::ObserverAllocation BitrateAllocator::NormalRateAllocation( |
uint32_t bitrate, |
uint32_t sum_min_bitrates) { |
- uint32_t number_of_observers = |
- static_cast<uint32_t>(bitrate_observers_.size()); |
+ uint32_t num_remaining_observers = |
+ static_cast<uint32_t>(bitrate_observer_configs_.size()); |
+ RTC_DCHECK_GT(num_remaining_observers, 0u); |
+ |
uint32_t bitrate_per_observer = |
- (bitrate - sum_min_bitrates) / number_of_observers; |
+ (bitrate - sum_min_bitrates) / num_remaining_observers; |
// Use map to sort list based on max bitrate. |
ObserverSortingMap list_max_bitrates; |
- for (const auto& observer : bitrate_observers_) { |
- list_max_bitrates.insert(std::pair<uint32_t, ObserverConfiguration>( |
- observer.second.max_bitrate, |
- ObserverConfiguration(observer.first, observer.second.min_bitrate))); |
+ for (const auto& config : bitrate_observer_configs_) { |
+ list_max_bitrates.insert(std::pair<uint32_t, const ObserverConfig*>( |
+ config.max_bitrate_bps, &config)); |
} |
- ObserverBitrateMap allocation; |
+ |
+ ObserverAllocation allocation; |
ObserverSortingMap::iterator max_it = list_max_bitrates.begin(); |
while (max_it != list_max_bitrates.end()) { |
- number_of_observers--; |
+ num_remaining_observers--; |
uint32_t observer_allowance = |
- max_it->second.min_bitrate + bitrate_per_observer; |
+ max_it->second->min_bitrate_bps + bitrate_per_observer; |
if (max_it->first < observer_allowance) { |
// We have more than enough for this observer. |
// Carry the remainder forward. |
uint32_t remainder = observer_allowance - max_it->first; |
- if (number_of_observers != 0) { |
- bitrate_per_observer += remainder / number_of_observers; |
- } |
- allocation[max_it->second.observer] = max_it->first; |
+ if (num_remaining_observers != 0) |
+ bitrate_per_observer += remainder / num_remaining_observers; |
+ allocation[max_it->second->observer] = max_it->first; |
} else { |
- allocation[max_it->second.observer] = observer_allowance; |
+ allocation[max_it->second->observer] = observer_allowance; |
} |
list_max_bitrates.erase(max_it); |
// Prepare next iteration. |
@@ -160,29 +161,29 @@ BitrateAllocator::ObserverBitrateMap BitrateAllocator::NormalRateAllocation( |
return allocation; |
} |
-BitrateAllocator::ObserverBitrateMap BitrateAllocator::ZeroRateAllocation() { |
- ObserverBitrateMap allocation; |
+BitrateAllocator::ObserverAllocation BitrateAllocator::ZeroRateAllocation() { |
+ ObserverAllocation allocation; |
// Zero bitrate to all observers. |
- for (const auto& observer : bitrate_observers_) |
- allocation[observer.first] = 0; |
+ for (const auto& observer_config : bitrate_observer_configs_) |
+ allocation[observer_config.observer] = 0; |
return allocation; |
} |
-BitrateAllocator::ObserverBitrateMap BitrateAllocator::LowRateAllocation( |
+BitrateAllocator::ObserverAllocation BitrateAllocator::LowRateAllocation( |
uint32_t bitrate) { |
- ObserverBitrateMap allocation; |
+ ObserverAllocation allocation; |
if (enforce_min_bitrate_) { |
// Min bitrate to all observers. |
- for (const auto& observer : bitrate_observers_) |
- allocation[observer.first] = observer.second.min_bitrate; |
+ for (const auto& observer_config : bitrate_observer_configs_) |
+ allocation[observer_config.observer] = observer_config.min_bitrate_bps; |
} else { |
- // Allocate up to |min_bitrate| to one observer at a time, until |
+ // Allocate up to |min_bitrate_bps| to one observer at a time, until |
// |bitrate| is depleted. |
uint32_t remainder = bitrate; |
- for (const auto& observer : bitrate_observers_) { |
+ for (const auto& observer_config : bitrate_observer_configs_) { |
uint32_t allocated_bitrate = |
- std::min(remainder, observer.second.min_bitrate); |
- allocation[observer.first] = allocated_bitrate; |
+ std::min(remainder, observer_config.min_bitrate_bps); |
+ allocation[observer_config.observer] = allocated_bitrate; |
remainder -= allocated_bitrate; |
} |
} |