tor-browser

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

pcc_network_controller.cc (15795B)


      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/pcc_network_controller.h"
     12 
     13 #include <algorithm>
     14 #include <cstddef>
     15 #include <cstdint>
     16 #include <optional>
     17 
     18 #include "api/transport/network_control.h"
     19 #include "api/transport/network_types.h"
     20 #include "api/units/data_rate.h"
     21 #include "api/units/data_size.h"
     22 #include "api/units/time_delta.h"
     23 #include "api/units/timestamp.h"
     24 #include "rtc_base/checks.h"
     25 
     26 namespace webrtc {
     27 namespace pcc {
     28 namespace {
     29 constexpr int64_t kInitialRttMs = 200;
     30 constexpr int64_t kInitialBandwidthKbps = 300;
     31 constexpr double kMonitorIntervalDurationRatio = 1;
     32 constexpr double kDefaultSamplingStep = 0.05;
     33 constexpr double kTimeoutRatio = 2;
     34 constexpr double kAlphaForRtt = 0.9;
     35 constexpr double kSlowStartModeIncrease = 1.5;
     36 
     37 constexpr double kAlphaForPacketInterval = 0.9;
     38 constexpr int64_t kMinPacketsNumberPerInterval = 20;
     39 const TimeDelta kMinDurationOfMonitorInterval = TimeDelta::Millis(50);
     40 const TimeDelta kStartupDuration = TimeDelta::Millis(500);
     41 constexpr double kMinRateChangeBps = 4000;
     42 constexpr DataRate kMinRateHaveMultiplicativeRateChange = DataRate::BitsPerSec(
     43    static_cast<int64_t>(kMinRateChangeBps / kDefaultSamplingStep));
     44 
     45 // Bitrate controller constants.
     46 constexpr double kInitialConversionFactor = 5;
     47 constexpr double kInitialDynamicBoundary = 0.1;
     48 constexpr double kDynamicBoundaryIncrement = 0.1;
     49 // Utility function parameters.
     50 constexpr double kRttGradientCoefficientBps = 0.005;
     51 constexpr double kLossCoefficientBps = 10;
     52 constexpr double kThroughputCoefficient = 0.001;
     53 constexpr double kThroughputPower = 0.9;
     54 constexpr double kRttGradientThreshold = 0.01;
     55 constexpr double kDelayGradientNegativeBound = 0.1;
     56 
     57 constexpr int64_t kNumberOfPacketsToKeep = 20;
     58 const uint64_t kRandomSeed = 100;
     59 }  // namespace
     60 
     61 PccNetworkController::PccNetworkController(NetworkControllerConfig config)
     62    : start_time_(Timestamp::PlusInfinity()),
     63      last_sent_packet_time_(Timestamp::PlusInfinity()),
     64      smoothed_packets_sending_interval_(TimeDelta::Zero()),
     65      mode_(Mode::kStartup),
     66      default_bandwidth_(DataRate::KilobitsPerSec(kInitialBandwidthKbps)),
     67      bandwidth_estimate_(default_bandwidth_),
     68      rtt_tracker_(TimeDelta::Millis(kInitialRttMs), kAlphaForRtt),
     69      monitor_interval_timeout_(TimeDelta::Millis(kInitialRttMs) *
     70                                kTimeoutRatio),
     71      monitor_interval_length_strategy_(MonitorIntervalLengthStrategy::kFixed),
     72      monitor_interval_duration_ratio_(kMonitorIntervalDurationRatio),
     73      sampling_step_(kDefaultSamplingStep),
     74      monitor_interval_timeout_ratio_(kTimeoutRatio),
     75      min_packets_number_per_interval_(kMinPacketsNumberPerInterval),
     76      bitrate_controller_(kInitialConversionFactor,
     77                          kInitialDynamicBoundary,
     78                          kDynamicBoundaryIncrement,
     79                          kRttGradientCoefficientBps,
     80                          kLossCoefficientBps,
     81                          kThroughputCoefficient,
     82                          kThroughputPower,
     83                          kRttGradientThreshold,
     84                          kDelayGradientNegativeBound),
     85      monitor_intervals_duration_(TimeDelta::Zero()),
     86      complete_feedback_monitor_interval_number_(0),
     87      random_generator_(kRandomSeed) {
     88  if (config.constraints.starting_rate) {
     89    default_bandwidth_ = *config.constraints.starting_rate;
     90    bandwidth_estimate_ = default_bandwidth_;
     91  }
     92 }
     93 
     94 PccNetworkController::~PccNetworkController() {}
     95 
     96 NetworkControlUpdate PccNetworkController::CreateRateUpdate(
     97    Timestamp at_time) const {
     98  DataRate sending_rate = DataRate::Zero();
     99  if (monitor_intervals_.empty() ||
    100      (monitor_intervals_.size() >= monitor_intervals_bitrates_.size() &&
    101       at_time >= monitor_intervals_.back().GetEndTime())) {
    102    sending_rate = bandwidth_estimate_;
    103  } else {
    104    sending_rate = monitor_intervals_.back().GetTargetSendingRate();
    105  }
    106  // Set up config when sending rate is computed.
    107  NetworkControlUpdate update;
    108 
    109  // Set up target rate to encoder.
    110  TargetTransferRate target_rate_msg;
    111  target_rate_msg.at_time = at_time;
    112  target_rate_msg.network_estimate.at_time = at_time;
    113  target_rate_msg.network_estimate.round_trip_time = rtt_tracker_.GetRtt();
    114  // TODO(koloskova): Add correct estimate.
    115  target_rate_msg.network_estimate.loss_rate_ratio = 0;
    116  target_rate_msg.network_estimate.bwe_period =
    117      monitor_interval_duration_ratio_ * rtt_tracker_.GetRtt();
    118 
    119  target_rate_msg.target_rate = sending_rate;
    120  update.target_rate = target_rate_msg;
    121 
    122  // Set up pacing/padding target rate.
    123  PacerConfig pacer_config;
    124  pacer_config.at_time = at_time;
    125  pacer_config.time_window = TimeDelta::Millis(1);
    126  pacer_config.data_window = sending_rate * pacer_config.time_window;
    127  pacer_config.pad_window = sending_rate * pacer_config.time_window;
    128 
    129  update.pacer_config = pacer_config;
    130  return update;
    131 }
    132 
    133 NetworkControlUpdate PccNetworkController::OnSentPacket(SentPacket msg) {
    134  // Start new monitor interval if previous has finished.
    135  // Monitor interval is initialized in OnProcessInterval function.
    136  if (start_time_.IsInfinite()) {
    137    start_time_ = msg.send_time;
    138    monitor_intervals_duration_ = kStartupDuration;
    139    monitor_intervals_bitrates_ = {bandwidth_estimate_};
    140    monitor_intervals_.emplace_back(bandwidth_estimate_, msg.send_time,
    141                                    monitor_intervals_duration_);
    142    complete_feedback_monitor_interval_number_ = 0;
    143  }
    144  if (last_sent_packet_time_.IsFinite()) {
    145    smoothed_packets_sending_interval_ =
    146        (msg.send_time - last_sent_packet_time_) * kAlphaForPacketInterval +
    147        (1 - kAlphaForPacketInterval) * smoothed_packets_sending_interval_;
    148  }
    149  last_sent_packet_time_ = msg.send_time;
    150  if (!monitor_intervals_.empty() &&
    151      msg.send_time >= monitor_intervals_.back().GetEndTime() &&
    152      monitor_intervals_bitrates_.size() > monitor_intervals_.size()) {
    153    // Start new monitor interval.
    154    monitor_intervals_.emplace_back(
    155        monitor_intervals_bitrates_[monitor_intervals_.size()], msg.send_time,
    156        monitor_intervals_duration_);
    157  }
    158  if (IsTimeoutExpired(msg.send_time)) {
    159    DataSize received_size = DataSize::Zero();
    160    for (size_t i = 1; i < last_received_packets_.size(); ++i) {
    161      received_size += last_received_packets_[i].sent_packet.size;
    162    }
    163    TimeDelta sending_time = TimeDelta::Zero();
    164    if (!last_received_packets_.empty())
    165      sending_time = last_received_packets_.back().receive_time -
    166                     last_received_packets_.front().receive_time;
    167    DataRate receiving_rate = bandwidth_estimate_;
    168    if (sending_time > TimeDelta::Zero())
    169      receiving_rate = received_size / sending_time;
    170    bandwidth_estimate_ =
    171        std::min<DataRate>(bandwidth_estimate_ * 0.5, receiving_rate);
    172    if (mode_ == Mode::kSlowStart)
    173      mode_ = Mode::kOnlineLearning;
    174  }
    175  if (mode_ == Mode::kStartup &&
    176      msg.send_time - start_time_ >= kStartupDuration) {
    177    DataSize received_size = DataSize::Zero();
    178    for (size_t i = 1; i < last_received_packets_.size(); ++i) {
    179      received_size += last_received_packets_[i].sent_packet.size;
    180    }
    181    TimeDelta sending_time = TimeDelta::Zero();
    182    if (!last_received_packets_.empty())
    183      sending_time = last_received_packets_.back().receive_time -
    184                     last_received_packets_.front().receive_time;
    185    DataRate receiving_rate = bandwidth_estimate_;
    186    if (sending_time > TimeDelta::Zero())
    187      receiving_rate = received_size / sending_time;
    188    bandwidth_estimate_ = receiving_rate;
    189    monitor_intervals_.clear();
    190    mode_ = Mode::kSlowStart;
    191    monitor_intervals_duration_ = ComputeMonitorIntervalsDuration();
    192    monitor_intervals_bitrates_ = {bandwidth_estimate_};
    193    monitor_intervals_.emplace_back(bandwidth_estimate_, msg.send_time,
    194                                    monitor_intervals_duration_);
    195    bandwidth_estimate_ = bandwidth_estimate_ * (1 / kSlowStartModeIncrease);
    196    complete_feedback_monitor_interval_number_ = 0;
    197    return CreateRateUpdate(msg.send_time);
    198  }
    199  if (IsFeedbackCollectionDone() || IsTimeoutExpired(msg.send_time)) {
    200    // Creating new monitor intervals.
    201    monitor_intervals_.clear();
    202    monitor_interval_timeout_ =
    203        rtt_tracker_.GetRtt() * monitor_interval_timeout_ratio_;
    204    monitor_intervals_duration_ = ComputeMonitorIntervalsDuration();
    205    complete_feedback_monitor_interval_number_ = 0;
    206    // Compute bitrates and start first monitor interval.
    207    if (mode_ == Mode::kSlowStart) {
    208      monitor_intervals_bitrates_ = {kSlowStartModeIncrease *
    209                                     bandwidth_estimate_};
    210      monitor_intervals_.emplace_back(
    211          kSlowStartModeIncrease * bandwidth_estimate_, msg.send_time,
    212          monitor_intervals_duration_);
    213    } else {
    214      RTC_DCHECK(mode_ == Mode::kOnlineLearning || mode_ == Mode::kDoubleCheck);
    215      monitor_intervals_.clear();
    216      int64_t sign = 2 * (random_generator_.Rand(0, 1) % 2) - 1;
    217      RTC_DCHECK_GE(sign, -1);
    218      RTC_DCHECK_LE(sign, 1);
    219      if (bandwidth_estimate_ >= kMinRateHaveMultiplicativeRateChange) {
    220        monitor_intervals_bitrates_ = {
    221            bandwidth_estimate_ * (1 + sign * sampling_step_),
    222            bandwidth_estimate_ * (1 - sign * sampling_step_)};
    223      } else {
    224        monitor_intervals_bitrates_ = {
    225            DataRate::BitsPerSec(std::max<double>(
    226                bandwidth_estimate_.bps() + sign * kMinRateChangeBps, 0)),
    227            DataRate::BitsPerSec(std::max<double>(
    228                bandwidth_estimate_.bps() - sign * kMinRateChangeBps, 0))};
    229      }
    230      monitor_intervals_.emplace_back(monitor_intervals_bitrates_[0],
    231                                      msg.send_time,
    232                                      monitor_intervals_duration_);
    233    }
    234  }
    235  return CreateRateUpdate(msg.send_time);
    236 }
    237 
    238 TimeDelta PccNetworkController::ComputeMonitorIntervalsDuration() const {
    239  TimeDelta monitor_intervals_duration = TimeDelta::Zero();
    240  if (monitor_interval_length_strategy_ ==
    241      MonitorIntervalLengthStrategy::kAdaptive) {
    242    monitor_intervals_duration = std::max(
    243        rtt_tracker_.GetRtt() * monitor_interval_duration_ratio_,
    244        smoothed_packets_sending_interval_ * min_packets_number_per_interval_);
    245  } else {
    246    RTC_DCHECK(monitor_interval_length_strategy_ ==
    247               MonitorIntervalLengthStrategy::kFixed);
    248    monitor_intervals_duration =
    249        smoothed_packets_sending_interval_ * min_packets_number_per_interval_;
    250  }
    251  monitor_intervals_duration =
    252      std::max(kMinDurationOfMonitorInterval, monitor_intervals_duration);
    253  return monitor_intervals_duration;
    254 }
    255 
    256 bool PccNetworkController::IsTimeoutExpired(Timestamp current_time) const {
    257  if (complete_feedback_monitor_interval_number_ >= monitor_intervals_.size()) {
    258    return false;
    259  }
    260  return current_time -
    261             monitor_intervals_[complete_feedback_monitor_interval_number_]
    262                 .GetEndTime() >=
    263         monitor_interval_timeout_;
    264 }
    265 
    266 bool PccNetworkController::IsFeedbackCollectionDone() const {
    267  return complete_feedback_monitor_interval_number_ >=
    268         monitor_intervals_bitrates_.size();
    269 }
    270 
    271 NetworkControlUpdate PccNetworkController::OnTransportPacketsFeedback(
    272    TransportPacketsFeedback msg) {
    273  if (msg.packet_feedbacks.empty())
    274    return NetworkControlUpdate();
    275  // Save packets to last_received_packets_ array.
    276  for (const PacketResult& packet_result : msg.ReceivedWithSendInfo()) {
    277    last_received_packets_.push_back(packet_result);
    278  }
    279  while (last_received_packets_.size() > kNumberOfPacketsToKeep) {
    280    last_received_packets_.pop_front();
    281  }
    282  rtt_tracker_.OnPacketsFeedback(msg.PacketsWithFeedback(), msg.feedback_time);
    283  // Skip rate update in case when online learning mode just started, but
    284  // corresponding monitor intervals were not started yet.
    285  if (mode_ == Mode::kOnlineLearning &&
    286      monitor_intervals_bitrates_.size() < 2) {
    287    return NetworkControlUpdate();
    288  }
    289  if (!IsFeedbackCollectionDone() && !monitor_intervals_.empty()) {
    290    while (complete_feedback_monitor_interval_number_ <
    291           monitor_intervals_.size()) {
    292      monitor_intervals_[complete_feedback_monitor_interval_number_]
    293          .OnPacketsFeedback(msg.PacketsWithFeedback());
    294      if (!monitor_intervals_[complete_feedback_monitor_interval_number_]
    295               .IsFeedbackCollectionDone())
    296        break;
    297      ++complete_feedback_monitor_interval_number_;
    298    }
    299  }
    300  if (IsFeedbackCollectionDone()) {
    301    if (mode_ == Mode::kDoubleCheck) {
    302      mode_ = Mode::kOnlineLearning;
    303    } else if (NeedDoubleCheckMeasurments()) {
    304      mode_ = Mode::kDoubleCheck;
    305    }
    306    if (mode_ != Mode::kDoubleCheck)
    307      UpdateSendingRateAndMode();
    308  }
    309  return NetworkControlUpdate();
    310 }
    311 
    312 bool PccNetworkController::NeedDoubleCheckMeasurments() const {
    313  if (mode_ == Mode::kSlowStart) {
    314    return false;
    315  }
    316  double first_loss_rate = monitor_intervals_[0].GetLossRate();
    317  double second_loss_rate = monitor_intervals_[1].GetLossRate();
    318  DataRate first_bitrate = monitor_intervals_[0].GetTargetSendingRate();
    319  DataRate second_bitrate = monitor_intervals_[1].GetTargetSendingRate();
    320  if ((first_bitrate.bps() - second_bitrate.bps()) *
    321          (first_loss_rate - second_loss_rate) <
    322      0) {
    323    return true;
    324  }
    325  return false;
    326 }
    327 
    328 void PccNetworkController::UpdateSendingRateAndMode() {
    329  if (monitor_intervals_.empty() || !IsFeedbackCollectionDone()) {
    330    return;
    331  }
    332  if (mode_ == Mode::kSlowStart) {
    333    DataRate old_bandwidth_estimate = bandwidth_estimate_;
    334    bandwidth_estimate_ =
    335        bitrate_controller_
    336            .ComputeRateUpdateForSlowStartMode(monitor_intervals_[0])
    337            .value_or(bandwidth_estimate_);
    338    if (bandwidth_estimate_ <= old_bandwidth_estimate)
    339      mode_ = Mode::kOnlineLearning;
    340  } else {
    341    RTC_DCHECK(mode_ == Mode::kOnlineLearning);
    342    bandwidth_estimate_ =
    343        bitrate_controller_.ComputeRateUpdateForOnlineLearningMode(
    344            monitor_intervals_, bandwidth_estimate_);
    345  }
    346 }
    347 
    348 NetworkControlUpdate PccNetworkController::OnNetworkAvailability(
    349    NetworkAvailability /* msg */) {
    350  return NetworkControlUpdate();
    351 }
    352 
    353 NetworkControlUpdate PccNetworkController::OnNetworkRouteChange(
    354    NetworkRouteChange /* msg */) {
    355  return NetworkControlUpdate();
    356 }
    357 
    358 NetworkControlUpdate PccNetworkController::OnProcessInterval(
    359    ProcessInterval msg) {
    360  return CreateRateUpdate(msg.at_time);
    361 }
    362 
    363 NetworkControlUpdate PccNetworkController::OnTargetRateConstraints(
    364    TargetRateConstraints /* msg */) {
    365  return NetworkControlUpdate();
    366 }
    367 
    368 NetworkControlUpdate PccNetworkController::OnRemoteBitrateReport(
    369    RemoteBitrateReport) {
    370  return NetworkControlUpdate();
    371 }
    372 
    373 NetworkControlUpdate PccNetworkController::OnRoundTripTimeUpdate(
    374    RoundTripTimeUpdate) {
    375  return NetworkControlUpdate();
    376 }
    377 
    378 NetworkControlUpdate PccNetworkController::OnTransportLossReport(
    379    TransportLossReport) {
    380  return NetworkControlUpdate();
    381 }
    382 
    383 NetworkControlUpdate PccNetworkController::OnStreamsConfig(
    384    StreamsConfig /* msg */) {
    385  return NetworkControlUpdate();
    386 }
    387 
    388 NetworkControlUpdate PccNetworkController::OnReceivedPacket(
    389    ReceivedPacket /* msg */) {
    390  return NetworkControlUpdate();
    391 }
    392 
    393 NetworkControlUpdate PccNetworkController::OnNetworkStateEstimate(
    394    NetworkStateEstimate /* msg */) {
    395  return NetworkControlUpdate();
    396 }
    397 
    398 }  // namespace pcc
    399 }  // namespace webrtc