| 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/base/logging.h" | 
|   18 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" |   19 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | 
 |   20 #include "webrtc/system_wrappers/include/clock.h" | 
 |   21 #include "webrtc/system_wrappers/include/metrics.h" | 
|   19  |   22  | 
|   20 namespace webrtc { |   23 namespace webrtc { | 
|   21  |   24  | 
|   22 // Allow packets to be transmitted in up to 2 times max video bitrate if the |   25 // Allow packets to be transmitted in up to 2 times max video bitrate if the | 
|   23 // bandwidth estimate allows it. |   26 // bandwidth estimate allows it. | 
|   24 const int kTransmissionMaxBitrateMultiplier = 2; |   27 const int kTransmissionMaxBitrateMultiplier = 2; | 
|   25 const int kDefaultBitrateBps = 300000; |   28 const int kDefaultBitrateBps = 300000; | 
|   26  |   29  | 
|   27 // Require a bitrate increase of max(10%, 20kbps) to resume paused streams. |   30 // Require a bitrate increase of max(10%, 20kbps) to resume paused streams. | 
|   28 const double kToggleFactor = 0.1; |   31 const double kToggleFactor = 0.1; | 
|   29 const uint32_t kMinToggleBitrateBps = 20000; |   32 const uint32_t kMinToggleBitrateBps = 20000; | 
|   30  |   33  | 
 |   34 const int64_t kBweLogIntervalMs = 5000; | 
 |   35  | 
 |   36 namespace { | 
 |   37  | 
 |   38 double MediaRatio(uint32_t allocated_bitrate, uint32_t protection_bitrate) { | 
 |   39   RTC_DCHECK_GT(allocated_bitrate, 0u); | 
 |   40   if (protection_bitrate == 0) | 
 |   41     return 1.0; | 
 |   42  | 
 |   43   uint32_t media_bitrate = allocated_bitrate - protection_bitrate; | 
 |   44   return media_bitrate / static_cast<double>(allocated_bitrate); | 
 |   45 } | 
 |   46 }  // namespace | 
 |   47  | 
|   31 BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer) |   48 BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer) | 
|   32     : limit_observer_(limit_observer), |   49     : limit_observer_(limit_observer), | 
|   33       bitrate_observer_configs_(), |   50       bitrate_observer_configs_(), | 
|   34       last_bitrate_bps_(kDefaultBitrateBps), |   51       last_bitrate_bps_(kDefaultBitrateBps), | 
|   35       last_non_zero_bitrate_bps_(kDefaultBitrateBps), |   52       last_non_zero_bitrate_bps_(kDefaultBitrateBps), | 
|   36       last_fraction_loss_(0), |   53       last_fraction_loss_(0), | 
|   37       last_rtt_(0) {} |   54       last_rtt_(0), | 
 |   55       num_pause_events_(0), | 
 |   56       clock_(Clock::GetRealTimeClock()), | 
 |   57       last_bwe_log_time_(0) {} | 
 |   58  | 
 |   59 BitrateAllocator::~BitrateAllocator() { | 
 |   60   RTC_LOGGED_HISTOGRAM_COUNTS_100("WebRTC.Call.NumberOfPauseEvents", | 
 |   61                                   num_pause_events_); | 
 |   62 } | 
|   38  |   63  | 
|   39 void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps, |   64 void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps, | 
|   40                                         uint8_t fraction_loss, |   65                                         uint8_t fraction_loss, | 
|   41                                         int64_t rtt) { |   66                                         int64_t rtt) { | 
|   42   rtc::CritScope lock(&crit_sect_); |   67   rtc::CritScope lock(&crit_sect_); | 
|   43   last_bitrate_bps_ = target_bitrate_bps; |   68   last_bitrate_bps_ = target_bitrate_bps; | 
|   44   last_non_zero_bitrate_bps_ = |   69   last_non_zero_bitrate_bps_ = | 
|   45       target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_; |   70       target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_; | 
|   46   last_fraction_loss_ = fraction_loss; |   71   last_fraction_loss_ = fraction_loss; | 
|   47   last_rtt_ = rtt; |   72   last_rtt_ = rtt; | 
|   48  |   73  | 
 |   74   // Periodically log the incoming BWE. | 
 |   75   int64_t now = clock_->TimeInMilliseconds(); | 
 |   76   if (now > last_bwe_log_time_ + kBweLogIntervalMs) { | 
 |   77     LOG(LS_INFO) << "Current BWE " << target_bitrate_bps; | 
 |   78     last_bwe_log_time_ = now; | 
 |   79   } | 
 |   80  | 
|   49   ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps); |   81   ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps); | 
|   50   for (const auto& kv : allocation) { |   82  | 
|   51     kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |   83   for (auto& config : bitrate_observer_configs_) { | 
 |   84     uint32_t allocated_bitrate = allocation[config.observer]; | 
 |   85     uint32_t protection_bitrate = config.observer->OnBitrateUpdated( | 
 |   86         allocated_bitrate, last_fraction_loss_, last_rtt_); | 
 |   87  | 
 |   88     if (allocated_bitrate == 0 && config.allocated_bitrate_bps > 0) { | 
 |   89       if (target_bitrate_bps > 0) | 
 |   90         ++num_pause_events_; | 
 |   91       // The protection bitrate is an estimate based on the ratio between media | 
 |   92       // and protection used before this observer was muted. | 
 |   93       uint32_t predicted_protection_bps = | 
 |   94           (1.0 - config.media_ratio) * config.min_bitrate_bps; | 
 |   95       LOG(LS_INFO) << "Pausing observer " << config.observer | 
 |   96                    << " with configured min bitrate " << config.min_bitrate_bps | 
 |   97                    << " and current estimate of " << target_bitrate_bps | 
 |   98                    << " and protection bitrate " << predicted_protection_bps; | 
 |   99     } else if (allocated_bitrate > 0 && config.allocated_bitrate_bps == 0) { | 
 |  100       if (target_bitrate_bps > 0) | 
 |  101         ++num_pause_events_; | 
 |  102       LOG(LS_INFO) << "Resuming observer " << config.observer | 
 |  103                    << ", configured min bitrate " << config.min_bitrate_bps | 
 |  104                    << ", current allocation " << allocated_bitrate | 
 |  105                    << " and protection bitrate " << protection_bitrate; | 
 |  106     } | 
 |  107  | 
 |  108     // Only update the media ratio if the observer got an allocation. | 
 |  109     if (allocated_bitrate > 0) | 
 |  110       config.media_ratio = MediaRatio(allocated_bitrate, protection_bitrate); | 
 |  111     config.allocated_bitrate_bps = allocated_bitrate; | 
|   52   } |  112   } | 
|   53   last_allocation_ = allocation; |  | 
|   54 } |  113 } | 
|   55  |  114  | 
|   56 void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, |  115 void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer, | 
|   57                                    uint32_t min_bitrate_bps, |  116                                    uint32_t min_bitrate_bps, | 
|   58                                    uint32_t max_bitrate_bps, |  117                                    uint32_t max_bitrate_bps, | 
|   59                                    uint32_t pad_up_bitrate_bps, |  118                                    uint32_t pad_up_bitrate_bps, | 
|   60                                    bool enforce_min_bitrate) { |  119                                    bool enforce_min_bitrate) { | 
|   61   rtc::CritScope lock(&crit_sect_); |  120   rtc::CritScope lock(&crit_sect_); | 
|   62   auto it = FindObserverConfig(observer); |  121   auto it = FindObserverConfig(observer); | 
|   63  |  122  | 
|   64   // Update settings if the observer already exists, create a new one otherwise. |  123   // Update settings if the observer already exists, create a new one otherwise. | 
|   65   if (it != bitrate_observer_configs_.end()) { |  124   if (it != bitrate_observer_configs_.end()) { | 
|   66     it->min_bitrate_bps = min_bitrate_bps; |  125     it->min_bitrate_bps = min_bitrate_bps; | 
|   67     it->max_bitrate_bps = max_bitrate_bps; |  126     it->max_bitrate_bps = max_bitrate_bps; | 
|   68     it->pad_up_bitrate_bps = pad_up_bitrate_bps; |  127     it->pad_up_bitrate_bps = pad_up_bitrate_bps; | 
|   69     it->enforce_min_bitrate = enforce_min_bitrate; |  128     it->enforce_min_bitrate = enforce_min_bitrate; | 
|   70   } else { |  129   } else { | 
|   71     bitrate_observer_configs_.push_back( |  130     bitrate_observer_configs_.push_back( | 
|   72         ObserverConfig(observer, min_bitrate_bps, max_bitrate_bps, |  131         ObserverConfig(observer, min_bitrate_bps, max_bitrate_bps, | 
|   73                        pad_up_bitrate_bps, enforce_min_bitrate)); |  132                        pad_up_bitrate_bps, enforce_min_bitrate)); | 
|   74   } |  133   } | 
|   75  |  134  | 
|   76   ObserverAllocation allocation; |  135   ObserverAllocation allocation; | 
|   77   if (last_bitrate_bps_ > 0) { |  136   if (last_bitrate_bps_ > 0) { | 
|   78     // Calculate a new allocation and update all observers. |  137     // Calculate a new allocation and update all observers. | 
|   79     allocation = AllocateBitrates(last_bitrate_bps_); |  138     allocation = AllocateBitrates(last_bitrate_bps_); | 
|   80     for (const auto& kv : allocation) |  139     for (auto& config : bitrate_observer_configs_) { | 
|   81       kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_); |  140       uint32_t allocated_bitrate = allocation[config.observer]; | 
 |  141       uint32_t protection_bitrate = config.observer->OnBitrateUpdated( | 
 |  142           allocated_bitrate, last_fraction_loss_, last_rtt_); | 
 |  143       config.allocated_bitrate_bps = allocated_bitrate; | 
 |  144       if (allocated_bitrate > 0) | 
 |  145         config.media_ratio = MediaRatio(allocated_bitrate, protection_bitrate); | 
 |  146     } | 
|   82   } else { |  147   } else { | 
|   83     // Currently, an encoder is not allowed to produce frames. |  148     // Currently, an encoder is not allowed to produce frames. | 
|   84     // But we still have to return the initial config bitrate + let the |  149     // But we still have to return the initial config bitrate + let the | 
|   85     // observer know that it can not produce frames. |  150     // observer know that it can not produce frames. | 
|   86     allocation = AllocateBitrates(last_non_zero_bitrate_bps_); |  151     allocation = AllocateBitrates(last_non_zero_bitrate_bps_); | 
|   87     observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); |  152     observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_); | 
|   88   } |  153   } | 
|   89   UpdateAllocationLimits(); |  154   UpdateAllocationLimits(); | 
|   90  |  | 
|   91   last_allocation_ = allocation; |  | 
|   92 } |  155 } | 
|   93  |  156  | 
|   94 void BitrateAllocator::UpdateAllocationLimits() { |  157 void BitrateAllocator::UpdateAllocationLimits() { | 
|   95   uint32_t total_requested_padding_bitrate = 0; |  158   uint32_t total_requested_padding_bitrate = 0; | 
|   96   uint32_t total_requested_min_bitrate = 0; |  159   uint32_t total_requested_min_bitrate = 0; | 
|   97  |  160  | 
|   98   { |  161   { | 
|   99     rtc::CritScope lock(&crit_sect_); |  162     rtc::CritScope lock(&crit_sect_); | 
|  100     for (const auto& config : bitrate_observer_configs_) { |  163     for (const auto& config : bitrate_observer_configs_) { | 
|  101       if (config.enforce_min_bitrate) { |  164       if (config.enforce_min_bitrate) { | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  115     auto it = FindObserverConfig(observer); |  178     auto it = FindObserverConfig(observer); | 
|  116     if (it != bitrate_observer_configs_.end()) { |  179     if (it != bitrate_observer_configs_.end()) { | 
|  117       bitrate_observer_configs_.erase(it); |  180       bitrate_observer_configs_.erase(it); | 
|  118     } |  181     } | 
|  119   } |  182   } | 
|  120   UpdateAllocationLimits(); |  183   UpdateAllocationLimits(); | 
|  121 } |  184 } | 
|  122  |  185  | 
|  123 int BitrateAllocator::GetStartBitrate(BitrateAllocatorObserver* observer) { |  186 int BitrateAllocator::GetStartBitrate(BitrateAllocatorObserver* observer) { | 
|  124   rtc::CritScope lock(&crit_sect_); |  187   rtc::CritScope lock(&crit_sect_); | 
|  125   const auto& it = last_allocation_.find(observer); |  188   const auto& it = FindObserverConfig(observer); | 
|  126   if (it != last_allocation_.end()) |  189   if (it == bitrate_observer_configs_.end()) { | 
|  127     return it->second; |  190     // This observer hasn't been added yet, just give it its fair share. | 
|  128  |  191     return last_non_zero_bitrate_bps_ / | 
|  129   // This is a new observer that has not yet been started. Assume that if it is |  192              static_cast<int>((bitrate_observer_configs_.size() + 1)); | 
|  130   // added, all observers would split the available bitrate evenly. |  193   } else if (it->allocated_bitrate_bps == -1) { | 
|  131   return last_non_zero_bitrate_bps_ / |  194     // This observer hasn't received an allocation yet, so do the same. | 
|  132          static_cast<int>((bitrate_observer_configs_.size() + 1)); |  195     return last_non_zero_bitrate_bps_ / | 
 |  196              static_cast<int>(bitrate_observer_configs_.size()); | 
 |  197   } else { | 
 |  198     // This observer already has an allocation. | 
 |  199     return it->allocated_bitrate_bps; | 
 |  200   } | 
|  133 } |  201 } | 
|  134  |  202  | 
|  135 BitrateAllocator::ObserverConfigList::iterator |  203 BitrateAllocator::ObserverConfigs::iterator | 
|  136 BitrateAllocator::FindObserverConfig( |  204 BitrateAllocator::FindObserverConfig( | 
|  137     const BitrateAllocatorObserver* observer) { |  205     const BitrateAllocatorObserver* observer) { | 
|  138   for (auto it = bitrate_observer_configs_.begin(); |  206   for (auto it = bitrate_observer_configs_.begin(); | 
|  139        it != bitrate_observer_configs_.end(); ++it) { |  207        it != bitrate_observer_configs_.end(); ++it) { | 
|  140     if (it->observer == observer) |  208     if (it->observer == observer) | 
|  141       return it; |  209       return it; | 
|  142   } |  210   } | 
|  143   return bitrate_observer_configs_.end(); |  211   return bitrate_observer_configs_.end(); | 
|  144 } |  212 } | 
|  145  |  213  | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  195     remaining_bitrate -= allocated_bitrate; |  263     remaining_bitrate -= allocated_bitrate; | 
|  196   } |  264   } | 
|  197  |  265  | 
|  198   // Allocate bitrate to all previously active streams. |  266   // Allocate bitrate to all previously active streams. | 
|  199   if (remaining_bitrate > 0) { |  267   if (remaining_bitrate > 0) { | 
|  200     for (const auto& observer_config : bitrate_observer_configs_) { |  268     for (const auto& observer_config : bitrate_observer_configs_) { | 
|  201       if (observer_config.enforce_min_bitrate || |  269       if (observer_config.enforce_min_bitrate || | 
|  202           LastAllocatedBitrate(observer_config) == 0) |  270           LastAllocatedBitrate(observer_config) == 0) | 
|  203         continue; |  271         continue; | 
|  204  |  272  | 
|  205       if (remaining_bitrate >= observer_config.min_bitrate_bps) { |  273       uint32_t required_bitrate = MinBitrateWithHysteresis(observer_config); | 
|  206         allocation[observer_config.observer] = observer_config.min_bitrate_bps; |  274       if (remaining_bitrate >= required_bitrate) { | 
|  207         remaining_bitrate -= observer_config.min_bitrate_bps; |  275         allocation[observer_config.observer] = required_bitrate; | 
 |  276         remaining_bitrate -= required_bitrate; | 
|  208       } |  277       } | 
|  209     } |  278     } | 
|  210   } |  279   } | 
|  211  |  280  | 
|  212   // Allocate bitrate to previously paused streams. |  281   // Allocate bitrate to previously paused streams. | 
|  213   if (remaining_bitrate > 0) { |  282   if (remaining_bitrate > 0) { | 
|  214     for (const auto& observer_config : bitrate_observer_configs_) { |  283     for (const auto& observer_config : bitrate_observer_configs_) { | 
|  215       if (LastAllocatedBitrate(observer_config) != 0) |  284       if (LastAllocatedBitrate(observer_config) != 0) | 
|  216         continue; |  285         continue; | 
|  217  |  286  | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  256     bitrate -= observer_config.max_bitrate_bps; |  325     bitrate -= observer_config.max_bitrate_bps; | 
|  257   } |  326   } | 
|  258   DistributeBitrateEvenly(bitrate, true, kTransmissionMaxBitrateMultiplier, |  327   DistributeBitrateEvenly(bitrate, true, kTransmissionMaxBitrateMultiplier, | 
|  259                           &allocation); |  328                           &allocation); | 
|  260   return allocation; |  329   return allocation; | 
|  261 } |  330 } | 
|  262  |  331  | 
|  263 uint32_t BitrateAllocator::LastAllocatedBitrate( |  332 uint32_t BitrateAllocator::LastAllocatedBitrate( | 
|  264     const ObserverConfig& observer_config) { |  333     const ObserverConfig& observer_config) { | 
|  265  |  334  | 
|  266   const auto& it = last_allocation_.find(observer_config.observer); |  | 
|  267   if (it != last_allocation_.end()) |  | 
|  268     return it->second; |  | 
|  269  |  | 
|  270   // Return the configured minimum bitrate for newly added observers, to avoid |  335   // Return the configured minimum bitrate for newly added observers, to avoid | 
|  271   // requiring an extra high bitrate for the observer to get an allocated |  336   // requiring an extra high bitrate for the observer to get an allocated | 
|  272   // bitrate. |  337   // bitrate. | 
|  273   return observer_config.min_bitrate_bps; |  338   return observer_config.allocated_bitrate_bps == -1 ? | 
 |  339       observer_config.min_bitrate_bps : observer_config.allocated_bitrate_bps; | 
|  274 } |  340 } | 
|  275  |  341  | 
|  276 uint32_t BitrateAllocator::MinBitrateWithHysteresis( |  342 uint32_t BitrateAllocator::MinBitrateWithHysteresis( | 
|  277     const ObserverConfig& observer_config) { |  343     const ObserverConfig& observer_config) { | 
|  278   uint32_t min_bitrate = observer_config.min_bitrate_bps; |  344   uint32_t min_bitrate = observer_config.min_bitrate_bps; | 
|  279   if (LastAllocatedBitrate(observer_config) == 0) { |  345   if (LastAllocatedBitrate(observer_config) == 0) { | 
|  280     min_bitrate += std::max(static_cast<uint32_t>(kToggleFactor * min_bitrate), |  346     min_bitrate += std::max(static_cast<uint32_t>(kToggleFactor * min_bitrate), | 
|  281                             kMinToggleBitrateBps); |  347                             kMinToggleBitrateBps); | 
|  282   } |  348   } | 
 |  349   // Account for protection bitrate used by this observer in the previous | 
 |  350   // allocation. | 
 |  351   // Note: the ratio will only be updated when the stream is active, meaning a | 
 |  352   // paused stream won't get any ratio updates. This might lead to waiting a bit | 
 |  353   // longer than necessary if the network condition improves, but this is to | 
 |  354   // avoid too much toggling. | 
 |  355   if (observer_config.media_ratio > 0.0 && observer_config.media_ratio < 1.0) | 
 |  356     min_bitrate += min_bitrate * (1.0 - observer_config.media_ratio); | 
 |  357  | 
|  283   return min_bitrate; |  358   return min_bitrate; | 
|  284 } |  359 } | 
|  285  |  360  | 
|  286 void BitrateAllocator::DistributeBitrateEvenly(uint32_t bitrate, |  361 void BitrateAllocator::DistributeBitrateEvenly(uint32_t bitrate, | 
|  287                                                bool include_zero_allocations, |  362                                                bool include_zero_allocations, | 
|  288                                                int max_multiplier, |  363                                                int max_multiplier, | 
|  289                                                ObserverAllocation* allocation) { |  364                                                ObserverAllocation* allocation) { | 
|  290   RTC_DCHECK_EQ(allocation->size(), bitrate_observer_configs_.size()); |  365   RTC_DCHECK_EQ(allocation->size(), bitrate_observer_configs_.size()); | 
|  291  |  366  | 
|  292   ObserverSortingMap list_max_bitrates; |  367   ObserverSortingMap list_max_bitrates; | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  325   uint32_t extra_bitrate_per_observer = (bitrate - sum_min_bitrates) / |  400   uint32_t extra_bitrate_per_observer = (bitrate - sum_min_bitrates) / | 
|  326       static_cast<uint32_t>(bitrate_observer_configs_.size()); |  401       static_cast<uint32_t>(bitrate_observer_configs_.size()); | 
|  327   for (const auto& observer_config : bitrate_observer_configs_) { |  402   for (const auto& observer_config : bitrate_observer_configs_) { | 
|  328     if (observer_config.min_bitrate_bps + extra_bitrate_per_observer < |  403     if (observer_config.min_bitrate_bps + extra_bitrate_per_observer < | 
|  329         MinBitrateWithHysteresis(observer_config)) |  404         MinBitrateWithHysteresis(observer_config)) | 
|  330       return false; |  405       return false; | 
|  331   } |  406   } | 
|  332   return true; |  407   return true; | 
|  333 } |  408 } | 
|  334 }  // namespace webrtc |  409 }  // namespace webrtc | 
| OLD | NEW |