Allow GoogCC to send padding if BWE is loss limited

This will be used in an experiment to ramp up BWE when BWE is reduced
due to loss.

Bug: webrtc:12707
Change-Id: I3b78f9dd3fe8ef9f94a9616640ffb8b2225e161e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324042
Reviewed-by: Diep Bui <diepbp@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40961}
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
index 1344bf3..94645dc 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -84,10 +84,15 @@
   }
   switch (loss_based_state) {
     case LossBasedState::kDecreasing:
+      // Probes may not be sent in this state.
+      return BandwidthLimitedCause::kLossLimitedBwe;
+    case webrtc::LossBasedState::kIncreaseUsingPadding:
+      // Probes may not be sent in this state.
       return BandwidthLimitedCause::kLossLimitedBwe;
     case LossBasedState::kIncreasing:
+      // Probes may be sent in this state.
       return BandwidthLimitedCause::kLossLimitedBweIncreasing;
-    default:
+    case LossBasedState::kDelayBasedEstimate:
       return BandwidthLimitedCause::kDelayBasedLimited;
   }
 }
@@ -140,6 +145,7 @@
       last_loss_based_target_rate_(*config.constraints.starting_rate),
       last_pushback_target_rate_(last_loss_based_target_rate_),
       last_stable_target_rate_(last_loss_based_target_rate_),
+      last_loss_base_state_(LossBasedState::kDelayBasedEstimate),
       pacing_factor_(config.stream_based_config.pacing_factor.value_or(
           kDefaultPaceMultiplier)),
       min_total_allocated_bitrate_(
@@ -635,6 +641,7 @@
   uint8_t fraction_loss = bandwidth_estimation_->fraction_loss();
   TimeDelta round_trip_time = bandwidth_estimation_->round_trip_time();
   DataRate loss_based_target_rate = bandwidth_estimation_->target_rate();
+  LossBasedState loss_based_state = bandwidth_estimation_->loss_based_state();
   DataRate pushback_target_rate = loss_based_target_rate;
 
   BWE_TEST_LOGGING_PLOT(1, "fraction_loss_%", at_time.ms(),
@@ -662,6 +669,7 @@
   stable_target_rate = std::min(stable_target_rate, pushback_target_rate);
 
   if ((loss_based_target_rate != last_loss_based_target_rate_) ||
+      (loss_based_state != last_loss_base_state_) ||
       (fraction_loss != last_estimated_fraction_loss_) ||
       (round_trip_time != last_estimated_round_trip_time_) ||
       (pushback_target_rate != last_pushback_target_rate_) ||
@@ -671,6 +679,7 @@
     last_estimated_fraction_loss_ = fraction_loss;
     last_estimated_round_trip_time_ = round_trip_time;
     last_stable_target_rate_ = stable_target_rate;
+    last_loss_base_state_ = loss_based_state;
 
     alr_detector_->SetEstimatedBitrate(loss_based_target_rate.bps());
 
@@ -722,7 +731,10 @@
         pacing_factor_;
   }
   DataRate padding_rate =
-      std::min(max_padding_rate_, last_pushback_target_rate_);
+      (last_loss_base_state_ == LossBasedState::kIncreaseUsingPadding)
+          ? std::max(max_padding_rate_, last_loss_based_target_rate_)
+          : max_padding_rate_;
+  padding_rate = std::min(padding_rate, last_pushback_target_rate_);
   PacerConfig msg;
   msg.at_time = at_time;
   msg.time_window = TimeDelta::Seconds(1);
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.h b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
index 3ebcf08..957cedb 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
@@ -130,6 +130,7 @@
   DataRate last_loss_based_target_rate_;
   DataRate last_pushback_target_rate_;
   DataRate last_stable_target_rate_;
+  LossBasedState last_loss_base_state_;
 
   absl::optional<uint8_t> last_estimated_fraction_loss_ = 0;
   TimeDelta last_estimated_round_trip_time_ = TimeDelta::PlusInfinity();
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 81c2f90..a908bdb 100644
--- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
+++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
@@ -28,8 +28,12 @@
 // when network is loss limited, or equal to the delay based estimate.
 enum class LossBasedState {
   kIncreasing = 0,
-  kDecreasing = 1,
-  kDelayBasedEstimate = 2
+  // 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 {