Add ability to set custom RtpEncodingParameters for each simulcast stream in PC framework

Bug: webrtc:11557
Change-Id: I9f44728ff9178cd9c7dbe4cbcd639d610a981015
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174754
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31218}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 8d3ee8f..c5629c0 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -365,6 +365,7 @@
     ":media_stream_interface",
     ":network_state_predictor_api",
     ":packet_socket_factory",
+    ":rtp_parameters",
     ":simulated_network_api",
     ":stats_observer_interface",
     ":video_quality_analyzer_api",
diff --git a/api/test/peerconnection_quality_test_fixture.h b/api/test/peerconnection_quality_test_fixture.h
index d55647a..7a17284 100644
--- a/api/test/peerconnection_quality_test_fixture.h
+++ b/api/test/peerconnection_quality_test_fixture.h
@@ -26,6 +26,7 @@
 #include "api/media_stream_interface.h"
 #include "api/peer_connection_interface.h"
 #include "api/rtc_event_log/rtc_event_log_factory_interface.h"
+#include "api/rtp_parameters.h"
 #include "api/task_queue/task_queue_factory.h"
 #include "api/test/audio_quality_analyzer_interface.h"
 #include "api/test/frame_generator_interface.h"
@@ -160,6 +161,14 @@
     // It requires Selective Forwarding Unit (SFU) to be configured in the
     // network.
     absl::optional<int> target_spatial_index;
+
+    // Encoding parameters per simulcast layer. If not empty, |encoding_params|
+    // size have to be equal to |simulcast_streams_count|. Will be used to set
+    // transceiver send encoding params for simulcast layers. Applicable only
+    // for codecs that support simulcast (ex. Vp8) and will be ignored
+    // otherwise. RtpEncodingParameters::rid may be changed by fixture
+    // implementation to ensure signaling correctness.
+    std::vector<RtpEncodingParameters> encoding_params;
   };
 
   // Contains properties of single video stream.
diff --git a/test/pc/e2e/peer_configurer.cc b/test/pc/e2e/peer_configurer.cc
index eabe1ab..0bbbda7 100644
--- a/test/pc/e2e/peer_configurer.cc
+++ b/test/pc/e2e/peer_configurer.cc
@@ -104,13 +104,13 @@
     const RunParams& run_params,
     const std::vector<std::unique_ptr<PeerConfigurerImpl>>& peers) {
   RTC_CHECK_GT(run_params.video_encoder_bitrate_multiplier, 0.0);
+  RTC_CHECK_GE(run_params.video_codecs.size(), 1);
 
   std::set<std::string> peer_names;
   std::set<std::string> video_labels;
   std::set<std::string> audio_labels;
   int media_streams_count = 0;
 
-  bool has_simulcast = false;
   for (size_t i = 0; i < peers.size(); ++i) {
     Params* p = peers[i]->params();
 
@@ -134,16 +134,25 @@
                           << video_config.stream_label.value();
 
       if (video_config.simulcast_config) {
-        has_simulcast = true;
         if (video_config.simulcast_config->target_spatial_index) {
           RTC_CHECK_GE(*video_config.simulcast_config->target_spatial_index, 0);
           RTC_CHECK_LT(*video_config.simulcast_config->target_spatial_index,
                        video_config.simulcast_config->simulcast_streams_count);
         }
+        RTC_CHECK_EQ(run_params.video_codecs.size(), 1)
+            << "Only 1 video codec is supported when simulcast is enabled in "
+            << "at least 1 video config";
         RTC_CHECK(!video_config.max_encode_bitrate_bps)
             << "Setting max encode bitrate is not implemented for simulcast.";
         RTC_CHECK(!video_config.min_encode_bitrate_bps)
             << "Setting min encode bitrate is not implemented for simulcast.";
+        if (run_params.video_codecs[0].name == cricket::kVp8CodecName &&
+            !video_config.simulcast_config->encoding_params.empty()) {
+          RTC_CHECK_EQ(video_config.simulcast_config->simulcast_streams_count,
+                       video_config.simulcast_config->encoding_params.size())
+              << "|encoding_params| have to be specified for each simulcast "
+              << "stream in |simulcast_config|.";
+        }
       }
     }
     if (p->audio_config) {
@@ -164,11 +173,6 @@
       }
     }
   }
-  if (has_simulcast) {
-    RTC_CHECK_EQ(run_params.video_codecs.size(), 1)
-        << "Only 1 video codec is supported when simulcast is enabled in at "
-        << "least 1 video config";
-  }
 
   RTC_CHECK_GT(media_streams_count, 0) << "No media in the call.";
 }
diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc
index 9d79b0e..17104a9 100644
--- a/test/pc/e2e/peer_connection_quality_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test.cc
@@ -419,10 +419,14 @@
       // Because simulcast enabled |run_params.video_codecs| has only 1 element.
       if (run_params.video_codecs[0].name == cricket::kVp8CodecName) {
         // For Vp8 simulcast we need to add as many RtpEncodingParameters to the
-        // track as many simulcast streams requested.
+        // track as many simulcast streams requested. If they specified in
+        // |video_config.simulcast_config| it should be copied from there.
         for (int i = 0;
              i < video_config.simulcast_config->simulcast_streams_count; ++i) {
           RtpEncodingParameters enc_params;
+          if (video_config.simulcast_config->encoding_params.size() > 0) {
+            enc_params = video_config.simulcast_config->encoding_params[i];
+          }
           // We need to be sure, that all rids will be unique with all mids.
           enc_params.rid = std::to_string(alice_transceivers_counter) + "000" +
                            std::to_string(i);