tor-browser

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

receive_side_congestion_controller.cc (6968B)


      1 /*
      2 *  Copyright (c) 2017 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/include/receive_side_congestion_controller.h"
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <utility>
     17 
     18 #include "api/environment/environment.h"
     19 #include "api/media_types.h"
     20 #include "api/sequence_checker.h"
     21 #include "api/units/data_rate.h"
     22 #include "api/units/time_delta.h"
     23 #include "api/units/timestamp.h"
     24 #include "modules/congestion_controller/remb_throttler.h"
     25 #include "modules/remote_bitrate_estimator/congestion_control_feedback_generator.h"
     26 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
     27 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
     28 #include "modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.h"
     29 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
     30 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     31 #include "rtc_base/experiments/field_trial_parser.h"
     32 #include "rtc_base/logging.h"
     33 #include "rtc_base/synchronization/mutex.h"
     34 
     35 namespace webrtc {
     36 
     37 namespace {
     38 const uint32_t kTimeOffsetSwitchThreshold = 30;
     39 }  // namespace
     40 
     41 void ReceiveSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
     42                                                  int64_t max_rtt_ms) {
     43  MutexLock lock(&mutex_);
     44  rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
     45 }
     46 
     47 void ReceiveSideCongestionController::RemoveStream(uint32_t ssrc) {
     48  MutexLock lock(&mutex_);
     49  rbe_->RemoveStream(ssrc);
     50 }
     51 
     52 DataRate ReceiveSideCongestionController::LatestReceiveSideEstimate() const {
     53  MutexLock lock(&mutex_);
     54  return rbe_->LatestEstimate();
     55 }
     56 
     57 void ReceiveSideCongestionController::PickEstimator(
     58    bool has_absolute_send_time) {
     59  if (has_absolute_send_time) {
     60    // If we see AST in header, switch RBE strategy immediately.
     61    if (!using_absolute_send_time_) {
     62      RTC_LOG(LS_INFO)
     63          << "WrappingBitrateEstimator: Switching to absolute send time RBE.";
     64      using_absolute_send_time_ = true;
     65      rbe_ = std::make_unique<RemoteBitrateEstimatorAbsSendTime>(
     66          env_, &remb_throttler_);
     67    }
     68    packets_since_absolute_send_time_ = 0;
     69  } else {
     70    // When we don't see AST, wait for a few packets before going back to TOF.
     71    if (using_absolute_send_time_) {
     72      ++packets_since_absolute_send_time_;
     73      if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
     74        RTC_LOG(LS_INFO)
     75            << "WrappingBitrateEstimator: Switching to transmission "
     76               "time offset RBE.";
     77        using_absolute_send_time_ = false;
     78        rbe_ = std::make_unique<RemoteBitrateEstimatorSingleStream>(
     79            env_, &remb_throttler_);
     80      }
     81    }
     82  }
     83 }
     84 
     85 ReceiveSideCongestionController::ReceiveSideCongestionController(
     86    const Environment& env,
     87    TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender,
     88    RembThrottler::RembSender remb_sender)
     89    : env_(env),
     90      remb_throttler_(std::move(remb_sender), &env_.clock()),
     91      transport_sequence_number_feedback_generator_(feedback_sender),
     92      congestion_control_feedback_generator_(env, feedback_sender),
     93      rbe_(std::make_unique<RemoteBitrateEstimatorSingleStream>(
     94          env_,
     95          &remb_throttler_)),
     96      using_absolute_send_time_(false),
     97      packets_since_absolute_send_time_(0) {
     98  FieldTrialParameter<bool> force_send_rfc8888_feedback("force_send", false);
     99  ParseFieldTrial(
    100      {&force_send_rfc8888_feedback},
    101      env.field_trials().Lookup("WebRTC-RFC8888CongestionControlFeedback"));
    102  if (force_send_rfc8888_feedback) {
    103    EnableSendCongestionControlFeedbackAccordingToRfc8888();
    104  }
    105 }
    106 
    107 void ReceiveSideCongestionController::
    108    EnableSendCongestionControlFeedbackAccordingToRfc8888() {
    109  RTC_DCHECK_RUN_ON(&sequence_checker_);
    110  send_rfc8888_congestion_feedback_ = true;
    111 }
    112 
    113 void ReceiveSideCongestionController::OnReceivedPacket(
    114    const RtpPacketReceived& packet,
    115    MediaType media_type) {
    116  bool has_transport_sequence_number =
    117      packet.HasExtension<TransportSequenceNumber>() ||
    118      packet.HasExtension<TransportSequenceNumberV2>();
    119  if (send_rfc8888_congestion_feedback_) {
    120    RTC_DCHECK_RUN_ON(&sequence_checker_);
    121    congestion_control_feedback_generator_.OnReceivedPacket(packet);
    122    // TODO(https://bugs.webrtc.org/374197376): Utilize RFC 8888 feedback, which
    123    // provides comprehensive details similar to transport-cc. To ensure a
    124    // smooth transition, we will continue using transport sequence number
    125    // feedback temporarily. Once validation is complete, we will fully
    126    // transition to using RFC 8888 feedback exclusively.
    127    if (has_transport_sequence_number) {
    128      transport_sequence_number_feedback_generator_.OnReceivedPacket(packet);
    129    }
    130    return;
    131  }
    132  if (media_type == MediaType::AUDIO && !has_transport_sequence_number) {
    133    // For audio, we only support send side BWE.
    134    return;
    135  }
    136 
    137  if (has_transport_sequence_number) {
    138    // Send-side BWE.
    139    transport_sequence_number_feedback_generator_.OnReceivedPacket(packet);
    140  } else {
    141    // Receive-side BWE.
    142    MutexLock lock(&mutex_);
    143    PickEstimator(packet.HasExtension<AbsoluteSendTime>());
    144    rbe_->IncomingPacket(packet);
    145  }
    146 }
    147 
    148 void ReceiveSideCongestionController::OnBitrateChanged(int bitrate_bps) {
    149  RTC_DCHECK_RUN_ON(&sequence_checker_);
    150  DataRate send_bandwidth_estimate = DataRate::BitsPerSec(bitrate_bps);
    151  transport_sequence_number_feedback_generator_.OnSendBandwidthEstimateChanged(
    152      send_bandwidth_estimate);
    153  congestion_control_feedback_generator_.OnSendBandwidthEstimateChanged(
    154      send_bandwidth_estimate);
    155 }
    156 
    157 TimeDelta ReceiveSideCongestionController::MaybeProcess() {
    158  Timestamp now = env_.clock().CurrentTime();
    159  if (send_rfc8888_congestion_feedback_) {
    160    RTC_DCHECK_RUN_ON(&sequence_checker_);
    161    TimeDelta time_until_cc_rep =
    162        congestion_control_feedback_generator_.Process(now);
    163    TimeDelta time_until_rep =
    164        transport_sequence_number_feedback_generator_.Process(now);
    165    TimeDelta time_until = std::min(time_until_cc_rep, time_until_rep);
    166    return std::max(time_until, TimeDelta::Zero());
    167  }
    168  mutex_.Lock();
    169  TimeDelta time_until_rbe = rbe_->Process();
    170  mutex_.Unlock();
    171  TimeDelta time_until_rep =
    172      transport_sequence_number_feedback_generator_.Process(now);
    173  TimeDelta time_until = std::min(time_until_rbe, time_until_rep);
    174  return std::max(time_until, TimeDelta::Zero());
    175 }
    176 
    177 void ReceiveSideCongestionController::SetMaxDesiredReceiveBitrate(
    178    DataRate bitrate) {
    179  remb_throttler_.SetMaxDesiredReceiveBitrate(bitrate);
    180 }
    181 
    182 }  // namespace webrtc