LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/congestion_controller - probe_controller.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 101 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/congestion_controller/probe_controller.h"
      12             : 
      13             : #include <algorithm>
      14             : #include <initializer_list>
      15             : 
      16             : #include "webrtc/base/logging.h"
      17             : #include "webrtc/base/safe_conversions.h"
      18             : #include "webrtc/system_wrappers/include/metrics.h"
      19             : 
      20             : namespace webrtc {
      21             : 
      22             : namespace {
      23             : // Maximum waiting time from the time of initiating probing to getting
      24             : // the measured results back.
      25             : constexpr int64_t kMaxWaitingTimeForProbingResultMs = 1000;
      26             : 
      27             : // Value of |min_bitrate_to_probe_further_bps_| that indicates
      28             : // further probing is disabled.
      29             : constexpr int kExponentialProbingDisabled = 0;
      30             : 
      31             : // Default probing bitrate limit. Applied only when the application didn't
      32             : // specify max bitrate.
      33             : constexpr int64_t kDefaultMaxProbingBitrateBps = 5000000;
      34             : 
      35             : // This is a limit on how often probing can be done when there is a BW
      36             : // drop detected in ALR.
      37             : constexpr int64_t kAlrProbingIntervalMinMs = 5000;
      38             : 
      39             : // Interval between probes when ALR periodic probing is enabled.
      40             : constexpr int64_t kAlrPeriodicProbingIntervalMs = 5000;
      41             : 
      42             : // Minimum probe bitrate percentage to probe further for repeated probes,
      43             : // relative to the previous probe. For example, if 1Mbps probe results in
      44             : // 80kbps, then we'll probe again at 1.6Mbps. In that case second probe won't be
      45             : // sent if we get 600kbps from the first one.
      46             : constexpr int kRepeatedProbeMinPercentage = 70;
      47             : 
      48             : }  // namespace
      49             : 
      50           0 : ProbeController::ProbeController(PacedSender* pacer, Clock* clock)
      51             :     : pacer_(pacer),
      52             :       clock_(clock),
      53             :       network_state_(kNetworkUp),
      54             :       state_(State::kInit),
      55             :       min_bitrate_to_probe_further_bps_(kExponentialProbingDisabled),
      56             :       time_last_probing_initiated_ms_(0),
      57             :       estimated_bitrate_bps_(0),
      58             :       start_bitrate_bps_(0),
      59             :       max_bitrate_bps_(0),
      60           0 :       last_alr_probing_time_(clock_->TimeInMilliseconds()),
      61             :       enable_periodic_alr_probing_(false),
      62           0 :       mid_call_probing_waiting_for_result_(false) {}
      63             : 
      64           0 : void ProbeController::SetBitrates(int64_t min_bitrate_bps,
      65             :                                   int64_t start_bitrate_bps,
      66             :                                   int64_t max_bitrate_bps) {
      67           0 :   rtc::CritScope cs(&critsect_);
      68             : 
      69           0 :   if (start_bitrate_bps > 0)  {
      70           0 :     start_bitrate_bps_ = start_bitrate_bps;
      71           0 :   } else if (start_bitrate_bps_ == 0) {
      72           0 :     start_bitrate_bps_ = min_bitrate_bps;
      73             :   }
      74             : 
      75             :   // The reason we use the variable |old_max_bitrate_pbs| is because we
      76             :   // need to set |max_bitrate_bps_| before we call InitiateProbing.
      77           0 :   int64_t old_max_bitrate_bps = max_bitrate_bps_;
      78           0 :   max_bitrate_bps_ = max_bitrate_bps;
      79             : 
      80           0 :   switch (state_) {
      81             :     case State::kInit:
      82           0 :       if (network_state_ == kNetworkUp)
      83           0 :         InitiateExponentialProbing();
      84           0 :       break;
      85             : 
      86             :     case State::kWaitingForProbingResult:
      87           0 :       break;
      88             : 
      89             :     case State::kProbingComplete:
      90             :       // If the new max bitrate is higher than the old max bitrate and the
      91             :       // estimate is lower than the new max bitrate then initiate probing.
      92           0 :       if (estimated_bitrate_bps_ != 0 &&
      93           0 :           old_max_bitrate_bps < max_bitrate_bps_ &&
      94           0 :           estimated_bitrate_bps_ < max_bitrate_bps_) {
      95             :         // The assumption is that if we jump more than 20% in the bandwidth
      96             :         // estimate or if the bandwidth estimate is within 90% of the new
      97             :         // max bitrate then the probing attempt was successful.
      98           0 :         mid_call_probing_succcess_threshold_ =
      99           0 :             std::min(estimated_bitrate_bps_ * 1.2, max_bitrate_bps_ * 0.9);
     100           0 :         mid_call_probing_waiting_for_result_ = true;
     101           0 :         mid_call_probing_bitrate_bps_ = max_bitrate_bps_;
     102             : 
     103           0 :         RTC_HISTOGRAM_COUNTS_10000("WebRTC.BWE.MidCallProbing.Initiated",
     104             :                                    max_bitrate_bps_ / 1000);
     105             : 
     106           0 :         InitiateProbing(clock_->TimeInMilliseconds(), {max_bitrate_bps}, false);
     107             :       }
     108           0 :       break;
     109             :   }
     110           0 : }
     111             : 
     112           0 : void ProbeController::OnNetworkStateChanged(NetworkState network_state) {
     113           0 :   rtc::CritScope cs(&critsect_);
     114           0 :   network_state_ = network_state;
     115           0 :   if (network_state_ == kNetworkUp && state_ == State::kInit)
     116           0 :     InitiateExponentialProbing();
     117           0 : }
     118             : 
     119           0 : void ProbeController::InitiateExponentialProbing() {
     120           0 :   RTC_DCHECK(network_state_ == kNetworkUp);
     121           0 :   RTC_DCHECK(state_ == State::kInit);
     122           0 :   RTC_DCHECK_GT(start_bitrate_bps_, 0);
     123             : 
     124             :   // When probing at 1.8 Mbps ( 6x 300), this represents a threshold of
     125             :   // 1.2 Mbps to continue probing.
     126           0 :   InitiateProbing(clock_->TimeInMilliseconds(),
     127           0 :                   {3 * start_bitrate_bps_, 6 * start_bitrate_bps_}, true);
     128           0 : }
     129             : 
     130           0 : void ProbeController::SetEstimatedBitrate(int64_t bitrate_bps) {
     131           0 :   rtc::CritScope cs(&critsect_);
     132           0 :   int64_t now_ms = clock_->TimeInMilliseconds();
     133             : 
     134           0 :   if (mid_call_probing_waiting_for_result_ &&
     135           0 :       bitrate_bps >= mid_call_probing_succcess_threshold_) {
     136           0 :     RTC_HISTOGRAM_COUNTS_10000("WebRTC.BWE.MidCallProbing.Success",
     137             :                                mid_call_probing_bitrate_bps_ / 1000);
     138           0 :     RTC_HISTOGRAM_COUNTS_10000("WebRTC.BWE.MidCallProbing.ProbedKbps",
     139             :                                bitrate_bps / 1000);
     140           0 :     mid_call_probing_waiting_for_result_ = false;
     141             :   }
     142             : 
     143           0 :   if (state_ == State::kWaitingForProbingResult) {
     144             :     // Continue probing if probing results indicate channel has greater
     145             :     // capacity.
     146           0 :     LOG(LS_INFO) << "Measured bitrate: " << bitrate_bps
     147           0 :                  << " Minimum to probe further: "
     148           0 :                  << min_bitrate_to_probe_further_bps_;
     149             : 
     150           0 :     if (min_bitrate_to_probe_further_bps_ != kExponentialProbingDisabled &&
     151           0 :         bitrate_bps > min_bitrate_to_probe_further_bps_) {
     152             :       // Double the probing bitrate.
     153           0 :       InitiateProbing(now_ms, {2 * bitrate_bps}, true);
     154             :     }
     155             :   }
     156             : 
     157             :   // Detect a drop in estimated BW when operating in ALR and not already
     158             :   // probing. The current response is to initiate a single probe session at the
     159             :   // previous bitrate and immediately use the reported bitrate as the new
     160             :   // bitrate.
     161             :   //
     162             :   // If the probe session fails, the assumption is that this drop was a
     163             :   // real one from a competing flow or something else on the network and
     164             :   // it ramps up from bitrate_bps.
     165           0 :   if (state_ == State::kProbingComplete &&
     166           0 :       pacer_->GetApplicationLimitedRegionStartTime() &&
     167           0 :       bitrate_bps < estimated_bitrate_bps_ / 2 &&
     168           0 :       (now_ms - last_alr_probing_time_) > kAlrProbingIntervalMinMs) {
     169           0 :     LOG(LS_INFO) << "Detected big BW drop in ALR, start probe.";
     170             :     // Track how often we probe in response to BW drop in ALR.
     171           0 :     RTC_HISTOGRAM_COUNTS_10000("WebRTC.BWE.AlrProbingIntervalInS",
     172             :                                (now_ms - last_alr_probing_time_) / 1000);
     173           0 :     InitiateProbing(now_ms, {estimated_bitrate_bps_}, false);
     174           0 :     last_alr_probing_time_ = now_ms;
     175             : 
     176             :     // TODO(isheriff): May want to track when we did ALR probing in order
     177             :     // to reset |last_alr_probing_time_| if we validate that it was a
     178             :     // drop due to exogenous event.
     179             :   }
     180             : 
     181           0 :   estimated_bitrate_bps_ = bitrate_bps;
     182           0 : }
     183             : 
     184           0 : void ProbeController::EnablePeriodicAlrProbing(bool enable) {
     185           0 :   rtc::CritScope cs(&critsect_);
     186           0 :   enable_periodic_alr_probing_ = enable;
     187           0 : }
     188             : 
     189           0 : void ProbeController::Process() {
     190           0 :   rtc::CritScope cs(&critsect_);
     191             : 
     192           0 :   int64_t now_ms = clock_->TimeInMilliseconds();
     193             : 
     194           0 :   if (now_ms - time_last_probing_initiated_ms_ >
     195             :       kMaxWaitingTimeForProbingResultMs) {
     196           0 :     mid_call_probing_waiting_for_result_ = false;
     197             : 
     198           0 :     if (state_ == State::kWaitingForProbingResult) {
     199           0 :       LOG(LS_INFO) << "kWaitingForProbingResult: timeout";
     200           0 :       state_ = State::kProbingComplete;
     201           0 :       min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled;
     202             :     }
     203             :   }
     204             : 
     205           0 :   if (state_ != State::kProbingComplete || !enable_periodic_alr_probing_)
     206           0 :     return;
     207             : 
     208             :   // Probe bandwidth periodically when in ALR state.
     209             :   rtc::Optional<int64_t> alr_start_time =
     210           0 :       pacer_->GetApplicationLimitedRegionStartTime();
     211           0 :   if (alr_start_time) {
     212             :     int64_t next_probe_time_ms =
     213           0 :         std::max(*alr_start_time, time_last_probing_initiated_ms_) +
     214           0 :         kAlrPeriodicProbingIntervalMs;
     215           0 :     if (now_ms >= next_probe_time_ms) {
     216           0 :       InitiateProbing(now_ms, {estimated_bitrate_bps_ * 2}, true);
     217             :     }
     218             :   }
     219             : }
     220             : 
     221           0 : void ProbeController::InitiateProbing(
     222             :     int64_t now_ms,
     223             :     std::initializer_list<int64_t> bitrates_to_probe,
     224             :     bool probe_further) {
     225           0 :   for (int64_t bitrate : bitrates_to_probe) {
     226             :     int64_t max_probe_bitrate_bps =
     227           0 :         max_bitrate_bps_ > 0 ? max_bitrate_bps_ : kDefaultMaxProbingBitrateBps;
     228           0 :     if (bitrate > max_probe_bitrate_bps) {
     229           0 :       bitrate = max_probe_bitrate_bps;
     230           0 :       probe_further = false;
     231             :     }
     232           0 :     pacer_->CreateProbeCluster(rtc::checked_cast<int>(bitrate));
     233             :   }
     234           0 :   time_last_probing_initiated_ms_ = now_ms;
     235           0 :   if (probe_further) {
     236           0 :     state_ = State::kWaitingForProbingResult;
     237           0 :     min_bitrate_to_probe_further_bps_ =
     238           0 :         (*(bitrates_to_probe.end() - 1)) * kRepeatedProbeMinPercentage / 100;
     239             :   } else {
     240           0 :     state_ = State::kProbingComplete;
     241           0 :     min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled;
     242             :   }
     243           0 : }
     244             : 
     245             : }  // namespace webrtc

Generated by: LCOV version 1.13