LossBweV2: Base ramp up speed on time passed since last backoff.

By initialization, time since backoff is unlimited at startup.

Bug: none
Change-Id: I9693cd09b7201606374a8bf9a0a03e6ee83191d3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232611
Commit-Queue: Fanny Linderborg <linderborg@webrtc.org>
Reviewed-by: Fanny Linderborg <linderborg@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35076}
diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
index dd7c52c..91fd719 100644
--- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
+++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
@@ -213,7 +213,10 @@
       best_candidate = candidate;
     }
   }
-
+  if (best_candidate.loss_limited_bandwidth <
+      current_estimate_.loss_limited_bandwidth) {
+    last_time_estimate_reduced_ = last_send_time_most_recent_observation_;
+  }
   current_estimate_ = best_candidate;
 }
 
@@ -224,6 +227,10 @@
   FieldTrialParameter<bool> enabled("Enabled", false);
   FieldTrialParameter<double> bandwidth_rampup_upper_bound_factor(
       "BwRampupUpperBoundFactor", 1.1);
+  FieldTrialParameter<double> rampup_acceleration_max_factor(
+      "BwRampupAccelMaxFactor", 0.0);
+  FieldTrialParameter<TimeDelta> rampup_acceleration_maxout_time(
+      "BwRampupAccelMaxoutTime", TimeDelta::Seconds(60));
   FieldTrialList<double> candidate_factors("CandidateFactors",
                                            {1.05, 1.0, 0.95});
   FieldTrialParameter<double> higher_bandwidth_bias_factor("HigherBwBiasFactor",
@@ -261,6 +268,8 @@
   if (key_value_config) {
     ParseFieldTrial({&enabled,
                      &bandwidth_rampup_upper_bound_factor,
+                     &rampup_acceleration_max_factor,
+                     &rampup_acceleration_maxout_time,
                      &candidate_factors,
                      &higher_bandwidth_bias_factor,
                      &higher_log_bandwidth_bias_factor,
@@ -289,6 +298,9 @@
   config.emplace();
   config->bandwidth_rampup_upper_bound_factor =
       bandwidth_rampup_upper_bound_factor.Get();
+  config->rampup_acceleration_max_factor = rampup_acceleration_max_factor.Get();
+  config->rampup_acceleration_maxout_time =
+      rampup_acceleration_maxout_time.Get();
   config->candidate_factors = candidate_factors.Get();
   config->higher_bandwidth_bias_factor = higher_bandwidth_bias_factor.Get();
   config->higher_log_bandwidth_bias_factor =
@@ -332,6 +344,18 @@
         << config_->bandwidth_rampup_upper_bound_factor;
     valid = false;
   }
+  if (config_->rampup_acceleration_max_factor < 0.0) {
+    RTC_LOG(LS_WARNING)
+        << "The rampup acceleration max factor must be non-negative.: "
+        << config_->rampup_acceleration_max_factor;
+    valid = false;
+  }
+  if (config_->rampup_acceleration_maxout_time <= TimeDelta::Zero()) {
+    RTC_LOG(LS_WARNING)
+        << "The rampup acceleration maxout time must be above zero: "
+        << config_->rampup_acceleration_maxout_time.seconds();
+    valid = false;
+  }
   if (config_->higher_bandwidth_bias_factor < 0.0) {
     RTC_LOG(LS_WARNING)
         << "The higher bandwidth bias factor must be non-negative: "
@@ -450,6 +474,28 @@
   return static_cast<double>(num_lost_packets) / num_packets;
 }
 
+DataRate LossBasedBweV2::GetCandidateBandwidthUpperBound() const {
+  if (!acknowledged_bitrate_.has_value())
+    return DataRate::PlusInfinity();
+
+  DataRate candidate_bandwidth_upper_bound =
+      config_->bandwidth_rampup_upper_bound_factor * (*acknowledged_bitrate_);
+
+  if (config_->rampup_acceleration_max_factor > 0.0) {
+    const TimeDelta time_since_bandwidth_reduced = std::min(
+        config_->rampup_acceleration_maxout_time,
+        std::max(TimeDelta::Zero(), last_send_time_most_recent_observation_ -
+                                        last_time_estimate_reduced_));
+    const double rampup_acceleration = config_->rampup_acceleration_max_factor *
+                                       time_since_bandwidth_reduced /
+                                       config_->rampup_acceleration_maxout_time;
+
+    candidate_bandwidth_upper_bound +=
+        rampup_acceleration * (*acknowledged_bitrate_);
+  }
+  return candidate_bandwidth_upper_bound;
+}
+
 std::vector<LossBasedBweV2::ChannelParameters> LossBasedBweV2::GetCandidates(
     DataRate delay_based_estimate) const {
   std::vector<DataRate> bandwidths;
@@ -469,10 +515,7 @@
   }
 
   const DataRate candidate_bandwidth_upper_bound =
-      acknowledged_bitrate_.has_value()
-          ? config_->bandwidth_rampup_upper_bound_factor *
-                (*acknowledged_bitrate_)
-          : DataRate::PlusInfinity();
+      GetCandidateBandwidthUpperBound();
 
   std::vector<ChannelParameters> candidates;
   candidates.resize(bandwidths.size());
diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
index 0d550e1..f764892 100644
--- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
+++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
@@ -59,6 +59,8 @@
 
   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;
@@ -109,6 +111,7 @@
   double GetAverageReportedLossRatio() const;
   std::vector<ChannelParameters> GetCandidates(
       DataRate delay_based_estimate) const;
+  DataRate GetCandidateBandwidthUpperBound() const;
   Derivatives GetDerivatives(const ChannelParameters& channel_parameters) const;
   double GetFeasibleInherentLoss(
       const ChannelParameters& channel_parameters) const;
@@ -132,6 +135,7 @@
   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_;
   std::vector<double> instant_upper_bound_temporal_weights_;
   std::vector<double> temporal_weights_;