WebRTC Congestion Control classes

Table of Contents

Module remote_bitrate_estimator

class RemoteEstimatorProxy

It is used when send-side BWE is enabled: This proxy is instantiated on the receive side.

It buffers a number of receive timestamps and then sends transport feedback messages back too the send side.

class AimdRateControl

A rate control implementation based on additive increases of bitrate when no over-use is detected and multiplicative decreases when over-uses are detected.

When we think the available bandwidth has changes or is unknown, we will switch to a "slow-start mode" where we increase multiplicatively.

class InterArrival

It is Helper class to compute the inter-arrival time delta and the size delta between two timestamp groups. A timestamp is a 32 bit unsigned number with a client defined rate.

class OveruseDetector

  • main method
// Update the detection state based on the estimated inter-arrival time delta
// offset. `timestamp_delta` is the delta between the last timestamp which the
// estimated offset is based on and the last timestamp on which the last
// offset was based on, representing the time between detector updates.
// `num_of_deltas` is the number of deltas the offset estimate is based on.
// Returns the state after the detection update.
BandwidthUsage Detect(double offset,
                        double timestamp_delta,
                        int num_of_deltas,
                        int64_t now_ms);

Module congestion_controller

rtp module

CongestionControlHandler

This is used to observe the network controller state and route calls to the proper handler.

It also keeps cached values for safe asynchronous use.

This makes sure that things running on the worker queue can't access state in RtpTransportControllerSend, which would risk causing data race on destruction unless members are properly ordered.


struct NetworkEstimate {
  Timestamp at_time = Timestamp::PlusInfinity();
  // Deprecated, use TargetTransferRate::target_rate instead.
  DataRate bandwidth = DataRate::Infinity();
  TimeDelta round_trip_time = TimeDelta::PlusInfinity();
  TimeDelta bwe_period = TimeDelta::PlusInfinity();

  float loss_rate_ratio = 0;
};

struct TargetTransferRate {
  Timestamp at_time = Timestamp::PlusInfinity();
  // The estimate on which the target rate is based on.
  NetworkEstimate network_estimate;
  DataRate target_rate = DataRate::Zero();
  DataRate stable_target_rate = DataRate::Zero();
  double cwnd_reduce_ratio = 0;
};

class CongestionControlHandler {
 public:
  CongestionControlHandler();
  ~CongestionControlHandler();

  CongestionControlHandler(const CongestionControlHandler&) = delete;
  CongestionControlHandler& operator=(const CongestionControlHandler&) = delete;

  void SetTargetRate(TargetTransferRate new_target_rate);
  void SetNetworkAvailability(bool network_available);
  void SetPacerQueue(TimeDelta expected_queue_time);
  absl::optional<TargetTransferRate> GetUpdate();
  //...
}

TransportFeedbackAdapter

It is from RTCP message to struct TransportPacketsFeedback

  • RTCP message class
class TransportFeedback : public Rtpfb {
//...
};
  • TransportPacketsFeedback

    struct TransportPacketsFeedback {
    TransportPacketsFeedback();
    TransportPacketsFeedback(const TransportPacketsFeedback& other);
    ~TransportPacketsFeedback();
    
    Timestamp feedback_time = Timestamp::PlusInfinity();
    Timestamp first_unacked_send_time = Timestamp::PlusInfinity();
    DataSize data_in_flight = DataSize::Zero();
    DataSize prior_in_flight = DataSize::Zero();
    std::vector<PacketResult> packet_feedbacks;
    
    // Arrival times for messages without send time information.
    std::vector<Timestamp> sendless_arrival_times;
    
    std::vector<PacketResult> ReceivedWithSendInfo() const;
    std::vector<PacketResult> LostWithSendInfo() const;
    std::vector<PacketResult> PacketsWithFeedback() const;
    std::vector<PacketResult> SortedByReceiveTime() const;
    };
  • main methods

  void AddPacket(const RtpPacketSendInfo& packet_info,
                 size_t overhead_bytes,
                 Timestamp creation_time);

  absl::optional<SentPacket> ProcessSentPacket(const rtc::SentPacket& sent_packet);

  absl::optional<TransportPacketsFeedback> ProcessTransportFeedback(
      const rtcp::TransportFeedback& feedback,
      Timestamp feedback_receive_time);

  void SetNetworkRoute(const rtc::NetworkRoute& network_route);

  DataSize GetOutstandingData() const;

TransportFeedbackDemuxer

Implementation of StreamFeedbackProvider that provides a way for implementations of StreamFeedbackObserver to register for feedback callbacks for a given set of SSRCs.
Registration methods need to be called from the same execution context (thread or task queue) and callbacks to StreamFeedbackObserver::OnPacketFeedbackVector will be made in that same context.

StreamFeedbackProvider 的实现,它为 StreamFeedbackObserver 的实现提供了一种方法,用于注册一组给定 SSRC 的反馈回调。
注册方法需要从相同的执行上下文(线程或任务队列)调用,并且将在同一上下文中对StreamFeedbackObserver::OnPacketFeedbackVector进行回调。


class StreamFeedbackObserver {
 public:
  struct StreamPacketInfo {
    bool received;

    // `rtp_sequence_number` and `is_retransmission` are only valid if `ssrc`
    // is populated.
    absl::optional<uint32_t> ssrc;
    uint16_t rtp_sequence_number;
    bool is_retransmission;
  };
  virtual ~StreamFeedbackObserver() = default;

  virtual void OnPacketFeedbackVector(
      std::vector<StreamPacketInfo> packet_feedback_vector) = 0;
};

class StreamFeedbackProvider {
 public:
  virtual void RegisterStreamFeedbackObserver(
      std::vector<uint32_t> ssrcs,
      StreamFeedbackObserver* observer) = 0;
  virtual void DeRegisterStreamFeedbackObserver(
      StreamFeedbackObserver* observer) = 0;
  virtual ~StreamFeedbackProvider() = default;
};

gcc module

class InterArrivalDelta

It is Helper class to compute the inter-arrival time delta and the size delta
between two send bursts.
This code is branched from modules/remote_bitrate_estimator/inter_arrival.

SendSideBandwidthEstimation

AlrDetector

Application limited region detector is a class that utilizes signals of elapsed time and bytes sent to estimate whether network traffic is currently limited by the application's ability to generate traffic.

AlrDetector provides a signal that can be utilized to adjust estimate bandwidth.

Note: This class is not thread-safe.

  • config:
struct AlrDetectorConfig {
  // Sent traffic ratio as a function of network capacity used to determine
  // application-limited region. ALR region start when bandwidth usage drops
  // below kAlrStartUsageRatio and ends when it raises above
  // kAlrEndUsageRatio. NOTE: This is intentionally conservative at the moment
  // until BW adjustments of application limited region is fine tuned.
  double bandwidth_usage_ratio = 0.65;
  double start_budget_level_ratio = 0.80;
  double stop_budget_level_ratio = 0.50;
  std::unique_ptr<StructParametersParser> Parser();
};

class ProbeController

This class controls initiation of probing to estimate initial channel capacity. There is also support for probing during a session when max bitrate is adjusted by an application.

ProbeBitrateEstimator

  • main method HandleProbeAndEstimateBitrate
  // Should be called for every probe packet we receive feedback about.
  // Returns the estimated bitrate if the probe completes a valid cluster.
  absl::optional<DataRate> HandleProbeAndEstimateBitrate(
      const PacketResult& packet_feedback);

DelayBasedBwe

这个类的主要方法就是


  Result IncomingPacketFeedbackVector(
      const TransportPacketsFeedback& msg,
      absl::optional<DataRate> acked_bitrate,
      absl::optional<DataRate> probe_bitrate,
      absl::optional<NetworkStateEstimate> network_estimate,
      bool in_alr);

其结果类型为

  struct Result {
    Result();
    ~Result() = default;
    bool updated;
    bool probe;
    DataRate target_bitrate = DataRate::Zero();
    bool recovered_from_overuse;
    bool backoff_in_alr;
  };

AcknowledgedBitrateEstimator

According to the below setting , use class BitrateEstimator to estimate throughput

  • setting

struct RobustThroughputEstimatorSettings {
  static constexpr char kKey[] = "WebRTC-Bwe-RobustThroughputEstimatorSettings";
  static constexpr size_t kMaxPackets = 500;

  RobustThroughputEstimatorSettings() = delete;
  explicit RobustThroughputEstimatorSettings(
      const WebRtcKeyValueConfig* key_value_config);

  bool enabled = false;  // Set to true to use RobustThroughputEstimator.

  // The estimator handles delay spikes by removing the largest receive time
  // gap, but this introduces some bias that may lead to overestimation when
  // there isn't any delay spike. If `reduce_bias` is true, we instead replace
  // the largest receive time gap by the second largest. This reduces the bias
  // at the cost of not completely removing the genuine delay spikes.
  bool reduce_bias = true;

  // If `assume_shared_link` is false, we ignore the size of the first packet
  // when computing the receive rate. Otherwise, we remove half of the first
  // and last packet's sizes.
  bool assume_shared_link = false;

  // The estimator window keeps at least `min_packets` packets and up to
  // kMaxPackets received during the last `window_duration`.
  unsigned min_packets = 20;
  TimeDelta window_duration = TimeDelta::Millis(500);

  // The estimator window requires at least `initial_packets` packets received
  // over at least `initial_duration`.
  unsigned initial_packets = 20;

  // If audio packets are included in allocation, but not in bandwidth
  // estimation and the sent audio packets get double counted,
  // then it might be useful to reduce the weight to 0.5.
  double unacked_weight = 1.0;

  std::unique_ptr<StructParametersParser> Parser();
};

class BitrateEstimator

Computes a bayesian estimate of the throughput given acks containing the arrival time and payload size.

Samples which are far from the current estimate or are based on few packets are given a smaller weight, as they are considered to be more likely to have been caused by, e.g., delay spikes unrelated to congestion.

计算给定的确认的吞吐量的贝叶斯估计值,其中包含到达时间和有效负载大小。

与当前估计值相差甚远或基于少量数据包的样本权重较小,因为它们被认为更有可能是由与拥塞无关的延迟峰值引起的。

将样本不确定性定义为它与当前估计值之间的距离的函数。对于较低的uncertainty_symmetrycap,我们增加的不确定性大于减少的不确定性。对于更高的值,我们接近对称性。

void BitrateEstimator::Update(int64_t now_ms, int bytes) {
  int rate_window_ms = noninitial_window_ms_.Get();
  // We use a larger window at the beginning to get a more stable sample that
  // we can use to initialize the estimate.
  if (bitrate_estimate_kbps_ < 0.f)
    rate_window_ms = initial_window_ms_.Get();
  float bitrate_sample_kbps = UpdateWindow(now_ms, bytes, rate_window_ms);
  if (bitrate_sample_kbps < 0.0f)
    return;
  if (bitrate_estimate_kbps_ < 0.0f) {
    // This is the very first sample we get. Use it to initialize the estimate.
    bitrate_estimate_kbps_ = bitrate_sample_kbps;
    return;
  }
  // Define the sample uncertainty as a function of how far away it is from the
  // current estimate. With low values of uncertainty_symmetry_cap_ we add more
  // uncertainty to increases than to decreases. For higher values we approach
  // symmetry.
  float sample_uncertainty =
      uncertainty_scale_ *
      std::abs(bitrate_estimate_kbps_ - bitrate_sample_kbps) /
      (bitrate_estimate_kbps_ +
       std::min(bitrate_sample_kbps,
                uncertainty_symmetry_cap_.Get().kbps<float>()));

  float sample_var = sample_uncertainty * sample_uncertainty;
  // Update a bayesian estimate of the rate, weighting it lower if the sample
  // uncertainty is large.
  // The bitrate estimate uncertainty is increased with each update to model
  // that the bitrate changes over time.
  float pred_bitrate_estimate_var = bitrate_estimate_var_ + 5.f;
  bitrate_estimate_kbps_ = (sample_var * bitrate_estimate_kbps_ +
                            pred_bitrate_estimate_var * bitrate_sample_kbps) /
                           (sample_var + pred_bitrate_estimate_var);
  bitrate_estimate_kbps_ =
      std::max(bitrate_estimate_kbps_, estimate_floor_.Get().kbps<float>());
  bitrate_estimate_var_ = sample_var * pred_bitrate_estimate_var /
                          (sample_var + pred_bitrate_estimate_var);
  BWE_TEST_LOGGING_PLOT(1, "acknowledged_bitrate", now_ms,
                        bitrate_estimate_kbps_ * 1000);
}

CongestionWindowPushbackController

This class enables pushback from congestion window directly to video encoder.
When the congestion window is filling up, the video encoder target bitrate will be reduced accordingly to accommodate the network changes. To avoid pausing video too frequently, a minimum encoder target bitrate threshold is used to prevent video pause due to a full congestion window.

此类支持从拥塞窗口直接推送到视频编码器。 当拥塞窗口被填满时,视频编码器目标比特率将相应降低以适应网络变化。 为了避免过于频繁地暂停视频,使用最小编码器目标比特率阈值来防止视频由于完全拥塞窗口而暂停。

Comments |0|

Legend *) Required fields are marked
**) You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Category: WebRTC