| 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/modules/bitrate_controller/include/bitrate_controller.h" |   17 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | 
|   18 #include "webrtc/rtc_base/checks.h" |   18 #include "webrtc/rtc_base/checks.h" | 
 |   19 #include "webrtc/rtc_base/helpers.h" | 
|   19 #include "webrtc/rtc_base/logging.h" |   20 #include "webrtc/rtc_base/logging.h" | 
|   20 #include "webrtc/system_wrappers/include/clock.h" |   21 #include "webrtc/system_wrappers/include/clock.h" | 
|   21 #include "webrtc/system_wrappers/include/metrics.h" |   22 #include "webrtc/system_wrappers/include/metrics.h" | 
|   22  |   23  | 
|   23 namespace webrtc { |   24 namespace webrtc { | 
|   24  |   25  | 
|   25 // Allow packets to be transmitted in up to 2 times max video bitrate if the |   26 // Allow packets to be transmitted in up to 2 times max video bitrate if the | 
|   26 // bandwidth estimate allows it. |   27 // bandwidth estimate allows it. | 
|   27 const int kTransmissionMaxBitrateMultiplier = 2; |   28 const int kTransmissionMaxBitrateMultiplier = 2; | 
|   28 const int kDefaultBitrateBps = 300000; |   29 const int kDefaultBitrateBps = 300000; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|   49     : limit_observer_(limit_observer), |   50     : limit_observer_(limit_observer), | 
|   50       bitrate_observer_configs_(), |   51       bitrate_observer_configs_(), | 
|   51       last_bitrate_bps_(0), |   52       last_bitrate_bps_(0), | 
|   52       last_non_zero_bitrate_bps_(kDefaultBitrateBps), |   53       last_non_zero_bitrate_bps_(kDefaultBitrateBps), | 
|   53       last_fraction_loss_(0), |   54       last_fraction_loss_(0), | 
|   54       last_rtt_(0), |   55       last_rtt_(0), | 
|   55       num_pause_events_(0), |   56       num_pause_events_(0), | 
|   56       clock_(Clock::GetRealTimeClock()), |   57       clock_(Clock::GetRealTimeClock()), | 
|   57       last_bwe_log_time_(0), |   58       last_bwe_log_time_(0), | 
|   58       total_requested_padding_bitrate_(0), |   59       total_requested_padding_bitrate_(0), | 
|   59       total_requested_min_bitrate_(0) { |   60       total_requested_min_bitrate_(0), | 
 |   61       bitrate_allocation_strategy_(nullptr) { | 
|   60   sequenced_checker_.Detach(); |   62   sequenced_checker_.Detach(); | 
|   61 } |   63 } | 
|   62  |   64  | 
|   63 BitrateAllocator::~BitrateAllocator() { |   65 BitrateAllocator::~BitrateAllocator() { | 
|   64   RTC_HISTOGRAM_COUNTS_100("WebRTC.Call.NumberOfPauseEvents", |   66   RTC_HISTOGRAM_COUNTS_100("WebRTC.Call.NumberOfPauseEvents", | 
|   65                            num_pause_events_); |   67                            num_pause_events_); | 
|   66 } |   68 } | 
|   67  |   69  | 
|   68 void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps, |   70 void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps, | 
|   69                                         uint8_t fraction_loss, |   71                                         uint8_t fraction_loss, | 
|   70                                         int64_t rtt, |   72                                         int64_t rtt, | 
|   71                                         int64_t bwe_period_ms) { |   73                                         int64_t bwe_period_ms) { | 
|   72   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |   74   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|   73   last_bitrate_bps_ = target_bitrate_bps; |   75   last_bitrate_bps_ = target_bitrate_bps; | 
|   74   last_non_zero_bitrate_bps_ = |   76   last_non_zero_bitrate_bps_ = | 
|   75       target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_; |   77       target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_; | 
|   76   last_fraction_loss_ = fraction_loss; |   78   last_fraction_loss_ = fraction_loss; | 
|   77   last_rtt_ = rtt; |   79   last_rtt_ = rtt; | 
|   78   last_bwe_period_ms_ = bwe_period_ms; |   80   last_bwe_period_ms_ = bwe_period_ms; | 
|   79  |   81  | 
|   80   // Periodically log the incoming BWE. |   82   // Periodically log the incoming BWE. | 
|   81   int64_t now = clock_->TimeInMilliseconds(); |   83   int64_t now = clock_->TimeInMilliseconds(); | 
|   82   if (now > last_bwe_log_time_ + kBweLogIntervalMs) { |   84   if (now > last_bwe_log_time_ + kBweLogIntervalMs) { | 
|   83     LOG(LS_INFO) << "Current BWE " << target_bitrate_bps; |   85     LOG(LS_INFO) << "Current BWE " << target_bitrate_bps; | 
|   84     last_bwe_log_time_ = now; |   86     last_bwe_log_time_ = now; | 
|   85   } |   87   } | 
|   86  |   88  | 
|   87   ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps); |   89   ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps); | 
|   88  |   90  | 
|   89   for (auto& config : bitrate_observer_configs_) { |   91   for (const auto& track_config : bitrate_observer_configs_) { | 
|   90     uint32_t allocated_bitrate = allocation[config.observer]; |   92     ObserverConfig* config = static_cast<ObserverConfig*>(track_config.get()); | 
|   91     uint32_t protection_bitrate = config.observer->OnBitrateUpdated( |   93     uint32_t allocated_bitrate = allocation[config->observer]; | 
|   92         allocated_bitrate, last_fraction_loss_, last_rtt_, |   94     uint32_t protection_bitrate = config->observer->OnBitrateUpdated( | 
|   93         last_bwe_period_ms_); |   95         allocated_bitrate, last_fraction_loss_, last_rtt_, last_bwe_period_ms_); | 
|   94  |   96  | 
|   95     if (allocated_bitrate == 0 && config.allocated_bitrate_bps > 0) { |   97     if (allocated_bitrate == 0 && config->allocated_bitrate_bps > 0) { | 
|   96       if (target_bitrate_bps > 0) |   98       if (target_bitrate_bps > 0) | 
|   97         ++num_pause_events_; |   99         ++num_pause_events_; | 
|   98       // The protection bitrate is an estimate based on the ratio between media |  100       // The protection bitrate is an estimate based on the ratio between media | 
|   99       // and protection used before this observer was muted. |  101       // and protection used before this observer was muted. | 
|  100       uint32_t predicted_protection_bps = |  102       uint32_t predicted_protection_bps = | 
|  101           (1.0 - config.media_ratio) * config.min_bitrate_bps; |  103           (1.0 - config->media_ratio) * config->min_bitrate_bps; | 
|  102       LOG(LS_INFO) << "Pausing observer " << config.observer |  104       LOG(LS_INFO) << "Pausing observer " << config->observer | 
|  103                    << " with configured min bitrate " << config.min_bitrate_bps |  105                    << " with configured min bitrate " << config->min_bitrate_bps | 
|  104                    << " and current estimate of " << target_bitrate_bps |  106                    << " and current estimate of " << target_bitrate_bps | 
|  105                    << " and protection bitrate " << predicted_protection_bps; |  107                    << " and protection bitrate " << predicted_protection_bps; | 
|  106     } else if (allocated_bitrate > 0 && config.allocated_bitrate_bps == 0) { |  108     } else if (allocated_bitrate > 0 && config->allocated_bitrate_bps == 0) { | 
|  107       if (target_bitrate_bps > 0) |  109       if (target_bitrate_bps > 0) | 
|  108         ++num_pause_events_; |  110         ++num_pause_events_; | 
|  109       LOG(LS_INFO) << "Resuming observer " << config.observer |  111       LOG(LS_INFO) << "Resuming observer " << config->observer | 
|  110                    << ", configured min bitrate " << config.min_bitrate_bps |  112                    << ", configured min bitrate " << config->min_bitrate_bps | 
|  111                    << ", current allocation " << allocated_bitrate |  113                    << ", current allocation " << allocated_bitrate | 
|  112                    << " and protection bitrate " << protection_bitrate; |  114                    << " and protection bitrate " << protection_bitrate; | 
|  113     } |  115     } | 
|  114  |  116  | 
|  115     // Only update the media ratio if the observer got an allocation. |  117     // Only update the media ratio if the observer got an allocation. | 
|  116     if (allocated_bitrate > 0) |  118     if (allocated_bitrate > 0) | 
|  117       config.media_ratio = MediaRatio(allocated_bitrate, protection_bitrate); |  119       config->media_ratio = MediaRatio(allocated_bitrate, protection_bitrate); | 
|  118     config.allocated_bitrate_bps = allocated_bitrate; |  120     config->allocated_bitrate_bps = allocated_bitrate; | 
|  119   } |  121   } | 
|  120   UpdateAllocationLimits(); |  122   UpdateAllocationLimits(); | 
|  121 } |  123 } | 
|  122  |  124  | 
|  123 void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, |  125 void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, | 
|  124                                    uint32_t min_bitrate_bps, |  126                                    uint32_t min_bitrate_bps, | 
|  125                                    uint32_t max_bitrate_bps, |  127                                    uint32_t max_bitrate_bps, | 
|  126                                    uint32_t pad_up_bitrate_bps, |  128                                    uint32_t pad_up_bitrate_bps, | 
|  127                                    bool enforce_min_bitrate, |  129                                    bool enforce_min_bitrate, | 
|  128                                    std::string track_id) { |  130                                    std::string track_id) { | 
|  129   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  131   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  130   auto it = FindObserverConfig(observer); |  132   auto it = FindObserverConfig(observer); | 
|  131  |  133  | 
 |  134   // Track IDs are used by custom allocation strategies. Track IDs may be either | 
 |  135   // empty or unique. Empty track IDs will be replaced with the random strings. | 
 |  136   // The strategy will not be able to handle track without ID specifically | 
 |  137   // but it will be able to handle it in some general way. For example a | 
 |  138   // strategy giving priotiry to audio streams will consider a stream | 
 |  139   // without an ID as a non-audio streams and will allocate bitrate for it | 
 |  140   // after required minimum allocated for audio. | 
 |  141   // Track IDs have ot be unique because strategy returns allocations mapped by | 
 |  142   // track ID (it is not aware of observers). | 
 |  143   std::string unique_track_id = track_id; | 
 |  144   if (unique_track_id.size() == 0) { | 
 |  145     unique_track_id = rtc::CreateRandomString(8); | 
 |  146     while (track_ids.count(unique_track_id)) { | 
 |  147       unique_track_id = rtc::CreateRandomString(8); | 
 |  148     } | 
 |  149   } | 
|  132   // Update settings if the observer already exists, create a new one otherwise. |  150   // Update settings if the observer already exists, create a new one otherwise. | 
|  133   if (it != bitrate_observer_configs_.end()) { |  151   if (it != bitrate_observer_configs_.end()) { | 
|  134     it->min_bitrate_bps = min_bitrate_bps; |  152     ObserverConfig* observer_config = static_cast<ObserverConfig*>(it->get()); | 
|  135     it->max_bitrate_bps = max_bitrate_bps; |  153     observer_config->min_bitrate_bps = min_bitrate_bps; | 
|  136     it->pad_up_bitrate_bps = pad_up_bitrate_bps; |  154     observer_config->max_bitrate_bps = max_bitrate_bps; | 
|  137     it->enforce_min_bitrate = enforce_min_bitrate; |  155     observer_config->pad_up_bitrate_bps = pad_up_bitrate_bps; | 
 |  156     observer_config->enforce_min_bitrate = enforce_min_bitrate; | 
 |  157     RTC_DCHECK(track_ids.count(unique_track_id) == 0 || | 
 |  158                observer_config->track_id == unique_track_id); | 
 |  159     observer_config->track_id = unique_track_id; | 
|  138   } else { |  160   } else { | 
|  139     bitrate_observer_configs_.push_back( |  161     RTC_DCHECK(track_ids.count(unique_track_id) == 0); | 
|  140         ObserverConfig(observer, min_bitrate_bps, max_bitrate_bps, |  162     bitrate_observer_configs_.emplace_back(new ObserverConfig( | 
|  141                        pad_up_bitrate_bps, enforce_min_bitrate, track_id)); |  163         observer, min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps, | 
 |  164         enforce_min_bitrate, unique_track_id)); | 
|  142   } |  165   } | 
 |  166   track_ids.insert(unique_track_id); | 
|  143  |  167  | 
|  144   ObserverAllocation allocation; |  168   ObserverAllocation allocation; | 
|  145   if (last_bitrate_bps_ > 0) { |  169   if (last_bitrate_bps_ > 0) { | 
|  146     // Calculate a new allocation and update all observers. |  170     // Calculate a new allocation and update all observers. | 
|  147     allocation = AllocateBitrates(last_bitrate_bps_); |  171     allocation = AllocateBitrates(last_bitrate_bps_); | 
|  148     for (auto& config : bitrate_observer_configs_) { |  172     for (auto& track_config : bitrate_observer_configs_) { | 
|  149       uint32_t allocated_bitrate = allocation[config.observer]; |  173       ObserverConfig* config = static_cast<ObserverConfig*>(track_config.get()); | 
|  150       uint32_t protection_bitrate = config.observer->OnBitrateUpdated( |  174       uint32_t allocated_bitrate = allocation[config->observer]; | 
 |  175       uint32_t protection_bitrate = config->observer->OnBitrateUpdated( | 
|  151           allocated_bitrate, last_fraction_loss_, last_rtt_, |  176           allocated_bitrate, last_fraction_loss_, last_rtt_, | 
|  152           last_bwe_period_ms_); |  177           last_bwe_period_ms_); | 
|  153       config.allocated_bitrate_bps = allocated_bitrate; |  178       config->allocated_bitrate_bps = allocated_bitrate; | 
|  154       if (allocated_bitrate > 0) |  179       if (allocated_bitrate > 0) | 
|  155         config.media_ratio = MediaRatio(allocated_bitrate, protection_bitrate); |  180         config->media_ratio = MediaRatio(allocated_bitrate, protection_bitrate); | 
|  156     } |  181     } | 
|  157   } else { |  182   } else { | 
|  158     // Currently, an encoder is not allowed to produce frames. |  183     // Currently, an encoder is not allowed to produce frames. | 
|  159     // But we still have to return the initial config bitrate + let the |  184     // But we still have to return the initial config bitrate + let the | 
|  160     // observer know that it can not produce frames. |  185     // observer know that it can not produce frames. | 
|  161     allocation = AllocateBitrates(last_non_zero_bitrate_bps_); |  186     allocation = AllocateBitrates(last_non_zero_bitrate_bps_); | 
|  162     observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_, |  187     observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_, | 
|  163                                last_bwe_period_ms_); |  188                                last_bwe_period_ms_); | 
|  164   } |  189   } | 
|  165   UpdateAllocationLimits(); |  190   UpdateAllocationLimits(); | 
|  166 } |  191 } | 
|  167  |  192  | 
|  168 void BitrateAllocator::UpdateAllocationLimits() { |  193 void BitrateAllocator::UpdateAllocationLimits() { | 
|  169   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  194   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  170   uint32_t total_requested_padding_bitrate = 0; |  195   uint32_t total_requested_padding_bitrate = 0; | 
|  171   uint32_t total_requested_min_bitrate = 0; |  196   uint32_t total_requested_min_bitrate = 0; | 
|  172  |  197  | 
|  173   for (const auto& config : bitrate_observer_configs_) { |  198   for (const auto& track_config : bitrate_observer_configs_) { | 
|  174     uint32_t stream_padding = config.pad_up_bitrate_bps; |  199     ObserverConfig* config = static_cast<ObserverConfig*>(track_config.get()); | 
|  175     if (config.enforce_min_bitrate) { |  200     uint32_t stream_padding = config->pad_up_bitrate_bps; | 
|  176       total_requested_min_bitrate += config.min_bitrate_bps; |  201     if (config->enforce_min_bitrate) { | 
|  177     } else if (config.allocated_bitrate_bps == 0) { |  202       total_requested_min_bitrate += config->min_bitrate_bps; | 
 |  203     } else if (config->allocated_bitrate_bps == 0) { | 
|  178       stream_padding = |  204       stream_padding = | 
|  179           std::max(MinBitrateWithHysteresis(config), stream_padding); |  205           std::max(MinBitrateWithHysteresis(*config), stream_padding); | 
|  180     } |  206     } | 
|  181     total_requested_padding_bitrate += stream_padding; |  207     total_requested_padding_bitrate += stream_padding; | 
|  182   } |  208   } | 
|  183  |  209  | 
|  184   if (total_requested_padding_bitrate == total_requested_padding_bitrate_ && |  210   if (total_requested_padding_bitrate == total_requested_padding_bitrate_ && | 
|  185       total_requested_min_bitrate == total_requested_min_bitrate_) { |  211       total_requested_min_bitrate == total_requested_min_bitrate_) { | 
|  186     return; |  212     return; | 
|  187   } |  213   } | 
|  188  |  214  | 
|  189   total_requested_min_bitrate_ = total_requested_min_bitrate; |  215   total_requested_min_bitrate_ = total_requested_min_bitrate; | 
|  190   total_requested_padding_bitrate_ = total_requested_padding_bitrate; |  216   total_requested_padding_bitrate_ = total_requested_padding_bitrate; | 
|  191  |  217  | 
|  192   LOG(LS_INFO) << "UpdateAllocationLimits : total_requested_min_bitrate: " |  218   LOG(LS_INFO) << "UpdateAllocationLimits : total_requested_min_bitrate: " | 
|  193                << total_requested_min_bitrate |  219                << total_requested_min_bitrate | 
|  194                << "bps, total_requested_padding_bitrate: " |  220                << "bps, total_requested_padding_bitrate: " | 
|  195                << total_requested_padding_bitrate << "bps"; |  221                << total_requested_padding_bitrate << "bps"; | 
|  196   limit_observer_->OnAllocationLimitsChanged(total_requested_min_bitrate, |  222   limit_observer_->OnAllocationLimitsChanged(total_requested_min_bitrate, | 
|  197                                              total_requested_padding_bitrate); |  223                                              total_requested_padding_bitrate); | 
|  198 } |  224 } | 
|  199  |  225  | 
|  200 void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { |  226 void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) { | 
|  201   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  227   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  202   auto it = FindObserverConfig(observer); |  228   auto it = FindObserverConfig(observer); | 
|  203   if (it != bitrate_observer_configs_.end()) { |  229   if (it != bitrate_observer_configs_.end()) { | 
 |  230     track_ids.erase((*it)->track_id); | 
|  204     bitrate_observer_configs_.erase(it); |  231     bitrate_observer_configs_.erase(it); | 
|  205   } |  232   } | 
|  206  |  233  | 
|  207   UpdateAllocationLimits(); |  234   UpdateAllocationLimits(); | 
|  208 } |  235 } | 
|  209  |  236  | 
|  210 int BitrateAllocator::GetStartBitrate(BitrateAllocatorObserver* observer) { |  237 int BitrateAllocator::GetStartBitrate(BitrateAllocatorObserver* observer) { | 
|  211   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  238   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  212   const auto& it = FindObserverConfig(observer); |  239   const auto& it = FindObserverConfig(observer); | 
 |  240   ObserverConfig* config = static_cast<ObserverConfig*>(it->get()); | 
|  213   if (it == bitrate_observer_configs_.end()) { |  241   if (it == bitrate_observer_configs_.end()) { | 
|  214     // This observer hasn't been added yet, just give it its fair share. |  242     // This observer hasn't been added yet, just give it its fair share. | 
|  215     return last_non_zero_bitrate_bps_ / |  243     return last_non_zero_bitrate_bps_ / | 
|  216            static_cast<int>((bitrate_observer_configs_.size() + 1)); |  244            static_cast<int>((bitrate_observer_configs_.size() + 1)); | 
|  217   } else if (it->allocated_bitrate_bps == -1) { |  245   } else if (config->allocated_bitrate_bps == -1) { | 
|  218     // This observer hasn't received an allocation yet, so do the same. |  246     // This observer hasn't received an allocation yet, so do the same. | 
|  219     return last_non_zero_bitrate_bps_ / |  247     return last_non_zero_bitrate_bps_ / | 
|  220            static_cast<int>(bitrate_observer_configs_.size()); |  248            static_cast<int>(bitrate_observer_configs_.size()); | 
|  221   } else { |  249   } else { | 
|  222     // This observer already has an allocation. |  250     // This observer already has an allocation. | 
|  223     return it->allocated_bitrate_bps; |  251     return config->allocated_bitrate_bps; | 
|  224   } |  252   } | 
|  225 } |  253 } | 
|  226  |  254  | 
|  227 BitrateAllocator::ObserverConfigs::iterator |  255 void BitrateAllocator::SetBitrateAllocationStrategy( | 
 |  256     rtc::scoped_refptr<rtc::BitrateAllocationStrategy> | 
 |  257         bitrate_allocation_strategy) { | 
 |  258   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
 |  259   bitrate_allocation_strategy_ = bitrate_allocation_strategy; | 
 |  260 } | 
 |  261  | 
 |  262 rtc::BitrateAllocationStrategy::TrackConfigs::iterator | 
|  228 BitrateAllocator::FindObserverConfig(const BitrateAllocatorObserver* observer) { |  263 BitrateAllocator::FindObserverConfig(const BitrateAllocatorObserver* observer) { | 
|  229   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  264   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  230   for (auto it = bitrate_observer_configs_.begin(); |  265   for (auto it = bitrate_observer_configs_.begin(); | 
|  231        it != bitrate_observer_configs_.end(); ++it) { |  266        it != bitrate_observer_configs_.end(); ++it) { | 
|  232     if (it->observer == observer) |  267     ObserverConfig* config = static_cast<ObserverConfig*>(it->get()); | 
 |  268     if (config->observer == observer) | 
|  233       return it; |  269       return it; | 
|  234   } |  270   } | 
|  235   return bitrate_observer_configs_.end(); |  271   return bitrate_observer_configs_.end(); | 
|  236 } |  272 } | 
|  237  |  273  | 
|  238 BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates( |  274 BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates( | 
|  239     uint32_t bitrate) { |  275     uint32_t bitrate) { | 
|  240   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  276   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  241   if (bitrate_observer_configs_.empty()) |  277   if (bitrate_observer_configs_.empty()) | 
|  242     return ObserverAllocation(); |  278     return ObserverAllocation(); | 
|  243  |  279  | 
 |  280   if (bitrate_allocation_strategy_ != nullptr) { | 
 |  281     rtc::BitrateAllocationStrategy::TrackAllocations track_allocations = | 
 |  282         bitrate_allocation_strategy_->AllocateBitrates( | 
 |  283             bitrate, bitrate_observer_configs_); | 
 |  284     ObserverAllocation allocation; | 
 |  285     for (const auto& track_config : bitrate_observer_configs_) { | 
 |  286       ObserverConfig* observer_config = | 
 |  287           static_cast<ObserverConfig*>(track_config.get()); | 
 |  288       // The strategy should return allocation for all tracks. | 
 |  289       // In release builds still may be better to use zero allocation | 
 |  290       // rathen than crash | 
 |  291       RTC_DCHECK(track_allocations.find(observer_config->track_id) != | 
 |  292                  track_allocations.end()); | 
 |  293       allocation[observer_config->observer] = | 
 |  294           track_allocations[observer_config->track_id]; | 
 |  295     } | 
 |  296     return allocation; | 
 |  297   } | 
 |  298  | 
|  244   if (bitrate == 0) |  299   if (bitrate == 0) | 
|  245     return ZeroRateAllocation(); |  300     return ZeroRateAllocation(); | 
|  246  |  301  | 
|  247   uint32_t sum_min_bitrates = 0; |  302   uint32_t sum_min_bitrates = 0; | 
|  248   uint32_t sum_max_bitrates = 0; |  303   uint32_t sum_max_bitrates = 0; | 
|  249   for (const auto& observer_config : bitrate_observer_configs_) { |  304   for (const auto& observer_config : bitrate_observer_configs_) { | 
|  250     sum_min_bitrates += observer_config.min_bitrate_bps; |  305     sum_min_bitrates += observer_config->min_bitrate_bps; | 
|  251     sum_max_bitrates += observer_config.max_bitrate_bps; |  306     sum_max_bitrates += observer_config->max_bitrate_bps; | 
|  252   } |  307   } | 
|  253  |  308  | 
|  254   // Not enough for all observers to get an allocation, allocate according to: |  309   // Not enough for all observers to get an allocation, allocate according to: | 
|  255   // enforced min bitrate -> allocated bitrate previous round -> restart paused |  310   // enforced min bitrate -> allocated bitrate previous round -> restart paused | 
|  256   // streams. |  311   // streams. | 
|  257   if (!EnoughBitrateForAllObservers(bitrate, sum_min_bitrates)) |  312   if (!EnoughBitrateForAllObservers(bitrate, sum_min_bitrates)) | 
|  258     return LowRateAllocation(bitrate); |  313     return LowRateAllocation(bitrate); | 
|  259  |  314  | 
|  260   // All observers will get their min bitrate plus an even share of the rest. |  315   // All observers will get their min bitrate plus an even share of the rest. | 
|  261   if (bitrate <= sum_max_bitrates) |  316   if (bitrate <= sum_max_bitrates) | 
|  262     return NormalRateAllocation(bitrate, sum_min_bitrates); |  317     return NormalRateAllocation(bitrate, sum_min_bitrates); | 
|  263  |  318  | 
|  264   // All observers will get up to kTransmissionMaxBitrateMultiplier x max. |  319   // All observers will get up to kTransmissionMaxBitrateMultiplier x max. | 
|  265   return MaxRateAllocation(bitrate, sum_max_bitrates); |  320   return MaxRateAllocation(bitrate, sum_max_bitrates); | 
|  266 } |  321 } | 
|  267  |  322  | 
|  268 BitrateAllocator::ObserverAllocation BitrateAllocator::ZeroRateAllocation() { |  323 BitrateAllocator::ObserverAllocation BitrateAllocator::ZeroRateAllocation() { | 
|  269   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  324   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  270   ObserverAllocation allocation; |  325   ObserverAllocation allocation; | 
|  271   for (const auto& observer_config : bitrate_observer_configs_) |  326   for (const auto& track_config : bitrate_observer_configs_) { | 
|  272     allocation[observer_config.observer] = 0; |  327     ObserverConfig* observer_config = | 
 |  328         static_cast<ObserverConfig*>(track_config.get()); | 
 |  329     allocation[observer_config->observer] = 0; | 
 |  330   } | 
|  273   return allocation; |  331   return allocation; | 
|  274 } |  332 } | 
|  275  |  333  | 
|  276 BitrateAllocator::ObserverAllocation BitrateAllocator::LowRateAllocation( |  334 BitrateAllocator::ObserverAllocation BitrateAllocator::LowRateAllocation( | 
|  277     uint32_t bitrate) { |  335     uint32_t bitrate) { | 
|  278   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  336   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  279   ObserverAllocation allocation; |  337   ObserverAllocation allocation; | 
|  280   // Start by allocating bitrate to observers enforcing a min bitrate, hence |  338   // Start by allocating bitrate to observers enforcing a min bitrate, hence | 
|  281   // remaining_bitrate might turn negative. |  339   // remaining_bitrate might turn negative. | 
|  282   int64_t remaining_bitrate = bitrate; |  340   int64_t remaining_bitrate = bitrate; | 
|  283   for (const auto& observer_config : bitrate_observer_configs_) { |  341   for (const auto& track_config : bitrate_observer_configs_) { | 
 |  342     ObserverConfig* observer_config = | 
 |  343         static_cast<ObserverConfig*>(track_config.get()); | 
|  284     int32_t allocated_bitrate = 0; |  344     int32_t allocated_bitrate = 0; | 
|  285     if (observer_config.enforce_min_bitrate) |  345     if (observer_config->enforce_min_bitrate) | 
|  286       allocated_bitrate = observer_config.min_bitrate_bps; |  346       allocated_bitrate = observer_config->min_bitrate_bps; | 
|  287  |  347  | 
|  288     allocation[observer_config.observer] = allocated_bitrate; |  348     allocation[observer_config->observer] = allocated_bitrate; | 
|  289     remaining_bitrate -= allocated_bitrate; |  349     remaining_bitrate -= allocated_bitrate; | 
|  290   } |  350   } | 
|  291  |  351  | 
|  292   // Allocate bitrate to all previously active streams. |  352   // Allocate bitrate to all previously active streams. | 
|  293   if (remaining_bitrate > 0) { |  353   if (remaining_bitrate > 0) { | 
|  294     for (const auto& observer_config : bitrate_observer_configs_) { |  354     for (const auto& track_config : bitrate_observer_configs_) { | 
|  295       if (observer_config.enforce_min_bitrate || |  355       ObserverConfig* observer_config = | 
|  296           LastAllocatedBitrate(observer_config) == 0) |  356           static_cast<ObserverConfig*>(track_config.get()); | 
 |  357       if (observer_config->enforce_min_bitrate || | 
 |  358           LastAllocatedBitrate(*observer_config) == 0) | 
|  297         continue; |  359         continue; | 
|  298  |  360  | 
|  299       uint32_t required_bitrate = MinBitrateWithHysteresis(observer_config); |  361       uint32_t required_bitrate = MinBitrateWithHysteresis(*observer_config); | 
|  300       if (remaining_bitrate >= required_bitrate) { |  362       if (remaining_bitrate >= required_bitrate) { | 
|  301         allocation[observer_config.observer] = required_bitrate; |  363         allocation[observer_config->observer] = required_bitrate; | 
|  302         remaining_bitrate -= required_bitrate; |  364         remaining_bitrate -= required_bitrate; | 
|  303       } |  365       } | 
|  304     } |  366     } | 
|  305   } |  367   } | 
|  306  |  368  | 
|  307   // Allocate bitrate to previously paused streams. |  369   // Allocate bitrate to previously paused streams. | 
|  308   if (remaining_bitrate > 0) { |  370   if (remaining_bitrate > 0) { | 
|  309     for (const auto& observer_config : bitrate_observer_configs_) { |  371     for (const auto& track_config : bitrate_observer_configs_) { | 
|  310       if (LastAllocatedBitrate(observer_config) != 0) |  372       ObserverConfig* observer_config = | 
 |  373           static_cast<ObserverConfig*>(track_config.get()); | 
 |  374       if (LastAllocatedBitrate(*observer_config) != 0) | 
|  311         continue; |  375         continue; | 
|  312  |  376  | 
|  313       // Add a hysteresis to avoid toggling. |  377       // Add a hysteresis to avoid toggling. | 
|  314       uint32_t required_bitrate = MinBitrateWithHysteresis(observer_config); |  378       uint32_t required_bitrate = MinBitrateWithHysteresis(*observer_config); | 
|  315       if (remaining_bitrate >= required_bitrate) { |  379       if (remaining_bitrate >= required_bitrate) { | 
|  316         allocation[observer_config.observer] = required_bitrate; |  380         allocation[observer_config->observer] = required_bitrate; | 
|  317         remaining_bitrate -= required_bitrate; |  381         remaining_bitrate -= required_bitrate; | 
|  318       } |  382       } | 
|  319     } |  383     } | 
|  320   } |  384   } | 
|  321  |  385  | 
|  322   // Split a possible remainder evenly on all streams with an allocation. |  386   // Split a possible remainder evenly on all streams with an allocation. | 
|  323   if (remaining_bitrate > 0) |  387   if (remaining_bitrate > 0) | 
|  324     DistributeBitrateEvenly(remaining_bitrate, false, 1, &allocation); |  388     DistributeBitrateEvenly(remaining_bitrate, false, 1, &allocation); | 
|  325  |  389  | 
|  326   RTC_DCHECK_EQ(allocation.size(), bitrate_observer_configs_.size()); |  390   RTC_DCHECK_EQ(allocation.size(), bitrate_observer_configs_.size()); | 
|  327   return allocation; |  391   return allocation; | 
|  328 } |  392 } | 
|  329  |  393  | 
|  330 BitrateAllocator::ObserverAllocation BitrateAllocator::NormalRateAllocation( |  394 BitrateAllocator::ObserverAllocation BitrateAllocator::NormalRateAllocation( | 
|  331     uint32_t bitrate, |  395     uint32_t bitrate, | 
|  332     uint32_t sum_min_bitrates) { |  396     uint32_t sum_min_bitrates) { | 
|  333   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  397   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  334   ObserverAllocation allocation; |  398   ObserverAllocation allocation; | 
|  335   for (const auto& observer_config : bitrate_observer_configs_) |  399   for (const auto& track_config : bitrate_observer_configs_) { | 
|  336     allocation[observer_config.observer] = observer_config.min_bitrate_bps; |  400     ObserverConfig* observer_config = | 
 |  401         static_cast<ObserverConfig*>(track_config.get()); | 
 |  402     allocation[observer_config->observer] = observer_config->min_bitrate_bps; | 
 |  403   } | 
|  337  |  404  | 
|  338   bitrate -= sum_min_bitrates; |  405   bitrate -= sum_min_bitrates; | 
|  339   if (bitrate > 0) |  406   if (bitrate > 0) | 
|  340     DistributeBitrateEvenly(bitrate, true, 1, &allocation); |  407     DistributeBitrateEvenly(bitrate, true, 1, &allocation); | 
|  341  |  408  | 
|  342   return allocation; |  409   return allocation; | 
|  343 } |  410 } | 
|  344  |  411  | 
|  345 BitrateAllocator::ObserverAllocation BitrateAllocator::MaxRateAllocation( |  412 BitrateAllocator::ObserverAllocation BitrateAllocator::MaxRateAllocation( | 
|  346     uint32_t bitrate, |  413     uint32_t bitrate, | 
|  347     uint32_t sum_max_bitrates) { |  414     uint32_t sum_max_bitrates) { | 
|  348   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  415   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  349   ObserverAllocation allocation; |  416   ObserverAllocation allocation; | 
|  350  |  417  | 
|  351   for (const auto& observer_config : bitrate_observer_configs_) { |  418   for (const auto& track_config : bitrate_observer_configs_) { | 
|  352     allocation[observer_config.observer] = observer_config.max_bitrate_bps; |  419     ObserverConfig* observer_config = | 
|  353     bitrate -= observer_config.max_bitrate_bps; |  420         static_cast<ObserverConfig*>(track_config.get()); | 
 |  421     allocation[observer_config->observer] = observer_config->max_bitrate_bps; | 
 |  422     bitrate -= observer_config->max_bitrate_bps; | 
|  354   } |  423   } | 
|  355   DistributeBitrateEvenly(bitrate, true, kTransmissionMaxBitrateMultiplier, |  424   DistributeBitrateEvenly(bitrate, true, kTransmissionMaxBitrateMultiplier, | 
|  356                           &allocation); |  425                           &allocation); | 
|  357   return allocation; |  426   return allocation; | 
|  358 } |  427 } | 
|  359  |  428  | 
|  360 uint32_t BitrateAllocator::LastAllocatedBitrate( |  429 uint32_t BitrateAllocator::LastAllocatedBitrate( | 
|  361     const ObserverConfig& observer_config) { |  430     const ObserverConfig& observer_config) { | 
|  362   // Return the configured minimum bitrate for newly added observers, to avoid |  431   // Return the configured minimum bitrate for newly added observers, to avoid | 
|  363   // requiring an extra high bitrate for the observer to get an allocated |  432   // requiring an extra high bitrate for the observer to get an allocated | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  387 } |  456 } | 
|  388  |  457  | 
|  389 void BitrateAllocator::DistributeBitrateEvenly(uint32_t bitrate, |  458 void BitrateAllocator::DistributeBitrateEvenly(uint32_t bitrate, | 
|  390                                                bool include_zero_allocations, |  459                                                bool include_zero_allocations, | 
|  391                                                int max_multiplier, |  460                                                int max_multiplier, | 
|  392                                                ObserverAllocation* allocation) { |  461                                                ObserverAllocation* allocation) { | 
|  393   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  462   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  394   RTC_DCHECK_EQ(allocation->size(), bitrate_observer_configs_.size()); |  463   RTC_DCHECK_EQ(allocation->size(), bitrate_observer_configs_.size()); | 
|  395  |  464  | 
|  396   ObserverSortingMap list_max_bitrates; |  465   ObserverSortingMap list_max_bitrates; | 
|  397   for (const auto& observer_config : bitrate_observer_configs_) { |  466   for (const auto& track_config : bitrate_observer_configs_) { | 
 |  467     ObserverConfig* observer_config = | 
 |  468         static_cast<ObserverConfig*>(track_config.get()); | 
|  398     if (include_zero_allocations || |  469     if (include_zero_allocations || | 
|  399         allocation->at(observer_config.observer) != 0) { |  470         allocation->at(observer_config->observer) != 0) { | 
|  400       list_max_bitrates.insert(std::pair<uint32_t, const ObserverConfig*>( |  471       list_max_bitrates.insert(std::pair<uint32_t, ObserverConfig*>( | 
|  401           observer_config.max_bitrate_bps, &observer_config)); |  472           observer_config->max_bitrate_bps, observer_config)); | 
|  402     } |  473     } | 
|  403   } |  474   } | 
|  404   auto it = list_max_bitrates.begin(); |  475   auto it = list_max_bitrates.begin(); | 
|  405   while (it != list_max_bitrates.end()) { |  476   while (it != list_max_bitrates.end()) { | 
|  406     RTC_DCHECK_GT(bitrate, 0); |  477     RTC_DCHECK_GT(bitrate, 0); | 
|  407     uint32_t extra_allocation = |  478     uint32_t extra_allocation = | 
|  408         bitrate / static_cast<uint32_t>(list_max_bitrates.size()); |  479         bitrate / static_cast<uint32_t>(list_max_bitrates.size()); | 
|  409     uint32_t total_allocation = |  480     uint32_t total_allocation = | 
|  410         extra_allocation + allocation->at(it->second->observer); |  481         extra_allocation + allocation->at(it->second->observer); | 
|  411     bitrate -= extra_allocation; |  482     bitrate -= extra_allocation; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  423  |  494  | 
|  424 bool BitrateAllocator::EnoughBitrateForAllObservers(uint32_t bitrate, |  495 bool BitrateAllocator::EnoughBitrateForAllObservers(uint32_t bitrate, | 
|  425                                                     uint32_t sum_min_bitrates) { |  496                                                     uint32_t sum_min_bitrates) { | 
|  426   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); |  497   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_); | 
|  427   if (bitrate < sum_min_bitrates) |  498   if (bitrate < sum_min_bitrates) | 
|  428     return false; |  499     return false; | 
|  429  |  500  | 
|  430   uint32_t extra_bitrate_per_observer = |  501   uint32_t extra_bitrate_per_observer = | 
|  431       (bitrate - sum_min_bitrates) / |  502       (bitrate - sum_min_bitrates) / | 
|  432       static_cast<uint32_t>(bitrate_observer_configs_.size()); |  503       static_cast<uint32_t>(bitrate_observer_configs_.size()); | 
|  433   for (const auto& observer_config : bitrate_observer_configs_) { |  504   for (const auto& track_config : bitrate_observer_configs_) { | 
|  434     if (observer_config.min_bitrate_bps + extra_bitrate_per_observer < |  505     ObserverConfig* observer_config = | 
|  435         MinBitrateWithHysteresis(observer_config)) { |  506         static_cast<ObserverConfig*>(track_config.get()); | 
 |  507     if (observer_config->min_bitrate_bps + extra_bitrate_per_observer < | 
 |  508         MinBitrateWithHysteresis(*observer_config)) { | 
|  436       return false; |  509       return false; | 
|  437     } |  510     } | 
|  438   } |  511   } | 
|  439   return true; |  512   return true; | 
|  440 } |  513 } | 
|  441 }  // namespace webrtc |  514 }  // namespace webrtc | 
| OLD | NEW |