text: /*
   *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
   *
   *  Use of this source code is governed by a BSD-style license
   *  that can be found in the LICENSE file in the root of the source
   *  tree. An additional intellectual property rights grant can be found
   *  in the file PATENTS.  All contributing project authors may
   *  be found in the AUTHORS file in the root of the source tree.
   */
  
  #include "modules/congestion_controller/include/receive_side_congestion_controller.h"
  
  #include "modules/pacing/packet_router.h"
  #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
  #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
  #include BOSS_WEBRTC_U_rtc_base__logging_h //original-code:"rtc_base/logging.h"
  
  namespace webrtc {
  
  namespace {
  static const uint32_t kTimeOffsetSwitchThreshold = 30;
  }  // namespace
  
  ReceiveSideCongestionController::WrappingBitrateEstimator::
      WrappingBitrateEstimator(RemoteBitrateObserver* observer,
                               const Clock* clock)
      : observer_(observer),
        clock_(clock),
        rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)),
        using_absolute_send_time_(false),
        packets_since_absolute_send_time_(0),
        min_bitrate_bps_(congestion_controller::GetMinBitrateBps()) {}
  
  void ReceiveSideCongestionController::WrappingBitrateEstimator::IncomingPacket(
      int64_t arrival_time_ms,
      size_t payload_size,
      const RTPHeader& header) {
    rtc::CritScope cs(&crit_sect_);
    PickEstimatorFromHeader(header);
    rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
  }
  
  void ReceiveSideCongestionController::WrappingBitrateEstimator::Process() {
    rtc::CritScope cs(&crit_sect_);
    rbe_->Process();
  }
  
  int64_t ReceiveSideCongestionController::WrappingBitrateEstimator::
      TimeUntilNextProcess() {
    rtc::CritScope cs(&crit_sect_);
    return rbe_->TimeUntilNextProcess();
  }
  
  void ReceiveSideCongestionController::WrappingBitrateEstimator::OnRttUpdate(
      int64_t avg_rtt_ms,
      int64_t max_rtt_ms) {
    rtc::CritScope cs(&crit_sect_);
    rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
  }
  
  void ReceiveSideCongestionController::WrappingBitrateEstimator::RemoveStream(
      unsigned int ssrc) {
    rtc::CritScope cs(&crit_sect_);
    rbe_->RemoveStream(ssrc);
  }
  
  bool ReceiveSideCongestionController::WrappingBitrateEstimator::LatestEstimate(
      std::vector<unsigned int>* ssrcs,
      unsigned int* bitrate_bps) const {
    rtc::CritScope cs(&crit_sect_);
    return rbe_->LatestEstimate(ssrcs, bitrate_bps);
  }
  
  void ReceiveSideCongestionController::WrappingBitrateEstimator::SetMinBitrate(
      int min_bitrate_bps) {
    rtc::CritScope cs(&crit_sect_);
    rbe_->SetMinBitrate(min_bitrate_bps);
    min_bitrate_bps_ = min_bitrate_bps;
  }
  
  void ReceiveSideCongestionController::WrappingBitrateEstimator::
      PickEstimatorFromHeader(const RTPHeader& header) {
    if (header.extension.hasAbsoluteSendTime) {
      // If we see AST in header, switch RBE strategy immediately.
      if (!using_absolute_send_time_) {
        RTC_LOG(LS_INFO)
            << "WrappingBitrateEstimator: Switching to absolute send time RBE.";
        using_absolute_send_time_ = true;
        PickEstimator();
      }
      packets_since_absolute_send_time_ = 0;
    } else {
      // When we don't see AST, wait for a few packets before going back to TOF.
      if (using_absolute_send_time_) {
        ++packets_since_absolute_send_time_;
        if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
          RTC_LOG(LS_INFO)
              << "WrappingBitrateEstimator: Switching to transmission "
              << "time offset RBE.";
          using_absolute_send_time_ = false;
          PickEstimator();
        }
      }
    }
  }
  
  // Instantiate RBE for Time Offset or Absolute Send Time extensions.
  void ReceiveSideCongestionController::WrappingBitrateEstimator::
      PickEstimator() {
    if (using_absolute_send_time_) {
      rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_));
    } else {
      rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_));
    }
    rbe_->SetMinBitrate(min_bitrate_bps_);
  }
  
  ReceiveSideCongestionController::ReceiveSideCongestionController(
      const Clock* clock,
      PacketRouter* packet_router)
      : remote_bitrate_estimator_(packet_router, clock),
        remote_estimator_proxy_(clock, packet_router) {}
  
  void ReceiveSideCongestionController::OnReceivedPacket(
      int64_t arrival_time_ms,
      size_t payload_size,
      const RTPHeader& header) {
    // Send-side BWE.
    if (header.extension.hasTransportSequenceNumber) {
      remote_estimator_proxy_.IncomingPacket(arrival_time_ms, payload_size,
                                             header);
    } else {
      // Receive-side BWE.
      remote_bitrate_estimator_.IncomingPacket(arrival_time_ms, payload_size,
                                               header);
    }
  }
  
  RemoteBitrateEstimator*
  ReceiveSideCongestionController::GetRemoteBitrateEstimator(bool send_side_bwe) {
    if (send_side_bwe) {
      return &remote_estimator_proxy_;
    } else {
      return &remote_bitrate_estimator_;
    }
  }
  
  const RemoteBitrateEstimator*
  ReceiveSideCongestionController::GetRemoteBitrateEstimator(
      bool send_side_bwe) const {
    if (send_side_bwe) {
      return &remote_estimator_proxy_;
    } else {
      return &remote_bitrate_estimator_;
    }
  }
  
  void ReceiveSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
                                                    int64_t max_rtt_ms) {
    remote_bitrate_estimator_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
  }
  
  void ReceiveSideCongestionController::OnBitrateChanged(int bitrate_bps) {
    remote_estimator_proxy_.OnBitrateChanged(bitrate_bps);
  }
  
  int64_t ReceiveSideCongestionController::TimeUntilNextProcess() {
    return remote_bitrate_estimator_.TimeUntilNextProcess();
  }
  
  void ReceiveSideCongestionController::Process() {
    remote_bitrate_estimator_.Process();
  }
  
  }  // namespace webrtc
  