Index: webrtc/call/bitrate_allocator.cc |
diff --git a/webrtc/call/bitrate_allocator.cc b/webrtc/call/bitrate_allocator.cc |
index 3672ef520ca3422bc372d2108b75abf9b5390666..2d56ff80b399472d7650c3d53ad6c5f7f30db842 100644 |
--- a/webrtc/call/bitrate_allocator.cc |
+++ b/webrtc/call/bitrate_allocator.cc |
@@ -24,17 +24,18 @@ namespace webrtc { |
const int kTransmissionMaxBitrateMultiplier = 2; |
const int kDefaultBitrateBps = 300000; |
-BitrateAllocator::BitrateAllocator() |
- : bitrate_observer_configs_(), |
+BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer) |
+ : limit_observer_(limit_observer), |
+ bitrate_observer_configs_(), |
enforce_min_bitrate_(true), |
last_bitrate_bps_(kDefaultBitrateBps), |
last_non_zero_bitrate_bps_(kDefaultBitrateBps), |
last_fraction_loss_(0), |
last_rtt_(0) {} |
-uint32_t BitrateAllocator::OnNetworkChanged(uint32_t bitrate, |
- uint8_t fraction_loss, |
- int64_t rtt) { |
+void BitrateAllocator::OnNetworkChanged(uint32_t bitrate, |
+ uint8_t fraction_loss, |
+ int64_t rtt) { |
rtc::CritScope lock(&crit_sect_); |
last_bitrate_bps_ = bitrate; |
last_non_zero_bitrate_bps_ = |
@@ -42,67 +43,92 @@ uint32_t BitrateAllocator::OnNetworkChanged(uint32_t bitrate, |
last_fraction_loss_ = fraction_loss; |
last_rtt_ = rtt; |
- uint32_t allocated_bitrate_bps = 0; |
ObserverAllocation allocation = AllocateBitrates(bitrate); |
for (const auto& kv : allocation) { |
kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
- allocated_bitrate_bps += kv.second; |
} |
- return allocated_bitrate_bps; |
} |
int BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, |
uint32_t min_bitrate_bps, |
uint32_t max_bitrate_bps, |
+ uint32_t pad_up_bitrate_bps, |
bool enforce_min_bitrate) { |
+ int new_observer_bitrate_bps = 0; |
rtc::CritScope lock(&crit_sect_); |
- // TODO(mflodman): Enforce this per observer. |
- EnforceMinBitrate(enforce_min_bitrate); |
- |
- 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_observer_configs_.end()) { |
- // Update current configuration. |
- it->min_bitrate_bps = min_bitrate_bps; |
- it->max_bitrate_bps = max_bitrate_bps; |
- } else { |
- // Add new settings. |
- bitrate_observer_configs_.push_back(ObserverConfig( |
- observer, min_bitrate_bps, max_bitrate_bps, enforce_min_bitrate)); |
- } |
+ { |
+ // TODO(mflodman): Enforce this per observer. |
+ EnforceMinBitrate(enforce_min_bitrate); |
+ |
+ 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_observer_configs_.end()) { |
+ // Update current configuration. |
+ it->min_bitrate_bps = min_bitrate_bps; |
+ it->max_bitrate_bps = max_bitrate_bps; |
+ it->pad_up_bitrate_bps = pad_up_bitrate_bps; |
+ } else { |
+ // Add new settings. |
+ bitrate_observer_configs_.push_back( |
+ ObserverConfig(observer, min_bitrate_bps, max_bitrate_bps, |
+ pad_up_bitrate_bps, enforce_min_bitrate)); |
+ } |
- int new_observer_bitrate_bps = 0; |
- if (last_bitrate_bps_ > 0) { // We have a bitrate to allocate. |
- ObserverAllocation allocation = AllocateBitrates(last_bitrate_bps_); |
- for (auto& kv : allocation) { |
- // Update all observers with the new allocation. |
- kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
- if (kv.first == observer) |
- new_observer_bitrate_bps = kv.second; |
+ if (last_bitrate_bps_ > 0) { // We have a bitrate to allocate. |
+ ObserverAllocation allocation = AllocateBitrates(last_bitrate_bps_); |
+ for (auto& kv : allocation) { |
+ // Update all observers with the new allocation. |
+ kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
+ if (kv.first == observer) |
+ new_observer_bitrate_bps = kv.second; |
+ } |
+ } else { |
+ // Currently, an encoder is not allowed to produce frames. |
+ // But we still have to return the initial config bitrate + let the |
+ // observer know that it can not produce frames. |
+ ObserverAllocation allocation = |
+ AllocateBitrates(last_non_zero_bitrate_bps_); |
+ observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); |
+ new_observer_bitrate_bps = allocation[observer]; |
} |
- } else { |
- // Currently, an encoder is not allowed to produce frames. |
- // But we still have to return the initial config bitrate + let the |
- // observer know that it can not produce frames. |
- ObserverAllocation allocation = |
- AllocateBitrates(last_non_zero_bitrate_bps_); |
- observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); |
- new_observer_bitrate_bps = allocation[observer]; |
} |
+ UpdateAllocationLimits(); |
+ |
return new_observer_bitrate_bps; |
} |
+void BitrateAllocator::UpdateAllocationLimits() { |
+ uint32_t total_requested_padding_bitrate = 0; |
+ uint32_t total_requested_min_bitrate = 0; |
+ |
+ { |
+ rtc::CritScope lock(&crit_sect_); |
+ for (const auto& config : bitrate_observer_configs_) { |
+ if (enforce_min_bitrate_) { |
+ total_requested_min_bitrate += config.min_bitrate_bps; |
+ } |
+ total_requested_padding_bitrate += config.pad_up_bitrate_bps; |
+ } |
+ } |
+ |
+ limit_observer_->OnAllocationLimitsChanged(total_requested_min_bitrate, |
+ total_requested_padding_bitrate); |
+} |
+ |
void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { |
- rtc::CritScope lock(&crit_sect_); |
- auto it = FindObserverConfig(observer); |
- if (it != bitrate_observer_configs_.end()) { |
- bitrate_observer_configs_.erase(it); |
+ { |
+ rtc::CritScope lock(&crit_sect_); |
+ auto it = FindObserverConfig(observer); |
+ if (it != bitrate_observer_configs_.end()) { |
+ bitrate_observer_configs_.erase(it); |
+ } |
} |
+ UpdateAllocationLimits(); |
} |
void BitrateAllocator::EnforceMinBitrate(bool enforce_min_bitrate) { |