tor-browser

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

delay_based_bwe.cc (12256B)


      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 "modules/congestion_controller/goog_cc/delay_based_bwe.h"
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <optional>
     17 #include <utility>
     18 #include <vector>
     19 
     20 #include "api/field_trials_view.h"
     21 #include "api/network_state_predictor.h"
     22 #include "api/rtc_event_log/rtc_event_log.h"
     23 #include "api/transport/bandwidth_usage.h"
     24 #include "api/transport/network_types.h"
     25 #include "api/units/data_rate.h"
     26 #include "api/units/data_size.h"
     27 #include "api/units/time_delta.h"
     28 #include "api/units/timestamp.h"
     29 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
     30 #include "modules/congestion_controller/goog_cc/delay_increase_detector_interface.h"
     31 #include "modules/congestion_controller/goog_cc/inter_arrival_delta.h"
     32 #include "modules/congestion_controller/goog_cc/trendline_estimator.h"
     33 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
     34 #include "rtc_base/checks.h"
     35 #include "rtc_base/experiments/struct_parameters_parser.h"
     36 #include "rtc_base/logging.h"
     37 #include "rtc_base/race_checker.h"
     38 #include "system_wrappers/include/metrics.h"
     39 
     40 namespace webrtc {
     41 namespace {
     42 constexpr TimeDelta kStreamTimeOut = TimeDelta::Seconds(2);
     43 constexpr TimeDelta kSendTimeGroupLength = TimeDelta::Millis(5);
     44 
     45 // This ssrc is used to fulfill the current API but will be removed
     46 // after the API has been changed.
     47 constexpr uint32_t kFixedSsrc = 0;
     48 }  // namespace
     49 
     50 BweSeparateAudioPacketsSettings::BweSeparateAudioPacketsSettings(
     51    const FieldTrialsView* key_value_config) {
     52  Parser()->Parse(
     53      key_value_config->Lookup(BweSeparateAudioPacketsSettings::kKey));
     54 }
     55 
     56 std::unique_ptr<StructParametersParser>
     57 BweSeparateAudioPacketsSettings::Parser() {
     58  return StructParametersParser::Create(      //
     59      "enabled", &enabled,                    //
     60      "packet_threshold", &packet_threshold,  //
     61      "time_threshold", &time_threshold);
     62 }
     63 
     64 DelayBasedBwe::Result::Result()
     65    : updated(false),
     66      probe(false),
     67      target_bitrate(DataRate::Zero()),
     68      recovered_from_overuse(false),
     69      delay_detector_state(BandwidthUsage::kBwNormal) {}
     70 
     71 DelayBasedBwe::DelayBasedBwe(const FieldTrialsView* key_value_config,
     72                             RtcEventLog* event_log,
     73                             NetworkStatePredictor* network_state_predictor)
     74    : event_log_(event_log),
     75      key_value_config_(key_value_config),
     76      separate_audio_(key_value_config),
     77      audio_packets_since_last_video_(0),
     78      last_video_packet_recv_time_(Timestamp::MinusInfinity()),
     79      network_state_predictor_(network_state_predictor),
     80      video_delay_detector_(
     81          new TrendlineEstimator(*key_value_config_, network_state_predictor_)),
     82      audio_delay_detector_(
     83          new TrendlineEstimator(*key_value_config_, network_state_predictor_)),
     84      active_delay_detector_(video_delay_detector_.get()),
     85      last_seen_packet_(Timestamp::MinusInfinity()),
     86      uma_recorded_(false),
     87      rate_control_(*key_value_config, /*send_side=*/true),
     88      prev_bitrate_(DataRate::Zero()),
     89      prev_state_(BandwidthUsage::kBwNormal) {
     90  RTC_LOG(LS_INFO)
     91      << "Initialized DelayBasedBwe with separate audio overuse detection"
     92      << separate_audio_.Parser()->Encode();
     93 }
     94 
     95 DelayBasedBwe::~DelayBasedBwe() {}
     96 
     97 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
     98    const TransportPacketsFeedback& msg,
     99    std::optional<DataRate> acked_bitrate,
    100    std::optional<DataRate> probe_bitrate,
    101    std::optional<NetworkStateEstimate> network_estimate,
    102    bool in_alr) {
    103  RTC_DCHECK_RUNS_SERIALIZED(&network_race_);
    104 
    105  auto packet_feedback_vector = msg.SortedByReceiveTime();
    106  // TODO(holmer): An empty feedback vector here likely means that
    107  // all acks were too late and that the send time history had
    108  // timed out. We should reduce the rate when this occurs.
    109  if (packet_feedback_vector.empty()) {
    110    RTC_LOG(LS_WARNING) << "Very late feedback received.";
    111    return DelayBasedBwe::Result();
    112  }
    113 
    114  if (!uma_recorded_) {
    115    RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
    116                              BweNames::kSendSideTransportSeqNum,
    117                              BweNames::kBweNamesMax);
    118    uma_recorded_ = true;
    119  }
    120  bool delayed_feedback = true;
    121  bool recovered_from_overuse = false;
    122  BandwidthUsage prev_detector_state = active_delay_detector_->State();
    123  for (const auto& packet_feedback : packet_feedback_vector) {
    124    delayed_feedback = false;
    125    IncomingPacketFeedback(packet_feedback, msg.feedback_time);
    126    if (prev_detector_state == BandwidthUsage::kBwUnderusing &&
    127        active_delay_detector_->State() == BandwidthUsage::kBwNormal) {
    128      recovered_from_overuse = true;
    129    }
    130    prev_detector_state = active_delay_detector_->State();
    131  }
    132 
    133  if (delayed_feedback) {
    134    // TODO(bugs.webrtc.org/10125): Design a better mechanism to safe-guard
    135    // against building very large network queues.
    136    return Result();
    137  }
    138  rate_control_.SetInApplicationLimitedRegion(in_alr);
    139  rate_control_.SetNetworkStateEstimate(network_estimate);
    140  return MaybeUpdateEstimate(acked_bitrate, probe_bitrate,
    141                             std::move(network_estimate),
    142                             recovered_from_overuse, in_alr, msg.feedback_time);
    143 }
    144 
    145 void DelayBasedBwe::IncomingPacketFeedback(const PacketResult& packet_feedback,
    146                                           Timestamp at_time) {
    147  // Reset if the stream has timed out.
    148  if (last_seen_packet_.IsInfinite() ||
    149      at_time - last_seen_packet_ > kStreamTimeOut) {
    150    video_inter_arrival_delta_ =
    151        std::make_unique<InterArrivalDelta>(kSendTimeGroupLength);
    152    audio_inter_arrival_delta_ =
    153        std::make_unique<InterArrivalDelta>(kSendTimeGroupLength);
    154 
    155    video_delay_detector_.reset(
    156        new TrendlineEstimator(*key_value_config_, network_state_predictor_));
    157    audio_delay_detector_.reset(
    158        new TrendlineEstimator(*key_value_config_, network_state_predictor_));
    159    active_delay_detector_ = video_delay_detector_.get();
    160  }
    161  last_seen_packet_ = at_time;
    162 
    163  // As an alternative to ignoring small packets, we can separate audio and
    164  // video packets for overuse detection.
    165  DelayIncreaseDetectorInterface* delay_detector_for_packet =
    166      video_delay_detector_.get();
    167  if (separate_audio_.enabled) {
    168    if (packet_feedback.sent_packet.audio) {
    169      delay_detector_for_packet = audio_delay_detector_.get();
    170      audio_packets_since_last_video_++;
    171      if (audio_packets_since_last_video_ > separate_audio_.packet_threshold &&
    172          packet_feedback.receive_time - last_video_packet_recv_time_ >
    173              separate_audio_.time_threshold) {
    174        active_delay_detector_ = audio_delay_detector_.get();
    175      }
    176    } else {
    177      audio_packets_since_last_video_ = 0;
    178      last_video_packet_recv_time_ =
    179          std::max(last_video_packet_recv_time_, packet_feedback.receive_time);
    180      active_delay_detector_ = video_delay_detector_.get();
    181    }
    182  }
    183  DataSize packet_size = packet_feedback.sent_packet.size;
    184 
    185  TimeDelta send_delta = TimeDelta::Zero();
    186  TimeDelta recv_delta = TimeDelta::Zero();
    187  int size_delta = 0;
    188 
    189  InterArrivalDelta* inter_arrival_for_packet =
    190      (separate_audio_.enabled && packet_feedback.sent_packet.audio)
    191          ? audio_inter_arrival_delta_.get()
    192          : video_inter_arrival_delta_.get();
    193  bool calculated_deltas = inter_arrival_for_packet->ComputeDeltas(
    194      packet_feedback.sent_packet.send_time, packet_feedback.receive_time,
    195      at_time, packet_size.bytes(), &send_delta, &recv_delta, &size_delta);
    196 
    197  delay_detector_for_packet->Update(recv_delta.ms<double>(),
    198                                    send_delta.ms<double>(),
    199                                    packet_feedback.sent_packet.send_time.ms(),
    200                                    packet_feedback.receive_time.ms(),
    201                                    packet_size.bytes(), calculated_deltas);
    202 }
    203 
    204 DataRate DelayBasedBwe::TriggerOveruse(Timestamp at_time,
    205                                       std::optional<DataRate> link_capacity) {
    206  RateControlInput input(BandwidthUsage::kBwOverusing, link_capacity);
    207  return rate_control_.Update(input, at_time);
    208 }
    209 
    210 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
    211    std::optional<DataRate> acked_bitrate,
    212    std::optional<DataRate> probe_bitrate,
    213    std::optional<NetworkStateEstimate> /* state_estimate */,
    214    bool recovered_from_overuse,
    215    bool /* in_alr */,
    216    Timestamp at_time) {
    217  Result result;
    218 
    219  // Currently overusing the bandwidth.
    220  if (active_delay_detector_->State() == BandwidthUsage::kBwOverusing) {
    221    if (acked_bitrate &&
    222        rate_control_.TimeToReduceFurther(at_time, *acked_bitrate)) {
    223      result.updated =
    224          UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate);
    225    } else if (!acked_bitrate && rate_control_.ValidEstimate() &&
    226               rate_control_.InitialTimeToReduceFurther(at_time)) {
    227      // Overusing before we have a measured acknowledged bitrate. Reduce send
    228      // rate by 50% every 200 ms.
    229      // TODO(tschumim): Improve this and/or the acknowledged bitrate estimator
    230      // so that we (almost) always have a bitrate estimate.
    231      rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, at_time);
    232      result.updated = true;
    233      result.probe = false;
    234      result.target_bitrate = rate_control_.LatestEstimate();
    235    }
    236  } else {
    237    if (probe_bitrate) {
    238      result.probe = true;
    239      result.updated = true;
    240      rate_control_.SetEstimate(*probe_bitrate, at_time);
    241      result.target_bitrate = rate_control_.LatestEstimate();
    242    } else {
    243      result.updated =
    244          UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate);
    245      result.recovered_from_overuse = recovered_from_overuse;
    246    }
    247  }
    248  BandwidthUsage detector_state = active_delay_detector_->State();
    249  if ((result.updated && prev_bitrate_ != result.target_bitrate) ||
    250      detector_state != prev_state_) {
    251    DataRate bitrate = result.updated ? result.target_bitrate : prev_bitrate_;
    252 
    253    if (event_log_) {
    254      event_log_->Log(std::make_unique<RtcEventBweUpdateDelayBased>(
    255          bitrate.bps(), detector_state));
    256    }
    257 
    258    prev_bitrate_ = bitrate;
    259    prev_state_ = detector_state;
    260  }
    261 
    262  result.delay_detector_state = detector_state;
    263  return result;
    264 }
    265 
    266 bool DelayBasedBwe::UpdateEstimate(Timestamp at_time,
    267                                   std::optional<DataRate> acked_bitrate,
    268                                   DataRate* target_rate) {
    269  const RateControlInput input(active_delay_detector_->State(), acked_bitrate);
    270  *target_rate = rate_control_.Update(input, at_time);
    271  return rate_control_.ValidEstimate();
    272 }
    273 
    274 void DelayBasedBwe::OnRttUpdate(TimeDelta avg_rtt) {
    275  rate_control_.SetRtt(avg_rtt);
    276 }
    277 
    278 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
    279                                   DataRate* bitrate) const {
    280  // Currently accessed from both the process thread (see
    281  // ModuleRtpRtcpImpl::Process()) and the configuration thread (see
    282  // Call::GetStats()). Should in the future only be accessed from a single
    283  // thread.
    284  RTC_DCHECK(ssrcs);
    285  RTC_DCHECK(bitrate);
    286  if (!rate_control_.ValidEstimate())
    287    return false;
    288 
    289  *ssrcs = {kFixedSsrc};
    290  *bitrate = rate_control_.LatestEstimate();
    291  return true;
    292 }
    293 
    294 void DelayBasedBwe::SetStartBitrate(DataRate start_bitrate) {
    295  RTC_LOG(LS_INFO) << "BWE Setting start bitrate to: "
    296                   << ToString(start_bitrate);
    297  rate_control_.SetStartBitrate(start_bitrate);
    298 }
    299 
    300 void DelayBasedBwe::SetMinBitrate(DataRate min_bitrate) {
    301  // Called from both the configuration thread and the network thread. Shouldn't
    302  // be called from the network thread in the future.
    303  rate_control_.SetMinBitrate(min_bitrate);
    304 }
    305 
    306 TimeDelta DelayBasedBwe::GetExpectedBwePeriod() const {
    307  return rate_control_.GetExpectedBandwidthPeriod();
    308 }
    309 
    310 }  // namespace webrtc