summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h')
-rw-r--r--third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h214
1 files changed, 214 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
new file mode 100644
index 0000000000..425ca2a0c8
--- /dev/null
+++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#ifndef MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_
+#define MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_
+
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/field_trials_view.h"
+#include "api/transport/network_types.h"
+#include "api/units/data_rate.h"
+#include "api/units/data_size.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+
+namespace webrtc {
+
+// State of the loss based estimate, which can be either increasing/decreasing
+// when network is loss limited, or equal to the delay based estimate.
+enum class LossBasedState {
+ kIncreasing = 0,
+ // TODO(bugs.webrtc.org/12707): Remove one of the increasing states once we
+ // have decided if padding is usefull for ramping up when BWE is loss
+ // limited.
+ kIncreaseUsingPadding = 1,
+ kDecreasing = 2,
+ kDelayBasedEstimate = 3
+};
+
+class LossBasedBweV2 {
+ public:
+ struct Result {
+ ~Result() = default;
+ DataRate bandwidth_estimate = DataRate::Zero();
+ // State is used by goog_cc, which later sends probe requests to probe
+ // controller if state is kIncreasing.
+ LossBasedState state = LossBasedState::kDelayBasedEstimate;
+ };
+ // Creates a disabled `LossBasedBweV2` if the
+ // `key_value_config` is not valid.
+ explicit LossBasedBweV2(const FieldTrialsView* key_value_config);
+
+ LossBasedBweV2(const LossBasedBweV2&) = delete;
+ LossBasedBweV2& operator=(const LossBasedBweV2&) = delete;
+
+ ~LossBasedBweV2() = default;
+
+ bool IsEnabled() const;
+ // Returns true iff a BWE can be calculated, i.e., the estimator has been
+ // initialized with a BWE and then has received enough `PacketResult`s.
+ bool IsReady() const;
+
+ // Returns true if loss based BWE is ready to be used in the start phase.
+ bool ReadyToUseInStartPhase() const;
+
+ // Returns `DataRate::PlusInfinity` if no BWE can be calculated.
+ Result GetLossBasedResult() const;
+
+ void SetAcknowledgedBitrate(DataRate acknowledged_bitrate);
+ void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate);
+ void UpdateBandwidthEstimate(
+ rtc::ArrayView<const PacketResult> packet_results,
+ DataRate delay_based_estimate,
+ bool in_alr);
+
+ // For unit testing only.
+ void SetBandwidthEstimate(DataRate bandwidth_estimate);
+
+ private:
+ struct ChannelParameters {
+ double inherent_loss = 0.0;
+ DataRate loss_limited_bandwidth = DataRate::MinusInfinity();
+ };
+
+ struct Config {
+ double bandwidth_rampup_upper_bound_factor = 0.0;
+ double rampup_acceleration_max_factor = 0.0;
+ TimeDelta rampup_acceleration_maxout_time = TimeDelta::Zero();
+ std::vector<double> candidate_factors;
+ double higher_bandwidth_bias_factor = 0.0;
+ double higher_log_bandwidth_bias_factor = 0.0;
+ double inherent_loss_lower_bound = 0.0;
+ double loss_threshold_of_high_bandwidth_preference = 0.0;
+ double bandwidth_preference_smoothing_factor = 0.0;
+ DataRate inherent_loss_upper_bound_bandwidth_balance =
+ DataRate::MinusInfinity();
+ double inherent_loss_upper_bound_offset = 0.0;
+ double initial_inherent_loss_estimate = 0.0;
+ int newton_iterations = 0;
+ double newton_step_size = 0.0;
+ bool append_acknowledged_rate_candidate = true;
+ bool append_delay_based_estimate_candidate = false;
+ bool append_upper_bound_candidate_in_alr = false;
+ TimeDelta observation_duration_lower_bound = TimeDelta::Zero();
+ int observation_window_size = 0;
+ double sending_rate_smoothing_factor = 0.0;
+ double instant_upper_bound_temporal_weight_factor = 0.0;
+ DataRate instant_upper_bound_bandwidth_balance = DataRate::MinusInfinity();
+ double instant_upper_bound_loss_offset = 0.0;
+ double temporal_weight_factor = 0.0;
+ double bandwidth_backoff_lower_bound_factor = 0.0;
+ double max_increase_factor = 0.0;
+ TimeDelta delayed_increase_window = TimeDelta::Zero();
+ bool not_increase_if_inherent_loss_less_than_average_loss = false;
+ double high_loss_rate_threshold = 1.0;
+ DataRate bandwidth_cap_at_high_loss_rate = DataRate::MinusInfinity();
+ double slope_of_bwe_high_loss_func = 1000.0;
+ bool not_use_acked_rate_in_alr = false;
+ bool use_in_start_phase = false;
+ int min_num_observations = 0;
+ double lower_bound_by_acked_rate_factor = 0.0;
+ double hold_duration_factor = 0.0;
+ bool use_byte_loss_rate = false;
+ TimeDelta padding_duration = TimeDelta::Zero();
+ };
+
+ struct Derivatives {
+ double first = 0.0;
+ double second = 0.0;
+ };
+
+ struct Observation {
+ bool IsInitialized() const { return id != -1; }
+
+ int num_packets = 0;
+ int num_lost_packets = 0;
+ int num_received_packets = 0;
+ DataRate sending_rate = DataRate::MinusInfinity();
+ DataSize size = DataSize::Zero();
+ DataSize lost_size = DataSize::Zero();
+ int id = -1;
+ };
+
+ struct PartialObservation {
+ int num_packets = 0;
+ int num_lost_packets = 0;
+ DataSize size = DataSize::Zero();
+ DataSize lost_size = DataSize::Zero();
+ };
+
+ struct PaddingInfo {
+ DataRate padding_rate = DataRate::MinusInfinity();
+ Timestamp padding_timestamp = Timestamp::MinusInfinity();
+ };
+
+ static absl::optional<Config> CreateConfig(
+ const FieldTrialsView* key_value_config);
+ bool IsConfigValid() const;
+
+ // Returns `0.0` if not enough loss statistics have been received.
+ double GetAverageReportedLossRatio() const;
+ double GetAverageReportedPacketLossRatio() const;
+ double GetAverageReportedByteLossRatio() const;
+ std::vector<ChannelParameters> GetCandidates(bool in_alr) const;
+ DataRate GetCandidateBandwidthUpperBound() const;
+ Derivatives GetDerivatives(const ChannelParameters& channel_parameters) const;
+ double GetFeasibleInherentLoss(
+ const ChannelParameters& channel_parameters) const;
+ double GetInherentLossUpperBound(DataRate bandwidth) const;
+ double AdjustBiasFactor(double loss_rate, double bias_factor) const;
+ double GetHighBandwidthBias(DataRate bandwidth) const;
+ double GetObjective(const ChannelParameters& channel_parameters) const;
+ DataRate GetSendingRate(DataRate instantaneous_sending_rate) const;
+ DataRate GetInstantUpperBound() const;
+ void CalculateInstantUpperBound();
+ DataRate GetInstantLowerBound() const;
+ void CalculateInstantLowerBound();
+
+ void CalculateTemporalWeights();
+ void NewtonsMethodUpdate(ChannelParameters& channel_parameters) const;
+
+ // Returns false if no observation was created.
+ bool PushBackObservation(rtc::ArrayView<const PacketResult> packet_results);
+ void UpdateResult();
+ bool IsEstimateIncreasingWhenLossLimited(DataRate old_estimate,
+ DataRate new_estimate);
+ bool IsInLossLimitedState() const;
+ bool CanKeepIncreasingState(DataRate estimate) const;
+
+ absl::optional<DataRate> acknowledged_bitrate_;
+ absl::optional<Config> config_;
+ ChannelParameters current_best_estimate_;
+ int num_observations_ = 0;
+ std::vector<Observation> observations_;
+ PartialObservation partial_observation_;
+ Timestamp last_send_time_most_recent_observation_ = Timestamp::PlusInfinity();
+ Timestamp last_time_estimate_reduced_ = Timestamp::MinusInfinity();
+ absl::optional<DataRate> cached_instant_upper_bound_;
+ absl::optional<DataRate> cached_instant_lower_bound_;
+ std::vector<double> instant_upper_bound_temporal_weights_;
+ std::vector<double> temporal_weights_;
+ Timestamp recovering_after_loss_timestamp_ = Timestamp::MinusInfinity();
+ DataRate bandwidth_limit_in_current_window_ = DataRate::PlusInfinity();
+ DataRate min_bitrate_ = DataRate::KilobitsPerSec(1);
+ DataRate max_bitrate_ = DataRate::PlusInfinity();
+ DataRate delay_based_estimate_ = DataRate::PlusInfinity();
+ LossBasedBweV2::Result loss_based_result_ = LossBasedBweV2::Result();
+ Timestamp last_hold_timestamp_ = Timestamp::MinusInfinity();
+ TimeDelta hold_duration_ = TimeDelta::Zero();
+ PaddingInfo last_padding_info_ = PaddingInfo();
+};
+
+} // namespace webrtc
+
+#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_