Probe on video encoder reconfiguration test.

This CL includes the changes from this CL:
https://webrtc-review.googlesource.com/c/src/+/63642

Bug: webrtc:8955
Change-Id: If95cdec59f25e97c6ff5ea45a52d6113128a0921
Reviewed-on: https://webrtc-review.googlesource.com/64822
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22910}
diff --git a/call/call_perf_tests.cc b/call/call_perf_tests.cc
index 486195f..6520e6f 100644
--- a/call/call_perf_tests.cc
+++ b/call/call_perf_tests.cc
@@ -659,7 +659,6 @@
 TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
   static const uint32_t kInitialBitrateKbps = 400;
   static const uint32_t kReconfigureThresholdKbps = 600;
-  static const uint32_t kPermittedReconfiguredBitrateDiffKbps = 100;
 
   class VideoStreamFactory
       : public VideoEncoderConfig::VideoStreamFactoryInterface {
@@ -710,9 +709,7 @@
         EXPECT_EQ(2 * kDefaultWidth, config->width);
         EXPECT_EQ(2 * kDefaultHeight, config->height);
         EXPECT_GE(last_set_bitrate_kbps_, kReconfigureThresholdKbps);
-        EXPECT_GT(
-            config->startBitrate,
-            last_set_bitrate_kbps_ - kPermittedReconfiguredBitrateDiffKbps)
+        EXPECT_GT(config->startBitrate, kReconfigureThresholdKbps)
             << "Encoder reconfigured with bitrate too far away from last set.";
         observation_complete_.Set();
       }
diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc
index 4483616..66838d3 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller.cc
@@ -137,8 +137,9 @@
     int64_t at_time_ms) {
   // TODO(philipel): Should |max_total_allocated_bitrate| be used as a limit for
   //                 ALR probing?
-  if (estimated_bitrate_bps_ != 0 &&
-      estimated_bitrate_bps_ < max_bitrate_bps_ &&
+  if (max_total_allocated_bitrate != max_total_allocated_bitrate_ &&
+      estimated_bitrate_bps_ != 0 &&
+      (max_bitrate_bps_ <= 0 || estimated_bitrate_bps_ < max_bitrate_bps_) &&
       estimated_bitrate_bps_ < max_total_allocated_bitrate) {
     InitiateProbing(at_time_ms, {max_total_allocated_bitrate}, false);
   }
@@ -256,6 +257,7 @@
   mid_call_probing_waiting_for_result_ = false;
   time_of_last_large_drop_ms_ = now_ms;
   bitrate_before_last_large_drop_bps_ = 0;
+  max_total_allocated_bitrate_ = 0;
 }
 
 void ProbeController::Process(int64_t at_time_ms) {
diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h
index 6434b0e..baa3736 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.h
+++ b/modules/congestion_controller/goog_cc/probe_controller.h
@@ -90,6 +90,7 @@
   bool enable_periodic_alr_probing_;
   int64_t time_of_last_large_drop_ms_;
   int64_t bitrate_before_last_large_drop_bps_;
+  int64_t max_total_allocated_bitrate_;
 
   bool in_rapid_recovery_experiment_;
   // For WebRTC.BWE.MidCallProbing.* metric.
diff --git a/modules/congestion_controller/probe_controller.cc b/modules/congestion_controller/probe_controller.cc
index 381eaa2..6fbe01e 100644
--- a/modules/congestion_controller/probe_controller.cc
+++ b/modules/congestion_controller/probe_controller.cc
@@ -130,9 +130,11 @@
   rtc::CritScope cs(&critsect_);
   // TODO(philipel): Should |max_total_allocated_bitrate| be used as a limit for
   //                 ALR probing?
-  if (estimated_bitrate_bps_ != 0 &&
-      estimated_bitrate_bps_ < max_bitrate_bps_ &&
+  if (max_total_allocated_bitrate != max_total_allocated_bitrate_ &&
+      estimated_bitrate_bps_ != 0 &&
+      (max_bitrate_bps_ <= 0 || estimated_bitrate_bps_ < max_bitrate_bps_) &&
       estimated_bitrate_bps_ < max_total_allocated_bitrate) {
+    max_total_allocated_bitrate_ = max_total_allocated_bitrate;
     InitiateProbing(clock_->TimeInMilliseconds(), {max_total_allocated_bitrate},
                     false);
   }
@@ -252,6 +254,7 @@
   mid_call_probing_waiting_for_result_ = false;
   time_of_last_large_drop_ms_ = now_ms;
   bitrate_before_last_large_drop_bps_ = 0;
+  max_total_allocated_bitrate_ = 0;
 }
 
 void ProbeController::Process() {
diff --git a/modules/congestion_controller/probe_controller.h b/modules/congestion_controller/probe_controller.h
index 7c64b4c..084055b 100644
--- a/modules/congestion_controller/probe_controller.h
+++ b/modules/congestion_controller/probe_controller.h
@@ -83,6 +83,7 @@
   bool enable_periodic_alr_probing_ RTC_GUARDED_BY(critsect_);
   int64_t time_of_last_large_drop_ms_ RTC_GUARDED_BY(critsect_);
   int64_t bitrate_before_last_large_drop_bps_ RTC_GUARDED_BY(critsect_);
+  int64_t max_total_allocated_bitrate_ RTC_GUARDED_BY(critsect_);
 
   bool in_rapid_recovery_experiment_ RTC_GUARDED_BY(critsect_);
   // For WebRTC.BWE.MidCallProbing.* metric.
diff --git a/test/encoder_settings.cc b/test/encoder_settings.cc
index 665c82b..33e81b0 100644
--- a/test/encoder_settings.cc
+++ b/test/encoder_settings.cc
@@ -48,10 +48,37 @@
     stream_settings[i].max_framerate = 30;
     stream_settings[i].min_bitrate_bps =
         DefaultVideoStreamFactory::kDefaultMinBitratePerStream[i];
-    stream_settings[i].target_bitrate_bps = stream_settings[i].max_bitrate_bps =
-        std::min(bitrate_left_bps,
-                 DefaultVideoStreamFactory::kMaxBitratePerStream[i]);
+
+    int target_bitrate_bps = -1;
+    int max_bitrate_bps = -1;
+    // Use configured values instead of default values if values has been
+    // configured.
+    if (i < encoder_config.simulcast_layers.size()) {
+      const VideoStream& stream = encoder_config.simulcast_layers[i];
+
+      max_bitrate_bps =
+          stream.max_bitrate_bps > 0
+              ? stream.max_bitrate_bps
+              : DefaultVideoStreamFactory::kMaxBitratePerStream[i];
+      max_bitrate_bps = std::min(bitrate_left_bps, max_bitrate_bps);
+
+      target_bitrate_bps =
+          stream.target_bitrate_bps > 0
+              ? stream.target_bitrate_bps
+              : DefaultVideoStreamFactory::kMaxBitratePerStream[i];
+      target_bitrate_bps = std::min(max_bitrate_bps, target_bitrate_bps);
+    } else {
+      max_bitrate_bps = std::min(
+          bitrate_left_bps, DefaultVideoStreamFactory::kMaxBitratePerStream[i]);
+      target_bitrate_bps = max_bitrate_bps;
+    }
+
+    RTC_DCHECK_NE(target_bitrate_bps, -1);
+    RTC_DCHECK_NE(max_bitrate_bps, -1);
+    stream_settings[i].target_bitrate_bps = target_bitrate_bps;
+    stream_settings[i].max_bitrate_bps = max_bitrate_bps;
     stream_settings[i].max_qp = 56;
+
     if (i < encoder_config.simulcast_layers.size()) {
       // Higher level controls are setting the active configuration for the
       // VideoStream.
diff --git a/video/end_to_end_tests/probing_tests.cc b/video/end_to_end_tests/probing_tests.cc
index db66f62..777a346 100644
--- a/video/end_to_end_tests/probing_tests.cc
+++ b/video/end_to_end_tests/probing_tests.cc
@@ -188,4 +188,110 @@
   EXPECT_TRUE(success) << "Failed to perform mid call probing (" << kMaxAttempts
                        << " attempts).";
 }
+
+#if defined(MEMORY_SANITIZER)
+TEST_P(ProbingEndToEndTest, DISABLED_ProbeOnVideoEncoderReconfiguration) {
+#elif defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
+TEST_P(ProbingEndToEndTest, DISABLED_ProbeOnVideoEncoderReconfiguration) {
+#else
+TEST_P(ProbingEndToEndTest, ProbeOnVideoEncoderReconfiguration) {
+#endif
+
+  class ReconfigureTest : public ProbingTest {
+   public:
+    ReconfigureTest(test::SingleThreadedTaskQueueForTesting* task_queue,
+                    bool* success)
+        : ProbingTest(50000), task_queue_(task_queue), success_(success) {}
+
+    void ModifyVideoConfigs(
+        VideoSendStream::Config* send_config,
+        std::vector<VideoReceiveStream::Config>* receive_configs,
+        VideoEncoderConfig* encoder_config) override {
+      encoder_config_ = encoder_config;
+    }
+
+    void OnVideoStreamsCreated(
+        VideoSendStream* send_stream,
+        const std::vector<VideoReceiveStream*>& receive_streams) override {
+      send_stream_ = send_stream;
+    }
+
+    test::PacketTransport* CreateSendTransport(
+        test::SingleThreadedTaskQueueForTesting* task_queue,
+        Call* sender_call) override {
+      send_transport_ = new test::PacketTransport(
+          task_queue, sender_call, this, test::PacketTransport::kSender,
+          CallTest::payload_type_map_, FakeNetworkPipe::Config());
+      return send_transport_;
+    }
+
+    void PerformTest() override {
+      *success_ = false;
+      int64_t start_time_ms = clock_->TimeInMilliseconds();
+      do {
+        if (clock_->TimeInMilliseconds() - start_time_ms > kTimeoutMs)
+          break;
+
+        Call::Stats stats = sender_call_->GetStats();
+
+        switch (state_) {
+          case 0:
+            // Wait until initial probing has been completed (6 times start
+            // bitrate).
+            if (stats.send_bandwidth_bps >= 250000 &&
+                stats.send_bandwidth_bps <= 350000) {
+              FakeNetworkPipe::Config config;
+              config.link_capacity_kbps = 200;
+              send_transport_->SetConfig(config);
+
+              ++state_;
+            }
+            break;
+          case 1:
+            if (stats.send_bandwidth_bps <= 210000) {
+              FakeNetworkPipe::Config config;
+              config.link_capacity_kbps = 5000;
+              send_transport_->SetConfig(config);
+
+              encoder_config_->max_bitrate_bps = 2000000;
+              encoder_config_->simulcast_layers[0].max_bitrate_bps = 1200000;
+              task_queue_->SendTask([this]() {
+                send_stream_->ReconfigureVideoEncoder(encoder_config_->Copy());
+              });
+
+              ++state_;
+            }
+            break;
+          case 2:
+            if (stats.send_bandwidth_bps >= 1000000) {
+              *success_ = true;
+              observation_complete_.Set();
+            }
+            break;
+        }
+      } while (!observation_complete_.Wait(20));
+    }
+
+   private:
+    const int kTimeoutMs = 3000;
+    test::SingleThreadedTaskQueueForTesting* const task_queue_;
+    bool* const success_;
+    test::PacketTransport* send_transport_;
+    VideoSendStream* send_stream_;
+    VideoEncoderConfig* encoder_config_;
+  };
+
+  bool success = false;
+  const int kMaxAttempts = 3;
+  for (int i = 0; i < kMaxAttempts; ++i) {
+    ReconfigureTest test(&task_queue_, &success);
+    RunBaseTest(&test);
+    if (success) {
+      return;
+    }
+  }
+  EXPECT_TRUE(success) << "Failed to perform mid call probing (" << kMaxAttempts
+                       << " attempts).";
+}
+
 }  // namespace webrtc