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 // Require a bitrate increase of max(10%, 20kbps) to resume paused streams. | |
28 const double kToggleFactor = 0.1; | |
29 const uint32_t kMinToggleBitrateBps = 20000; | |
30 | |
27 BitrateAllocator::BitrateAllocator() | 31 BitrateAllocator::BitrateAllocator() |
28 : bitrate_observer_configs_(), | 32 : bitrate_observer_configs_(), |
29 enforce_min_bitrate_(true), | |
30 last_bitrate_bps_(kDefaultBitrateBps), | 33 last_bitrate_bps_(kDefaultBitrateBps), |
31 last_non_zero_bitrate_bps_(kDefaultBitrateBps), | 34 last_non_zero_bitrate_bps_(kDefaultBitrateBps), |
32 last_fraction_loss_(0), | 35 last_fraction_loss_(0), |
33 last_rtt_(0) {} | 36 last_rtt_(0) {} |
34 | 37 |
35 uint32_t BitrateAllocator::OnNetworkChanged(uint32_t bitrate, | 38 uint32_t BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps, |
36 uint8_t fraction_loss, | 39 uint8_t fraction_loss, |
37 int64_t rtt) { | 40 int64_t rtt) { |
38 rtc::CritScope lock(&crit_sect_); | 41 rtc::CritScope lock(&crit_sect_); |
39 last_bitrate_bps_ = bitrate; | 42 last_bitrate_bps_ = target_bitrate_bps; |
40 last_non_zero_bitrate_bps_ = | 43 last_non_zero_bitrate_bps_ = |
41 bitrate > 0 ? bitrate : last_non_zero_bitrate_bps_; | 44 target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_; |
42 last_fraction_loss_ = fraction_loss; | 45 last_fraction_loss_ = fraction_loss; |
43 last_rtt_ = rtt; | 46 last_rtt_ = rtt; |
44 | 47 |
45 uint32_t allocated_bitrate_bps = 0; | 48 uint32_t allocated_bitrate_bps = 0; |
46 ObserverAllocation allocation = AllocateBitrates(bitrate); | 49 ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps); |
47 for (const auto& kv : allocation) { | 50 for (const auto& kv : allocation) { |
48 kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); | 51 kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |
49 allocated_bitrate_bps += kv.second; | 52 allocated_bitrate_bps += kv.second; |
50 } | 53 } |
54 last_allocation_ = allocation; | |
51 return allocated_bitrate_bps; | 55 return allocated_bitrate_bps; |
52 } | 56 } |
53 | 57 |
54 int BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, | 58 int BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, |
55 uint32_t min_bitrate_bps, | 59 uint32_t min_bitrate_bps, |
56 uint32_t max_bitrate_bps, | 60 uint32_t max_bitrate_bps, |
57 bool enforce_min_bitrate) { | 61 bool enforce_min_bitrate) { |
58 rtc::CritScope lock(&crit_sect_); | 62 rtc::CritScope lock(&crit_sect_); |
59 // TODO(mflodman): Enforce this per observer. | |
60 EnforceMinBitrate(enforce_min_bitrate); | |
61 | |
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 // Update settings if the observer already exists, create a new one otherwise. |
65 // 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 // extra bitrate after all streams have maxed out. | |
68 max_bitrate_bps *= kTransmissionMaxBitrateMultiplier; | |
69 if (it != bitrate_observer_configs_.end()) { | 66 if (it != bitrate_observer_configs_.end()) { |
70 // Update current configuration. | |
71 it->min_bitrate_bps = min_bitrate_bps; | 67 it->min_bitrate_bps = min_bitrate_bps; |
72 it->max_bitrate_bps = max_bitrate_bps; | 68 it->max_bitrate_bps = max_bitrate_bps; |
69 it->enforce_min_bitrate = enforce_min_bitrate; | |
73 } else { | 70 } else { |
74 // Add new settings. | |
75 bitrate_observer_configs_.push_back(ObserverConfig( | 71 bitrate_observer_configs_.push_back(ObserverConfig( |
76 observer, min_bitrate_bps, max_bitrate_bps, enforce_min_bitrate)); | 72 observer, min_bitrate_bps, max_bitrate_bps, enforce_min_bitrate)); |
77 } | 73 } |
78 | 74 |
79 int new_observer_bitrate_bps = 0; | 75 ObserverAllocation allocation; |
80 if (last_bitrate_bps_ > 0) { // We have a bitrate to allocate. | 76 if (last_bitrate_bps_ > 0) { |
81 ObserverAllocation allocation = AllocateBitrates(last_bitrate_bps_); | 77 // Calculate a new allocation and update all observers. |
82 for (auto& kv : allocation) { | 78 allocation = AllocateBitrates(last_bitrate_bps_); |
83 // Update all observers with the new allocation. | 79 for (const auto& kv : allocation) |
84 kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); | 80 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 { | 81 } else { |
89 // Currently, an encoder is not allowed to produce frames. | 82 // Currently, an encoder is not allowed to produce frames. |
90 // But we still have to return the initial config bitrate + let the | 83 // But we still have to return the initial config bitrate + let the |
91 // observer know that it can not produce frames. | 84 // observer know that it can not produce frames. |
92 ObserverAllocation allocation = | 85 allocation = AllocateBitrates(last_non_zero_bitrate_bps_); |
93 AllocateBitrates(last_non_zero_bitrate_bps_); | |
94 observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); | 86 observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); |
95 new_observer_bitrate_bps = allocation[observer]; | |
96 } | 87 } |
97 return new_observer_bitrate_bps; | 88 last_allocation_ = allocation; |
89 return allocation[observer]; | |
98 } | 90 } |
99 | 91 |
100 void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { | 92 void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { |
101 rtc::CritScope lock(&crit_sect_); | 93 rtc::CritScope lock(&crit_sect_); |
102 auto it = FindObserverConfig(observer); | 94 auto it = FindObserverConfig(observer); |
103 if (it != bitrate_observer_configs_.end()) { | 95 if (it != bitrate_observer_configs_.end()) { |
104 bitrate_observer_configs_.erase(it); | 96 bitrate_observer_configs_.erase(it); |
105 } | 97 } |
106 } | 98 } |
107 | 99 |
108 void BitrateAllocator::EnforceMinBitrate(bool enforce_min_bitrate) { | |
109 enforce_min_bitrate_ = enforce_min_bitrate; | |
110 } | |
111 | |
112 BitrateAllocator::ObserverConfigList::iterator | 100 BitrateAllocator::ObserverConfigList::iterator |
113 BitrateAllocator::FindObserverConfig( | 101 BitrateAllocator::FindObserverConfig( |
114 const BitrateAllocatorObserver* observer) { | 102 const BitrateAllocatorObserver* observer) { |
115 for (auto it = bitrate_observer_configs_.begin(); | 103 for (auto it = bitrate_observer_configs_.begin(); |
116 it != bitrate_observer_configs_.end(); ++it) { | 104 it != bitrate_observer_configs_.end(); ++it) { |
117 if (it->observer == observer) | 105 if (it->observer == observer) |
118 return it; | 106 return it; |
119 } | 107 } |
120 return bitrate_observer_configs_.end(); | 108 return bitrate_observer_configs_.end(); |
121 } | 109 } |
122 | 110 |
123 BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates( | 111 BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates( |
124 uint32_t bitrate) { | 112 uint32_t bitrate) { |
125 if (bitrate_observer_configs_.empty()) | 113 if (bitrate_observer_configs_.empty()) |
126 return ObserverAllocation(); | 114 return ObserverAllocation(); |
127 | 115 |
128 if (bitrate == 0) | 116 if (bitrate == 0) |
129 return ZeroRateAllocation(); | 117 return ZeroRateAllocation(); |
130 | 118 |
131 uint32_t sum_min_bitrates = 0; | 119 uint32_t sum_min_bitrates = 0; |
132 for (const auto& observer_config : bitrate_observer_configs_) | 120 uint32_t sum_max_bitrates = 0; |
121 for (const auto& observer_config : bitrate_observer_configs_) { | |
133 sum_min_bitrates += observer_config.min_bitrate_bps; | 122 sum_min_bitrates += observer_config.min_bitrate_bps; |
134 if (bitrate <= sum_min_bitrates) | 123 sum_max_bitrates += observer_config.max_bitrate_bps; |
124 } | |
125 | |
126 // Not enough for all observers to get an allocation, allocate according to: | |
127 // enforced min bitrate -> allocated bitrate previous round -> restart paused | |
128 // streams. | |
129 if (EnoughBitrateForAllObservers(bitrate, sum_min_bitrates)) | |
pbos-webrtc
2016/06/09 13:37:21
!Enough, but preferably !BitrateSufficientForAllOb
| |
135 return LowRateAllocation(bitrate); | 130 return LowRateAllocation(bitrate); |
136 | 131 |
137 return NormalRateAllocation(bitrate, sum_min_bitrates); | 132 // All observers will get their min bitrate plus an even share of the rest. |
138 } | 133 if (bitrate <= sum_max_bitrates) |
134 return NormalRateAllocation(bitrate, sum_min_bitrates); | |
139 | 135 |
140 BitrateAllocator::ObserverAllocation BitrateAllocator::NormalRateAllocation( | 136 // All observers will get up to kTransmissionMaxBitrateMultiplier x max. |
141 uint32_t bitrate, | 137 return MaxRateAllocation(bitrate, sum_max_bitrates); |
142 uint32_t sum_min_bitrates) { | |
143 uint32_t num_remaining_observers = | |
144 static_cast<uint32_t>(bitrate_observer_configs_.size()); | |
145 RTC_DCHECK_GT(num_remaining_observers, 0u); | |
146 | |
147 uint32_t bitrate_per_observer = | |
148 (bitrate - sum_min_bitrates) / num_remaining_observers; | |
149 // Use map to sort list based on max bitrate. | |
150 ObserverSortingMap list_max_bitrates; | |
151 for (const auto& config : bitrate_observer_configs_) { | |
152 list_max_bitrates.insert(std::pair<uint32_t, const ObserverConfig*>( | |
153 config.max_bitrate_bps, &config)); | |
154 } | |
155 | |
156 ObserverAllocation allocation; | |
157 ObserverSortingMap::iterator max_it = list_max_bitrates.begin(); | |
158 while (max_it != list_max_bitrates.end()) { | |
159 num_remaining_observers--; | |
160 uint32_t observer_allowance = | |
161 max_it->second->min_bitrate_bps + bitrate_per_observer; | |
162 if (max_it->first < observer_allowance) { | |
163 // We have more than enough for this observer. | |
164 // Carry the remainder forward. | |
165 uint32_t remainder = observer_allowance - max_it->first; | |
166 if (num_remaining_observers != 0) | |
167 bitrate_per_observer += remainder / num_remaining_observers; | |
168 allocation[max_it->second->observer] = max_it->first; | |
169 } else { | |
170 allocation[max_it->second->observer] = observer_allowance; | |
171 } | |
172 list_max_bitrates.erase(max_it); | |
173 // Prepare next iteration. | |
174 max_it = list_max_bitrates.begin(); | |
175 } | |
176 return allocation; | |
177 } | 138 } |
178 | 139 |
179 BitrateAllocator::ObserverAllocation BitrateAllocator::ZeroRateAllocation() { | 140 BitrateAllocator::ObserverAllocation BitrateAllocator::ZeroRateAllocation() { |
180 ObserverAllocation allocation; | 141 ObserverAllocation allocation; |
181 // Zero bitrate to all observers. | |
182 for (const auto& observer_config : bitrate_observer_configs_) | 142 for (const auto& observer_config : bitrate_observer_configs_) |
183 allocation[observer_config.observer] = 0; | 143 allocation[observer_config.observer] = 0; |
184 return allocation; | 144 return allocation; |
185 } | 145 } |
186 | 146 |
187 BitrateAllocator::ObserverAllocation BitrateAllocator::LowRateAllocation( | 147 BitrateAllocator::ObserverAllocation BitrateAllocator::LowRateAllocation( |
188 uint32_t bitrate) { | 148 uint32_t bitrate) { |
189 ObserverAllocation allocation; | 149 ObserverAllocation allocation; |
190 if (enforce_min_bitrate_) { | 150 |
191 // Min bitrate to all observers. | 151 // Start by allocating bitrate to observers enforcing a min bitrate, hence |
192 for (const auto& observer_config : bitrate_observer_configs_) | 152 // remaining_bitrate might turn negative. |
193 allocation[observer_config.observer] = observer_config.min_bitrate_bps; | 153 int64_t remaining_bitrate = bitrate; |
194 } else { | 154 for (const auto& observer_config : bitrate_observer_configs_) { |
195 // Allocate up to |min_bitrate_bps| to one observer at a time, until | 155 int32_t allocated_bitrate = 0; |
196 // |bitrate| is depleted. | 156 if (observer_config.enforce_min_bitrate) |
197 uint32_t remainder = bitrate; | 157 allocated_bitrate = observer_config.min_bitrate_bps; |
158 | |
159 allocation[observer_config.observer] = allocated_bitrate; | |
160 remaining_bitrate -= allocated_bitrate; | |
161 } | |
162 | |
163 // Allocate bitrate to all previously active streams. | |
164 if (remaining_bitrate > 0) { | |
198 for (const auto& observer_config : bitrate_observer_configs_) { | 165 for (const auto& observer_config : bitrate_observer_configs_) { |
199 uint32_t allocated_bitrate = | 166 if (observer_config.enforce_min_bitrate || |
200 std::min(remainder, observer_config.min_bitrate_bps); | 167 LastAllocatedBitrate(observer_config) == 0) |
201 allocation[observer_config.observer] = allocated_bitrate; | 168 continue; |
202 remainder -= allocated_bitrate; | 169 |
170 if (remaining_bitrate >= observer_config.min_bitrate_bps) { | |
171 allocation[observer_config.observer] = observer_config.min_bitrate_bps; | |
172 remaining_bitrate -= observer_config.min_bitrate_bps; | |
173 } | |
203 } | 174 } |
204 } | 175 } |
176 | |
177 // Allocate bitrate to previously paused streams. | |
178 if (remaining_bitrate > 0) { | |
179 for (const auto& observer_config : bitrate_observer_configs_) { | |
180 if (LastAllocatedBitrate(observer_config) != 0) | |
181 continue; | |
182 | |
183 // Add a hysteresis to avoid toggling. | |
184 uint32_t required_bitrate = MinBitrateWithHysteresis(observer_config); | |
185 if (remaining_bitrate >= required_bitrate) { | |
186 allocation[observer_config.observer] = required_bitrate; | |
187 remaining_bitrate -= required_bitrate; | |
188 } | |
189 } | |
190 } | |
191 | |
192 // Split a possible remainder evenly on all streams with an allocation. | |
193 if (remaining_bitrate > 0) | |
194 DistributeBitrateEvenly(remaining_bitrate, false, 1, &allocation); | |
195 | |
196 RTC_DCHECK_EQ(allocation.size(), bitrate_observer_configs_.size()); | |
205 return allocation; | 197 return allocation; |
206 } | 198 } |
199 | |
200 BitrateAllocator::ObserverAllocation BitrateAllocator::NormalRateAllocation( | |
201 uint32_t bitrate, | |
202 uint32_t sum_min_bitrates) { | |
203 | |
204 ObserverAllocation allocation; | |
205 for (const auto& observer_config : bitrate_observer_configs_) { | |
206 // Adding at least 1bps simplifies the implementation of | |
207 // DistributeBitrateEvenly. | |
208 allocation[observer_config.observer] = observer_config.min_bitrate_bps; | |
209 } | |
210 | |
211 bitrate -= sum_min_bitrates; | |
212 if (bitrate > 0) | |
213 DistributeBitrateEvenly(bitrate, true, 1, &allocation); | |
214 | |
215 return allocation; | |
216 } | |
217 | |
218 BitrateAllocator::ObserverAllocation BitrateAllocator::MaxRateAllocation( | |
219 uint32_t bitrate, uint32_t sum_max_bitrates) { | |
220 ObserverAllocation allocation; | |
221 | |
222 for (const auto& observer_config : bitrate_observer_configs_) { | |
223 allocation[observer_config.observer] = observer_config.max_bitrate_bps; | |
224 bitrate -= observer_config.max_bitrate_bps; | |
225 } | |
226 DistributeBitrateEvenly(bitrate, true, kTransmissionMaxBitrateMultiplier, | |
227 &allocation); | |
228 return allocation; | |
229 } | |
230 | |
231 uint32_t BitrateAllocator::LastAllocatedBitrate( | |
232 const ObserverConfig& observer_config) { | |
233 | |
234 const auto& it = last_allocation_.find(observer_config.observer); | |
235 if (it != last_allocation_.end()) | |
236 return it->second; | |
237 | |
238 // Return the configured minimum bitrate for newly added observers, to avoid | |
239 // requiring an extra high bitrate for the observer to get an allocated | |
240 // bitrate. | |
241 return observer_config.min_bitrate_bps; | |
242 } | |
243 | |
244 uint32_t BitrateAllocator::MinBitrateWithHysteresis( | |
245 const ObserverConfig& observer_config) { | |
246 uint32_t min_bitrate = observer_config.min_bitrate_bps; | |
247 if (LastAllocatedBitrate(observer_config) == 0) { | |
248 min_bitrate += std::max(static_cast<uint32_t>(kToggleFactor * min_bitrate), | |
249 kMinToggleBitrateBps); | |
250 } | |
251 return min_bitrate; | |
252 } | |
253 | |
254 void BitrateAllocator::DistributeBitrateEvenly(uint32_t bitrate, | |
255 bool include_zero_allocations, | |
256 int max_multiplier, | |
257 ObserverAllocation* allocation) { | |
258 RTC_DCHECK_EQ(allocation->size(), bitrate_observer_configs_.size()); | |
259 | |
260 ObserverSortingMap list_max_bitrates; | |
261 for (const auto& observer_config : bitrate_observer_configs_) { | |
262 if (include_zero_allocations || | |
263 allocation->at(observer_config.observer) != 0) { | |
264 list_max_bitrates.insert(std::pair<uint32_t, const ObserverConfig*>( | |
265 observer_config.max_bitrate_bps, &observer_config)); | |
266 } | |
267 } | |
268 auto it = list_max_bitrates.begin(); | |
269 while (it != list_max_bitrates.end()) { | |
270 RTC_DCHECK_GT(bitrate, 0u); | |
271 uint32_t extra_allocation = | |
272 bitrate / static_cast<uint32_t>(list_max_bitrates.size()); | |
273 uint32_t total_allocation = | |
274 extra_allocation + allocation->at(it->second->observer); | |
275 bitrate -= extra_allocation; | |
276 if (total_allocation > max_multiplier * it->first) { | |
277 // There is more than we can fit for this observer, carry over to the | |
278 // remaining observers. | |
279 bitrate += total_allocation - max_multiplier * it->first; | |
280 total_allocation = max_multiplier * it->first; | |
281 } | |
282 // Finally, update the allocation for this observer. | |
283 allocation->at(it->second->observer) = total_allocation; | |
284 it = list_max_bitrates.erase(it); | |
285 } | |
286 } | |
287 | |
288 bool BitrateAllocator::EnoughBitrateForAllObservers(uint32_t bitrate, | |
289 uint32_t sum_min_bitrates) { | |
290 if (bitrate < sum_min_bitrates) | |
291 return true; | |
292 | |
293 uint32_t extra_bitrate_per_observer = (bitrate - sum_min_bitrates) / | |
294 static_cast<uint32_t>(bitrate_observer_configs_.size()); | |
295 for (const auto& observer_config : bitrate_observer_configs_) { | |
296 if (observer_config.min_bitrate_bps + extra_bitrate_per_observer < | |
297 MinBitrateWithHysteresis(observer_config)) | |
298 return true; | |
299 } | |
300 return false; | |
301 } | |
207 } // namespace webrtc | 302 } // namespace webrtc |
OLD | NEW |