Add ability to turn on conference mode during simulcast in PC framework.

Bug: webrtc:10138
Change-Id: I9ccb9674285121c8561745babc7e2109588d5053
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146081
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28599}
diff --git a/api/test/peerconnection_quality_test_fixture.h b/api/test/peerconnection_quality_test_fixture.h
index aa2481a..1fe07e0 100644
--- a/api/test/peerconnection_quality_test_fixture.h
+++ b/api/test/peerconnection_quality_test_fixture.h
@@ -136,6 +136,8 @@
     //    spatial layer and all layers below, including target one will be
     //    processed. All layers above target one will be dropped.
     int target_spatial_index;
+    // If true will set conference mode in SDP media section for this track.
+    bool use_conference_mode = false;
   };
 
   // Contains properties of single video stream.
diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn
index beca4b2..cb2f2f9 100644
--- a/test/pc/e2e/BUILD.gn
+++ b/test/pc/e2e/BUILD.gn
@@ -487,6 +487,7 @@
   deps = [
     "../../../api:array_view",
     "../../../api:libjingle_peerconnection_api",
+    "../../../api:peer_connection_quality_test_fixture_api",
     "../../../media:rtc_media_base",
     "../../../p2p:rtc_p2p",
     "../../../pc:peerconnection",
diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc
index 1fbf383..d360fb6 100644
--- a/test/pc/e2e/peer_connection_quality_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test.cc
@@ -823,7 +823,17 @@
 }
 
 void PeerConnectionE2EQualityTest::SetupCall() {
-  SignalingInterceptor signaling_interceptor;
+  std::map<std::string, VideoSimulcastConfig> stream_label_to_simulcast_config;
+  // We add only Alice here, because simulcast/svc is supported only from the
+  // first peer.
+  for (auto& video_config : alice_->params()->video_configs) {
+    if (video_config.simulcast_config) {
+      stream_label_to_simulcast_config.insert(
+          {*video_config.stream_label, *video_config.simulcast_config});
+    }
+  }
+  PatchingParams patching_params(stream_label_to_simulcast_config);
+  SignalingInterceptor signaling_interceptor(patching_params);
   // Connect peers.
   ExchangeOfferAnswer(&signaling_interceptor);
   // Do the SDP negotiation, and also exchange ice candidates.
diff --git a/test/pc/e2e/peer_connection_quality_test.h b/test/pc/e2e/peer_connection_quality_test.h
index 7b17ffc..5896e51 100644
--- a/test/pc/e2e/peer_connection_quality_test.h
+++ b/test/pc/e2e/peer_connection_quality_test.h
@@ -167,6 +167,8 @@
       PeerConnectionE2EQualityTestFixture::VideoGeneratorType;
   using RunParams = PeerConnectionE2EQualityTestFixture::RunParams;
   using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig;
+  using VideoSimulcastConfig =
+      PeerConnectionE2EQualityTestFixture::VideoSimulcastConfig;
   using PeerConfigurer = PeerConnectionE2EQualityTestFixture::PeerConfigurer;
   using QualityMetricsReporter =
       PeerConnectionE2EQualityTestFixture::QualityMetricsReporter;
diff --git a/test/pc/e2e/sdp/sdp_changer.cc b/test/pc/e2e/sdp/sdp_changer.cc
index fcc0c97..476e571 100644
--- a/test/pc/e2e/sdp/sdp_changer.cc
+++ b/test/pc/e2e/sdp/sdp_changer.cc
@@ -88,7 +88,8 @@
 // If offer has no simulcast video sections - do nothing.
 //
 // If offer has simulcast video sections - for each section creates
-// SimulcastSectionInfo and put it into |context_|.
+// SimulcastSectionInfo and put it into |context_|. Also will set conference
+// mode if requested.
 void SignalingInterceptor::FillContext(SessionDescriptionInterface* offer) {
   for (auto& content : offer->description()->contents()) {
     context_.mids_order.push_back(content.mid());
@@ -101,9 +102,23 @@
       RTC_CHECK_EQ(media_desc->mutable_streams().size(), 1);
       RTC_CHECK(media_desc->mutable_streams()[0].has_rids());
 
+      // Extract stream label, that was used when we added the stream.
+      cricket::StreamParams& stream = media_desc->mutable_streams()[0];
+      RTC_CHECK(stream.stream_ids().size() == 1)
+          << "Too many stream ids in video stream";
+      std::string stream_label = stream.stream_ids()[0];
+
+      bool conference_mode =
+          params_.stream_label_to_simulcast_config.at(stream_label)
+              .use_conference_mode;
+
       // Create SimulcastSectionInfo for this video section.
       SimulcastSectionInfo info(content.mid(), content.type,
-                                media_desc->mutable_streams()[0].rids());
+                                media_desc->mutable_streams()[0].rids(),
+                                conference_mode);
+
+      // Set conference mode if requested
+      media_desc->set_conference_mode(conference_mode);
 
       // Set new rids basing on created SimulcastSectionInfo.
       std::vector<cricket::RidDescription> rids;
@@ -168,6 +183,7 @@
     // because otherwise description will be deleted.
     std::unique_ptr<cricket::MediaContentDescription> prototype_media_desc =
         absl::WrapUnique(simulcast_content->media_description()->Copy());
+    prototype_media_desc->set_conference_mode(false);
 
     // Remove simulcast video section from offer.
     RTC_CHECK(desc->RemoveContentByName(simulcast_content->mid()));
@@ -334,6 +350,9 @@
     }
     media_desc->set_simulcast_description(simulcast_description);
 
+    // Set conference mode if requested.
+    media_desc->set_conference_mode(info.conference_mode);
+
     // Add simulcast media section.
     desc->AddContent(info.mid, info.media_protocol_type, std::move(media_desc));
   }
@@ -427,8 +446,11 @@
 SignalingInterceptor::SimulcastSectionInfo::SimulcastSectionInfo(
     const std::string& mid,
     cricket::MediaProtocolType media_protocol_type,
-    const std::vector<cricket::RidDescription>& rids_desc)
-    : mid(mid), media_protocol_type(media_protocol_type) {
+    const std::vector<cricket::RidDescription>& rids_desc,
+    bool conference_mode)
+    : mid(mid),
+      media_protocol_type(media_protocol_type),
+      conference_mode(conference_mode) {
   for (auto& rid : rids_desc) {
     rids.push_back(rid.rid);
   }
diff --git a/test/pc/e2e/sdp/sdp_changer.h b/test/pc/e2e/sdp/sdp_changer.h
index fe11421..47dc23e 100644
--- a/test/pc/e2e/sdp/sdp_changer.h
+++ b/test/pc/e2e/sdp/sdp_changer.h
@@ -20,6 +20,7 @@
 #include "api/array_view.h"
 #include "api/jsep.h"
 #include "api/rtp_parameters.h"
+#include "api/test/peerconnection_quality_test_fixture.h"
 #include "media/base/rid_description.h"
 #include "pc/session_description.h"
 #include "pc/simulcast_description.h"
@@ -59,8 +60,22 @@
   std::unique_ptr<SessionDescriptionInterface> remote_sdp;
 };
 
+struct PatchingParams {
+  PatchingParams(
+      std::map<std::string,
+               PeerConnectionE2EQualityTestFixture::VideoSimulcastConfig>
+          stream_label_to_simulcast_config)
+      : stream_label_to_simulcast_config(stream_label_to_simulcast_config) {}
+
+  std::map<std::string,
+           PeerConnectionE2EQualityTestFixture::VideoSimulcastConfig>
+      stream_label_to_simulcast_config;
+};
+
 class SignalingInterceptor {
  public:
+  explicit SignalingInterceptor(PatchingParams params) : params_(params) {}
+
   LocalAndRemoteSdp PatchOffer(
       std::unique_ptr<SessionDescriptionInterface> offer);
   LocalAndRemoteSdp PatchAnswer(
@@ -78,10 +93,12 @@
   struct SimulcastSectionInfo {
     SimulcastSectionInfo(const std::string& mid,
                          cricket::MediaProtocolType media_protocol_type,
-                         const std::vector<cricket::RidDescription>& rids_desc);
+                         const std::vector<cricket::RidDescription>& rids_desc,
+                         bool conference_mode);
 
     const std::string mid;
     const cricket::MediaProtocolType media_protocol_type;
+    const bool conference_mode;
     std::vector<std::string> rids;
     cricket::SimulcastDescription simulcast_description;
     webrtc::RtpExtension mid_extension;
@@ -112,6 +129,7 @@
   std::unique_ptr<cricket::SessionDescription> RestoreMediaSectionsOrder(
       std::unique_ptr<cricket::SessionDescription> source);
 
+  PatchingParams params_;
   SignalingContext context_;
 };