tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

bitrate_controller.cc (6125B)


      1 /*
      2 *  Copyright (c) 2018 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 "modules/congestion_controller/pcc/bitrate_controller.h"
     12 
     13 #include <algorithm>
     14 #include <cmath>
     15 #include <cstdint>
     16 #include <cstdlib>
     17 #include <memory>
     18 #include <optional>
     19 #include <utility>
     20 #include <vector>
     21 
     22 #include "api/units/data_rate.h"
     23 #include "modules/congestion_controller/pcc/monitor_interval.h"
     24 #include "modules/congestion_controller/pcc/utility_function.h"
     25 
     26 namespace webrtc {
     27 namespace pcc {
     28 
     29 PccBitrateController::PccBitrateController(double initial_conversion_factor,
     30                                           double initial_dynamic_boundary,
     31                                           double dynamic_boundary_increment,
     32                                           double rtt_gradient_coefficient,
     33                                           double loss_coefficient,
     34                                           double throughput_coefficient,
     35                                           double throughput_power,
     36                                           double rtt_gradient_threshold,
     37                                           double delay_gradient_negative_bound)
     38    : PccBitrateController(initial_conversion_factor,
     39                           initial_dynamic_boundary,
     40                           dynamic_boundary_increment,
     41                           std::make_unique<ModifiedVivaceUtilityFunction>(
     42                               rtt_gradient_coefficient,
     43                               loss_coefficient,
     44                               throughput_coefficient,
     45                               throughput_power,
     46                               rtt_gradient_threshold,
     47                               delay_gradient_negative_bound)) {}
     48 
     49 PccBitrateController::PccBitrateController(
     50    double initial_conversion_factor,
     51    double initial_dynamic_boundary,
     52    double dynamic_boundary_increment,
     53    std::unique_ptr<PccUtilityFunctionInterface> utility_function)
     54    : consecutive_boundary_adjustments_number_(0),
     55      initial_dynamic_boundary_(initial_dynamic_boundary),
     56      dynamic_boundary_increment_(dynamic_boundary_increment),
     57      utility_function_(std::move(utility_function)),
     58      step_size_adjustments_number_(0),
     59      initial_conversion_factor_(initial_conversion_factor) {}
     60 
     61 PccBitrateController::~PccBitrateController() = default;
     62 
     63 double PccBitrateController::ComputeStepSize(double utility_gradient) {
     64  // Computes number of consecutive step size adjustments.
     65  if (utility_gradient > 0) {
     66    step_size_adjustments_number_ =
     67        std::max<int64_t>(step_size_adjustments_number_ + 1, 1);
     68  } else if (utility_gradient < 0) {
     69    step_size_adjustments_number_ =
     70        std::min<int64_t>(step_size_adjustments_number_ - 1, -1);
     71  } else {
     72    step_size_adjustments_number_ = 0;
     73  }
     74  // Computes step size amplifier.
     75  int64_t step_size_amplifier = 1;
     76  if (std::abs(step_size_adjustments_number_) <= 3) {
     77    step_size_amplifier =
     78        std::max<int64_t>(std::abs(step_size_adjustments_number_), 1);
     79  } else {
     80    step_size_amplifier = 2 * std::abs(step_size_adjustments_number_) - 3;
     81  }
     82  return step_size_amplifier * initial_conversion_factor_;
     83 }
     84 
     85 double PccBitrateController::ApplyDynamicBoundary(double rate_change,
     86                                                  double bitrate) {
     87  double rate_change_abs = std::abs(rate_change);
     88  int64_t rate_change_sign = (rate_change > 0) ? 1 : -1;
     89  if (consecutive_boundary_adjustments_number_ * rate_change_sign < 0) {
     90    consecutive_boundary_adjustments_number_ = 0;
     91  }
     92  double dynamic_change_boundary =
     93      initial_dynamic_boundary_ +
     94      std::abs(consecutive_boundary_adjustments_number_) *
     95          dynamic_boundary_increment_;
     96  double boundary = bitrate * dynamic_change_boundary;
     97  if (rate_change_abs > boundary) {
     98    consecutive_boundary_adjustments_number_ += rate_change_sign;
     99    return boundary * rate_change_sign;
    100  }
    101  // Rate change smaller than boundary. Reset boundary to the smallest possible
    102  // that would allow the change.
    103  while (rate_change_abs <= boundary &&
    104         consecutive_boundary_adjustments_number_ * rate_change_sign > 0) {
    105    consecutive_boundary_adjustments_number_ -= rate_change_sign;
    106    dynamic_change_boundary =
    107        initial_dynamic_boundary_ +
    108        std::abs(consecutive_boundary_adjustments_number_) *
    109            dynamic_boundary_increment_;
    110    boundary = bitrate * dynamic_change_boundary;
    111  }
    112  consecutive_boundary_adjustments_number_ += rate_change_sign;
    113  return rate_change;
    114 }
    115 
    116 std::optional<DataRate> PccBitrateController::ComputeRateUpdateForSlowStartMode(
    117    const PccMonitorInterval& monitor_interval) {
    118  double utility_value = utility_function_->Compute(monitor_interval);
    119  if (previous_utility_.has_value() && utility_value <= previous_utility_) {
    120    return std::nullopt;
    121  }
    122  previous_utility_ = utility_value;
    123  return monitor_interval.GetTargetSendingRate();
    124 }
    125 
    126 DataRate PccBitrateController::ComputeRateUpdateForOnlineLearningMode(
    127    const std::vector<PccMonitorInterval>& intervals,
    128    DataRate bandwith_estimate) {
    129  double first_utility = utility_function_->Compute(intervals[0]);
    130  double second_utility = utility_function_->Compute(intervals[1]);
    131  double first_bitrate_bps = intervals[0].GetTargetSendingRate().bps();
    132  double second_bitrate_bps = intervals[1].GetTargetSendingRate().bps();
    133  double gradient = (first_utility - second_utility) /
    134                    (first_bitrate_bps - second_bitrate_bps);
    135  double rate_change_bps = gradient * ComputeStepSize(gradient);  // delta_r
    136  rate_change_bps =
    137      ApplyDynamicBoundary(rate_change_bps, bandwith_estimate.bps());
    138  return DataRate::BitsPerSec(
    139      std::max(0.0, bandwith_estimate.bps() + rate_change_bps));
    140 }
    141 
    142 }  // namespace pcc
    143 }  // namespace webrtc