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 |