Add ability to enable AV sync in PC level tests

Bug: webrtc:11381
Change-Id: I223ff0a2b81632ee7cbbac5b722bb6a7d5f72f7e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168959
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30629}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 82dc308..517a0db 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -353,6 +353,7 @@
     "video:video_frame",
     "video_codecs:video_codecs_api",
     "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/test/peerconnection_quality_test_fixture.h b/api/test/peerconnection_quality_test_fixture.h
index 89c8e04..74f8202 100644
--- a/api/test/peerconnection_quality_test_fixture.h
+++ b/api/test/peerconnection_quality_test_fixture.h
@@ -17,6 +17,8 @@
 #include <vector>
 
 #include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
 #include "api/async_resolver_factory.h"
 #include "api/call/call_factory_interface.h"
 #include "api/fec_controller.h"
@@ -202,7 +204,7 @@
     // each RtpEncodingParameters of RtpParameters of corresponding
     // RtpSenderInterface for this video stream.
     absl::optional<int> temporal_layers_count;
-    // Sets the maxiumum encode bitrate in bps. If this value is not set, the
+    // Sets the maximum encode bitrate in bps. If this value is not set, the
     // encoder will be capped at an internal maximum value around 2 Mbps
     // depending on the resolution. This means that it will never be able to
     // utilize a high bandwidth link.
@@ -225,6 +227,11 @@
     absl::optional<std::string> output_dump_file_name;
     // If true will display input and output video on the user's screen.
     bool show_on_screen = false;
+    // If specified, determines a sync group to which this video stream belongs.
+    // According to bugs.webrtc.org/4762 WebRTC supports synchronization only
+    // for pair of single audio and single video stream. Framework won't do any
+    // enforcements on this field.
+    absl::optional<std::string> sync_group;
   };
 
   // Contains properties for audio in the call.
@@ -248,6 +255,11 @@
     cricket::AudioOptions audio_options;
     // Sampling frequency of input audio data (from file or generated).
     int sampling_frequency_in_hz = 48000;
+    // If specified, determines a sync group to which this audio stream belongs.
+    // According to bugs.webrtc.org/4762 WebRTC supports synchronization only
+    // for pair of single audio and single video stream. Framework won't do any
+    // enforcements on this field.
+    absl::optional<std::string> sync_group;
   };
 
   // This class is used to fully configure one peer inside the call.
diff --git a/test/pc/e2e/peer_connection_e2e_smoke_test.cc b/test/pc/e2e/peer_connection_e2e_smoke_test.cc
index b136f59..5d43716 100644
--- a/test/pc/e2e/peer_connection_e2e_smoke_test.cc
+++ b/test/pc/e2e/peer_connection_e2e_smoke_test.cc
@@ -148,6 +148,7 @@
       [](PeerConfigurer* alice) {
         VideoConfig video(640, 360, 30);
         video.stream_label = "alice-video";
+        video.sync_group = "alice-media";
         alice->AddVideoConfig(std::move(video));
 
         AudioConfig audio;
@@ -156,6 +157,7 @@
         audio.input_file_name =
             test::ResourcePath("pc_quality_smoke_test_alice_source", "wav");
         audio.sampling_frequency_in_hz = 48000;
+        audio.sync_group = "alice-media";
         alice->SetAudioConfig(std::move(audio));
       },
       [](PeerConfigurer* bob) {
@@ -262,7 +264,7 @@
       "simulcast", run_params,
       [](PeerConfigurer* alice) {
         VideoConfig simulcast(1280, 720, 30);
-        simulcast.stream_label = "alice-simulcast";
+        simulcast.stream_label = "alice-svc";
         // Because we have network with packets loss we can analyze only the
         // highest spatial layer in SVC mode.
         simulcast.simulcast_config = VideoSimulcastConfig(3, 2);
diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc
index 1f785a9..faf1aaa 100644
--- a/test/pc/e2e/peer_connection_quality_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test.cc
@@ -629,8 +629,9 @@
     std::vector<VideoConfig> remote_video_configs) {
   const rtc::scoped_refptr<MediaStreamTrackInterface>& track =
       transceiver->receiver()->track();
-  RTC_CHECK_EQ(transceiver->receiver()->stream_ids().size(), 1);
-  std::string stream_label = transceiver->receiver()->stream_ids().front();
+  RTC_CHECK_EQ(transceiver->receiver()->stream_ids().size(), 2)
+      << "Expected 2 stream ids: 1st - sync group, 2nd - unique stream label";
+  std::string stream_label = transceiver->receiver()->stream_ids()[1];
   analyzer_helper_.AddTrackToStreamMapping(track->id(), stream_label);
   if (track->kind() != MediaStreamTrackInterface::kVideoKind) {
     return;
@@ -770,8 +771,11 @@
         video_config.screen_share_config->use_text_content_hint) {
       track->set_content_hint(VideoTrackInterface::ContentHint::kText);
     }
+    std::string sync_group = video_config.sync_group
+                                 ? video_config.sync_group.value()
+                                 : video_config.stream_label.value();
     RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> sender =
-        peer->AddTrack(track, {video_config.stream_label.value()});
+        peer->AddTrack(track, {sync_group, *video_config.stream_label});
     RTC_CHECK(sender.ok());
     if (video_config.temporal_layers_count) {
       RtpParameters rtp_parameters = sender.value()->GetParameters();
@@ -895,7 +899,10 @@
       peer->pc_factory()->CreateAudioSource(audio_config.audio_options);
   rtc::scoped_refptr<AudioTrackInterface> track =
       peer->pc_factory()->CreateAudioTrack(*audio_config.stream_label, source);
-  peer->AddTrack(track, {*audio_config.stream_label});
+  std::string sync_group = audio_config.sync_group
+                               ? audio_config.sync_group.value()
+                               : audio_config.stream_label.value();
+  peer->AddTrack(track, {sync_group, *audio_config.stream_label});
 }
 
 void PeerConnectionE2EQualityTest::SetPeerCodecPreferences(
diff --git a/test/pc/e2e/sdp/sdp_changer.cc b/test/pc/e2e/sdp/sdp_changer.cc
index 68f418e..a2bf4c5 100644
--- a/test/pc/e2e/sdp/sdp_changer.cc
+++ b/test/pc/e2e/sdp/sdp_changer.cc
@@ -312,9 +312,10 @@
     RTC_CHECK_EQ(content.media_description()->streams().size(), 1);
     cricket::StreamParams& stream =
         content.media_description()->mutable_streams()[0];
-    RTC_CHECK_EQ(stream.stream_ids().size(), 1)
-        << "Too many stream ids in video stream";
-    std::string stream_label = stream.stream_ids()[0];
+    RTC_CHECK_EQ(stream.stream_ids().size(), 2)
+        << "Expected 2 stream ids in video stream: 1st - sync_group, 2nd - "
+           "unique label";
+    std::string stream_label = stream.stream_ids()[1];
 
     auto it =
         params_.stream_label_to_simulcast_streams_count.find(stream_label);