| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 * | 9 * |
| 10 */ | 10 */ |
| 11 | 11 |
| 12 #include "webrtc/call/bitrate_allocator.h" | 12 #include "webrtc/call/bitrate_allocator.h" |
| 13 | 13 |
| 14 #include <algorithm> | 14 #include <algorithm> |
| 15 #include <utility> | 15 #include <utility> |
| 16 | 16 |
| 17 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | 18 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" |
| 19 | 19 |
| 20 namespace webrtc { | 20 namespace webrtc { |
| 21 | 21 |
| 22 // Allow packets to be transmitted in up to 2 times max video bitrate if the | 22 // Allow packets to be transmitted in up to 2 times max video bitrate if the |
| 23 // bandwidth estimate allows it. | 23 // bandwidth estimate allows it. |
| 24 const int kTransmissionMaxBitrateMultiplier = 2; | 24 const int kTransmissionMaxBitrateMultiplier = 2; |
| 25 const int kDefaultBitrateBps = 300000; | 25 const int kDefaultBitrateBps = 300000; |
| 26 | 26 |
| 27 BitrateAllocator::BitrateAllocator() | 27 BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer) |
| 28 : bitrate_observer_configs_(), | 28 : limit_observer_(limit_observer), |
| 29 bitrate_observer_configs_(), |
| 29 enforce_min_bitrate_(true), | 30 enforce_min_bitrate_(true), |
| 30 last_bitrate_bps_(kDefaultBitrateBps), | 31 last_bitrate_bps_(kDefaultBitrateBps), |
| 31 last_non_zero_bitrate_bps_(kDefaultBitrateBps), | 32 last_non_zero_bitrate_bps_(kDefaultBitrateBps), |
| 32 last_fraction_loss_(0), | 33 last_fraction_loss_(0), |
| 33 last_rtt_(0) {} | 34 last_rtt_(0) {} |
| 34 | 35 |
| 35 uint32_t BitrateAllocator::OnNetworkChanged(uint32_t bitrate, | 36 void BitrateAllocator::OnNetworkChanged(uint32_t bitrate, |
| 36 uint8_t fraction_loss, | 37 uint8_t fraction_loss, |
| 37 int64_t rtt) { | 38 int64_t rtt) { |
| 38 rtc::CritScope lock(&crit_sect_); | 39 rtc::CritScope lock(&crit_sect_); |
| 39 last_bitrate_bps_ = bitrate; | 40 last_bitrate_bps_ = bitrate; |
| 40 last_non_zero_bitrate_bps_ = | 41 last_non_zero_bitrate_bps_ = |
| 41 bitrate > 0 ? bitrate : last_non_zero_bitrate_bps_; | 42 bitrate > 0 ? bitrate : last_non_zero_bitrate_bps_; |
| 42 last_fraction_loss_ = fraction_loss; | 43 last_fraction_loss_ = fraction_loss; |
| 43 last_rtt_ = rtt; | 44 last_rtt_ = rtt; |
| 44 | 45 |
| 45 uint32_t allocated_bitrate_bps = 0; | |
| 46 ObserverAllocation allocation = AllocateBitrates(bitrate); | 46 ObserverAllocation allocation = AllocateBitrates(bitrate); |
| 47 for (const auto& kv : allocation) { | 47 for (const auto& kv : allocation) { |
| 48 kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); | 48 kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
| 49 allocated_bitrate_bps += kv.second; | |
| 50 } | 49 } |
| 51 return allocated_bitrate_bps; | |
| 52 } | 50 } |
| 53 | 51 |
| 54 int BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, | 52 int BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, |
| 55 uint32_t min_bitrate_bps, | 53 uint32_t min_bitrate_bps, |
| 56 uint32_t max_bitrate_bps, | 54 uint32_t max_bitrate_bps, |
| 55 uint32_t pad_up_bitrate_bps, |
| 57 bool enforce_min_bitrate) { | 56 bool enforce_min_bitrate) { |
| 57 int new_observer_bitrate_bps = 0; |
| 58 rtc::CritScope lock(&crit_sect_); | 58 rtc::CritScope lock(&crit_sect_); |
| 59 // TODO(mflodman): Enforce this per observer. | 59 { |
| 60 EnforceMinBitrate(enforce_min_bitrate); | 60 // TODO(mflodman): Enforce this per observer. |
| 61 EnforceMinBitrate(enforce_min_bitrate); |
| 61 | 62 |
| 62 auto it = FindObserverConfig(observer); | 63 auto it = FindObserverConfig(observer); |
| 63 | 64 |
| 64 // Allow the max bitrate to be exceeded for FEC and retransmissions. | 65 // Allow the max bitrate to be exceeded for FEC and retransmissions. |
| 65 // TODO(holmer): We have to get rid of this hack as it makes it difficult to | 66 // TODO(holmer): We have to get rid of this hack as it makes it difficult to |
| 66 // properly allocate bitrate. The allocator should instead distribute any | 67 // properly allocate bitrate. The allocator should instead distribute any |
| 67 // extra bitrate after all streams have maxed out. | 68 // extra bitrate after all streams have maxed out. |
| 68 max_bitrate_bps *= kTransmissionMaxBitrateMultiplier; | 69 max_bitrate_bps *= kTransmissionMaxBitrateMultiplier; |
| 69 if (it != bitrate_observer_configs_.end()) { | 70 if (it != bitrate_observer_configs_.end()) { |
| 70 // Update current configuration. | 71 // Update current configuration. |
| 71 it->min_bitrate_bps = min_bitrate_bps; | 72 it->min_bitrate_bps = min_bitrate_bps; |
| 72 it->max_bitrate_bps = max_bitrate_bps; | 73 it->max_bitrate_bps = max_bitrate_bps; |
| 73 } else { | 74 it->pad_up_bitrate_bps = pad_up_bitrate_bps; |
| 74 // Add new settings. | 75 } else { |
| 75 bitrate_observer_configs_.push_back(ObserverConfig( | 76 // Add new settings. |
| 76 observer, min_bitrate_bps, max_bitrate_bps, enforce_min_bitrate)); | 77 bitrate_observer_configs_.push_back( |
| 78 ObserverConfig(observer, min_bitrate_bps, max_bitrate_bps, |
| 79 pad_up_bitrate_bps, enforce_min_bitrate)); |
| 80 } |
| 81 |
| 82 if (last_bitrate_bps_ > 0) { // We have a bitrate to allocate. |
| 83 ObserverAllocation allocation = AllocateBitrates(last_bitrate_bps_); |
| 84 for (auto& kv : allocation) { |
| 85 // Update all observers with the new allocation. |
| 86 kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
| 87 if (kv.first == observer) |
| 88 new_observer_bitrate_bps = kv.second; |
| 89 } |
| 90 } else { |
| 91 // Currently, an encoder is not allowed to produce frames. |
| 92 // But we still have to return the initial config bitrate + let the |
| 93 // observer know that it can not produce frames. |
| 94 ObserverAllocation allocation = |
| 95 AllocateBitrates(last_non_zero_bitrate_bps_); |
| 96 observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); |
| 97 new_observer_bitrate_bps = allocation[observer]; |
| 98 } |
| 77 } | 99 } |
| 100 UpdateAllocationLimits(); |
| 78 | 101 |
| 79 int new_observer_bitrate_bps = 0; | |
| 80 if (last_bitrate_bps_ > 0) { // We have a bitrate to allocate. | |
| 81 ObserverAllocation allocation = AllocateBitrates(last_bitrate_bps_); | |
| 82 for (auto& kv : allocation) { | |
| 83 // Update all observers with the new allocation. | |
| 84 kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); | |
| 85 if (kv.first == observer) | |
| 86 new_observer_bitrate_bps = kv.second; | |
| 87 } | |
| 88 } else { | |
| 89 // Currently, an encoder is not allowed to produce frames. | |
| 90 // But we still have to return the initial config bitrate + let the | |
| 91 // observer know that it can not produce frames. | |
| 92 ObserverAllocation allocation = | |
| 93 AllocateBitrates(last_non_zero_bitrate_bps_); | |
| 94 observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); | |
| 95 new_observer_bitrate_bps = allocation[observer]; | |
| 96 } | |
| 97 return new_observer_bitrate_bps; | 102 return new_observer_bitrate_bps; |
| 98 } | 103 } |
| 99 | 104 |
| 105 void BitrateAllocator::UpdateAllocationLimits() { |
| 106 uint32_t total_requested_padding_bitrate = 0; |
| 107 uint32_t total_requested_min_bitrate = 0; |
| 108 |
| 109 { |
| 110 rtc::CritScope lock(&crit_sect_); |
| 111 for (const auto& config : bitrate_observer_configs_) { |
| 112 if (enforce_min_bitrate_) { |
| 113 total_requested_min_bitrate += config.min_bitrate_bps; |
| 114 } |
| 115 total_requested_padding_bitrate += config.pad_up_bitrate_bps; |
| 116 } |
| 117 } |
| 118 |
| 119 limit_observer_->OnAllocationLimitsChanged(total_requested_min_bitrate, |
| 120 total_requested_padding_bitrate); |
| 121 } |
| 122 |
| 100 void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { | 123 void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { |
| 101 rtc::CritScope lock(&crit_sect_); | 124 { |
| 102 auto it = FindObserverConfig(observer); | 125 rtc::CritScope lock(&crit_sect_); |
| 103 if (it != bitrate_observer_configs_.end()) { | 126 auto it = FindObserverConfig(observer); |
| 104 bitrate_observer_configs_.erase(it); | 127 if (it != bitrate_observer_configs_.end()) { |
| 128 bitrate_observer_configs_.erase(it); |
| 129 } |
| 105 } | 130 } |
| 131 UpdateAllocationLimits(); |
| 106 } | 132 } |
| 107 | 133 |
| 108 void BitrateAllocator::EnforceMinBitrate(bool enforce_min_bitrate) { | 134 void BitrateAllocator::EnforceMinBitrate(bool enforce_min_bitrate) { |
| 109 enforce_min_bitrate_ = enforce_min_bitrate; | 135 enforce_min_bitrate_ = enforce_min_bitrate; |
| 110 } | 136 } |
| 111 | 137 |
| 112 BitrateAllocator::ObserverConfigList::iterator | 138 BitrateAllocator::ObserverConfigList::iterator |
| 113 BitrateAllocator::FindObserverConfig( | 139 BitrateAllocator::FindObserverConfig( |
| 114 const BitrateAllocatorObserver* observer) { | 140 const BitrateAllocatorObserver* observer) { |
| 115 for (auto it = bitrate_observer_configs_.begin(); | 141 for (auto it = bitrate_observer_configs_.begin(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 for (const auto& observer_config : bitrate_observer_configs_) { | 224 for (const auto& observer_config : bitrate_observer_configs_) { |
| 199 uint32_t allocated_bitrate = | 225 uint32_t allocated_bitrate = |
| 200 std::min(remainder, observer_config.min_bitrate_bps); | 226 std::min(remainder, observer_config.min_bitrate_bps); |
| 201 allocation[observer_config.observer] = allocated_bitrate; | 227 allocation[observer_config.observer] = allocated_bitrate; |
| 202 remainder -= allocated_bitrate; | 228 remainder -= allocated_bitrate; |
| 203 } | 229 } |
| 204 } | 230 } |
| 205 return allocation; | 231 return allocation; |
| 206 } | 232 } |
| 207 } // namespace webrtc | 233 } // namespace webrtc |
| OLD | NEW |