Moving functionality from VideoQualityTest to CallTest

Bug: webrtc:9510
Change-Id: Ie1cd34693e08d2c4b8fd79470573a6069564ded5
Reviewed-on: https://webrtc-review.googlesource.com/88182
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23969}
diff --git a/test/call_test.cc b/test/call_test.cc
index 641f03c..99bedaa 100644
--- a/test/call_test.cc
+++ b/test/call_test.cc
@@ -47,15 +47,13 @@
       num_flexfec_streams_(0),
       audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()),
       audio_encoder_factory_(CreateBuiltinAudioEncoderFactory()),
-      task_queue_("CallTestTaskQueue"),
-      video_send_config_(nullptr),
-      video_send_stream_(nullptr) {}
+      task_queue_("CallTestTaskQueue") {}
 
 CallTest::~CallTest() {
   task_queue_.SendTask([this]() {
     fake_send_audio_device_ = nullptr;
     fake_recv_audio_device_ = nullptr;
-    frame_generator_capturer_.reset();
+    video_capturers_.clear();
   });
 }
 
@@ -140,7 +138,7 @@
     }
     if (num_video_streams_ > 0) {
       CreateVideoStreams();
-      test->OnVideoStreamsCreated(video_send_stream_, video_receive_streams_);
+      test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
     }
     if (num_audio_streams_ > 0) {
       CreateAudioStreams();
@@ -153,7 +151,7 @@
       int frame_rate = kDefaultFramerate;
       test->ModifyVideoCaptureStartResolution(&width, &height, &frame_rate);
       CreateFrameGeneratorCapturer(frame_rate, width, height);
-      test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get());
+      test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_);
     }
 
     Start();
@@ -218,8 +216,11 @@
                    kTransportSequenceNumberExtensionId));
   video_config->rtp.extensions.push_back(RtpExtension(
       RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
-  FillEncoderConfiguration(kVideoCodecGeneric, num_video_streams,
-                           &video_encoder_config_);
+  if (video_encoder_configs_.empty()) {
+    video_encoder_configs_.emplace_back();
+    FillEncoderConfiguration(kVideoCodecGeneric, num_video_streams,
+                             &video_encoder_configs_.back());
+  }
 
   for (size_t i = 0; i < num_video_streams; ++i)
     video_config->rtp.ssrcs.push_back(kVideoSendSsrcs[num_used_ssrcs + i]);
@@ -233,98 +234,184 @@
   RTC_DCHECK_LE(num_audio_streams, 1);
   RTC_DCHECK_LE(num_flexfec_streams, 1);
   if (num_audio_streams > 0) {
-    audio_send_config_ = AudioSendStream::Config(send_transport);
-    audio_send_config_.rtp.ssrc = kAudioSendSsrc;
-    audio_send_config_.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
+    AudioSendStream::Config audio_send_config(send_transport);
+    audio_send_config.rtp.ssrc = kAudioSendSsrc;
+    audio_send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
         kAudioSendPayloadType, {"opus", 48000, 2, {{"stereo", "1"}}});
-    audio_send_config_.encoder_factory = audio_encoder_factory_;
+    audio_send_config.encoder_factory = audio_encoder_factory_;
+    SetAudioConfig(audio_send_config);
   }
 
   // TODO(brandtr): Update this when we support multistream protection.
   if (num_flexfec_streams > 0) {
-    GetVideoSendConfig()->rtp.flexfec.payload_type = kFlexfecPayloadType;
-    GetVideoSendConfig()->rtp.flexfec.ssrc = kFlexfecSendSsrc;
-    GetVideoSendConfig()->rtp.flexfec.protected_media_ssrcs = {
-        kVideoSendSsrcs[0]};
+    SetSendFecConfig({kVideoSendSsrcs[0]});
   }
 }
 
+void CallTest::SetAudioConfig(const AudioSendStream::Config& config) {
+  audio_send_config_ = config;
+}
+
+void CallTest::SetSendFecConfig(std::vector<uint32_t> video_send_ssrcs) {
+  GetVideoSendConfig()->rtp.flexfec.payload_type = kFlexfecPayloadType;
+  GetVideoSendConfig()->rtp.flexfec.ssrc = kFlexfecSendSsrc;
+  GetVideoSendConfig()->rtp.flexfec.protected_media_ssrcs = video_send_ssrcs;
+}
+
+void CallTest::SetSendUlpFecConfig(VideoSendStream::Config* send_config) {
+  send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
+  send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
+  send_config->rtp.ulpfec.red_rtx_payload_type = kRtxRedPayloadType;
+}
+
+void CallTest::SetReceiveUlpFecConfig(
+    VideoReceiveStream::Config* receive_config) {
+  receive_config->rtp.red_payload_type = kRedPayloadType;
+  receive_config->rtp.ulpfec_payload_type = kUlpfecPayloadType;
+  receive_config->rtp.rtx_associated_payload_types[kRtxRedPayloadType] =
+      kRedPayloadType;
+}
+
 void CallTest::CreateSendConfig(size_t num_video_streams,
                                 size_t num_audio_streams,
                                 size_t num_flexfec_streams,
                                 Transport* send_transport) {
   if (num_video_streams > 0) {
-    CreateVideoSendConfig(&video_send_config_, num_video_streams, 0,
+    video_send_configs_.clear();
+    video_send_configs_.emplace_back(nullptr);
+    CreateVideoSendConfig(&video_send_configs_.back(), num_video_streams, 0,
                           send_transport);
   }
   CreateAudioAndFecSendConfigs(num_audio_streams, num_flexfec_streams,
                                send_transport);
 }
 
-std::vector<VideoReceiveStream::Config>
-CallTest::CreateMatchingVideoReceiveConfigs(
+void CallTest::CreateMatchingVideoReceiveConfigs(
     const VideoSendStream::Config& video_send_config,
     Transport* rtcp_send_transport) {
-  std::vector<VideoReceiveStream::Config> result;
+  CreateMatchingVideoReceiveConfigs(video_send_config, rtcp_send_transport,
+                                    true, absl::nullopt, false, 0);
+}
+
+void CallTest::CreateMatchingVideoReceiveConfigs(
+    const VideoSendStream::Config& video_send_config,
+    Transport* rtcp_send_transport,
+    bool send_side_bwe,
+    absl::optional<size_t> decode_sub_stream,
+    bool receiver_reference_time_report,
+    int rtp_history_ms) {
+  AddMatchingVideoReceiveConfigs(
+      &video_receive_configs_, video_send_config, rtcp_send_transport,
+      send_side_bwe, decode_sub_stream, receiver_reference_time_report,
+      rtp_history_ms);
+}
+
+void CallTest::AddMatchingVideoReceiveConfigs(
+    std::vector<VideoReceiveStream::Config>* receive_configs,
+    const VideoSendStream::Config& video_send_config,
+    Transport* rtcp_send_transport,
+    bool send_side_bwe,
+    absl::optional<size_t> decode_sub_stream,
+    bool receiver_reference_time_report,
+    int rtp_history_ms) {
   RTC_DCHECK(!video_send_config.rtp.ssrcs.empty());
-  VideoReceiveStream::Config video_config(rtcp_send_transport);
-  video_config.rtp.remb = false;
-  video_config.rtp.transport_cc = true;
-  video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
+  VideoReceiveStream::Config default_config(rtcp_send_transport);
+  default_config.rtp.remb = !send_side_bwe;
+  default_config.rtp.transport_cc = send_side_bwe;
+  default_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
   for (const RtpExtension& extension : video_send_config.rtp.extensions)
-    video_config.rtp.extensions.push_back(extension);
-  video_config.renderer = &fake_renderer_;
+    default_config.rtp.extensions.push_back(extension);
+  default_config.rtp.nack.rtp_history_ms = rtp_history_ms;
+  // Enable RTT calculation so NTP time estimator will work.
+  default_config.rtp.rtcp_xr.receiver_reference_time_report =
+      receiver_reference_time_report;
+  default_config.renderer = &fake_renderer_;
+
   for (size_t i = 0; i < video_send_config.rtp.ssrcs.size(); ++i) {
-    VideoReceiveStream::Decoder decoder =
-        test::CreateMatchingDecoder(video_send_config);
-    allocated_decoders_.push_back(
-        std::unique_ptr<VideoDecoder>(decoder.decoder));
-    video_config.decoders.clear();
-    video_config.decoders.push_back(decoder);
-    video_config.rtp.remote_ssrc = video_send_config.rtp.ssrcs[i];
-    result.push_back(video_config.Copy());
+    VideoReceiveStream::Config video_recv_config(default_config.Copy());
+    video_recv_config.decoders.clear();
+    if (!video_send_config.rtp.rtx.ssrcs.empty()) {
+      video_recv_config.rtp.rtx_ssrc = video_send_config.rtp.rtx.ssrcs[i];
+      video_recv_config.rtp.rtx_associated_payload_types[kSendRtxPayloadType] =
+          video_send_config.rtp.payload_type;
+    }
+    video_recv_config.rtp.remote_ssrc = video_send_config.rtp.ssrcs[i];
+    VideoReceiveStream::Decoder decoder;
+
+    // Force fake decoders on non-selected simulcast streams.
+    if (!decode_sub_stream || i == *decode_sub_stream) {
+      decoder = test::CreateMatchingDecoder(video_send_config);
+    } else {
+      decoder.decoder = new test::FakeDecoder();
+      decoder.payload_type = video_send_config.rtp.payload_type;
+      decoder.payload_name = video_send_config.rtp.payload_name;
+    }
+    allocated_decoders_.emplace_back(decoder.decoder);
+    video_recv_config.decoders.push_back(decoder);
+    receive_configs->emplace_back(std::move(video_recv_config));
   }
-  result[0].rtp.protected_by_flexfec = (num_flexfec_streams_ == 1);
-  return result;
 }
 
 void CallTest::CreateMatchingAudioAndFecConfigs(
     Transport* rtcp_send_transport) {
   RTC_DCHECK_GE(1, num_audio_streams_);
   if (num_audio_streams_ == 1) {
-    AudioReceiveStream::Config audio_config;
-    audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc;
-    audio_config.rtcp_send_transport = rtcp_send_transport;
-    audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc;
-    audio_config.decoder_factory = audio_decoder_factory_;
-    audio_config.decoder_map = {{kAudioSendPayloadType, {"opus", 48000, 2}}};
-    audio_receive_configs_.push_back(audio_config);
+    CreateMatchingAudioConfigs(rtcp_send_transport, "");
   }
 
   // TODO(brandtr): Update this when we support multistream protection.
   RTC_DCHECK(num_flexfec_streams_ <= 1);
   if (num_flexfec_streams_ == 1) {
-    FlexfecReceiveStream::Config config(rtcp_send_transport);
-    config.payload_type = kFlexfecPayloadType;
-    config.remote_ssrc = kFlexfecSendSsrc;
-    config.protected_media_ssrcs = {kVideoSendSsrcs[0]};
-    config.local_ssrc = kReceiverLocalVideoSsrc;
+    CreateMatchingFecConfig(rtcp_send_transport, *GetVideoSendConfig());
     for (const RtpExtension& extension : GetVideoSendConfig()->rtp.extensions)
-      config.rtp_header_extensions.push_back(extension);
-    flexfec_receive_configs_.push_back(config);
+      GetFlexFecConfig()->rtp_header_extensions.push_back(extension);
   }
 }
 
+void CallTest::CreateMatchingAudioConfigs(Transport* transport,
+                                          std::string sync_group) {
+  audio_receive_configs_.push_back(CreateMatchingAudioConfig(
+      audio_send_config_, audio_decoder_factory_, transport, sync_group));
+}
+
+AudioReceiveStream::Config CallTest::CreateMatchingAudioConfig(
+    const AudioSendStream::Config& send_config,
+    rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
+    Transport* transport,
+    std::string sync_group) {
+  AudioReceiveStream::Config audio_config;
+  audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc;
+  audio_config.rtcp_send_transport = transport;
+  audio_config.rtp.remote_ssrc = send_config.rtp.ssrc;
+  audio_config.rtp.transport_cc =
+      send_config.send_codec_spec
+          ? send_config.send_codec_spec->transport_cc_enabled
+          : false;
+  audio_config.rtp.extensions = send_config.rtp.extensions;
+  audio_config.decoder_factory = audio_decoder_factory;
+  audio_config.decoder_map = {{kAudioSendPayloadType, {"opus", 48000, 2}}};
+  audio_config.sync_group = sync_group;
+  return audio_config;
+}
+
+void CallTest::CreateMatchingFecConfig(
+    Transport* transport,
+    const VideoSendStream::Config& send_config) {
+  FlexfecReceiveStream::Config config(transport);
+  config.payload_type = send_config.rtp.flexfec.payload_type;
+  config.remote_ssrc = send_config.rtp.flexfec.ssrc;
+  config.protected_media_ssrcs = send_config.rtp.flexfec.protected_media_ssrcs;
+  config.local_ssrc = kReceiverLocalVideoSsrc;
+  if (!video_receive_configs_.empty())
+    video_receive_configs_[0].rtp.protected_by_flexfec = true;
+  flexfec_receive_configs_.push_back(config);
+}
+
 void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
   video_receive_configs_.clear();
   allocated_decoders_.clear();
-  if (num_video_streams_ > 0) {
-    std::vector<VideoReceiveStream::Config> new_configs =
-        CreateMatchingVideoReceiveConfigs(*GetVideoSendConfig(),
-                                          rtcp_send_transport);
-    for (VideoReceiveStream::Config& config : new_configs) {
-      video_receive_configs_.push_back(config.Copy());
-    }
+  for (VideoSendStream::Config& video_send_config : video_send_configs_) {
+    CreateMatchingVideoReceiveConfigs(video_send_config, rtcp_send_transport);
   }
   CreateMatchingAudioAndFecConfigs(rtcp_send_transport);
 }
@@ -334,16 +421,26 @@
                                                      int framerate,
                                                      int width,
                                                      int height) {
-  frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
-      width, height, absl::nullopt, absl::nullopt, framerate * speed, clock));
+  video_sources_.clear();
+  video_capturers_.clear();
+  frame_generator_capturer_ = test::FrameGeneratorCapturer::Create(
+      width, height, absl::nullopt, absl::nullopt, framerate * speed, clock);
+  video_capturers_.emplace_back(
+      std::unique_ptr<FrameGeneratorCapturer>(frame_generator_capturer_));
+  video_sources_.push_back(video_capturers_.back().get());
   ConnectVideoSourcesToStreams();
 }
 
 void CallTest::CreateFrameGeneratorCapturer(int framerate,
                                             int width,
                                             int height) {
-  frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
-      width, height, absl::nullopt, absl::nullopt, framerate, clock_));
+  video_sources_.clear();
+  video_capturers_.clear();
+  frame_generator_capturer_ = test::FrameGeneratorCapturer::Create(
+      width, height, absl::nullopt, absl::nullopt, framerate, clock_);
+  video_capturers_.emplace_back(
+      std::unique_ptr<FrameGeneratorCapturer>(frame_generator_capturer_));
+  video_sources_.push_back(video_capturers_.back().get());
   ConnectVideoSourcesToStreams();
 }
 
@@ -368,15 +465,45 @@
 }
 
 void CallTest::CreateVideoSendStreams() {
-  RTC_DCHECK(video_send_stream_ == nullptr);
-  video_send_stream_ = sender_call_->CreateVideoSendStream(
-      GetVideoSendConfig()->Copy(), GetVideoEncoderConfig()->Copy());
+  RTC_DCHECK(video_send_streams_.empty());
+
+  // We currently only support testing external fec controllers with a single
+  // VideoSendStream.
+  if (fec_controller_factory_.get()) {
+    RTC_DCHECK_LE(video_send_configs_.size(), 1);
+  }
+
+  // TODO(http://crbug/818127):
+  // Remove this workaround when ALR is not screenshare-specific.
+  std::list<size_t> streams_creation_order;
+  for (size_t i = 0; i < video_send_configs_.size(); ++i) {
+    // If dual streams are created, add the screenshare stream last.
+    if (video_encoder_configs_[i].content_type ==
+        VideoEncoderConfig::ContentType::kScreen) {
+      streams_creation_order.push_back(i);
+    } else {
+      streams_creation_order.push_front(i);
+    }
+  }
+
+  video_send_streams_.resize(video_send_configs_.size(), nullptr);
+
+  for (size_t i : streams_creation_order) {
+    if (fec_controller_factory_.get()) {
+      video_send_streams_[i] = sender_call_->CreateVideoSendStream(
+          video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy(),
+          fec_controller_factory_->CreateFecController());
+    } else {
+      video_send_streams_[i] = sender_call_->CreateVideoSendStream(
+          video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy());
+    }
+  }
 }
 
 void CallTest::CreateVideoSendStream(const VideoEncoderConfig& encoder_config) {
-  RTC_DCHECK(video_send_stream_ == nullptr);
-  video_send_stream_ = sender_call_->CreateVideoSendStream(
-      GetVideoSendConfig()->Copy(), encoder_config.Copy());
+  RTC_DCHECK(video_send_streams_.empty());
+  video_send_streams_.push_back(sender_call_->CreateVideoSendStream(
+      GetVideoSendConfig()->Copy(), encoder_config.Copy()));
 }
 
 void CallTest::CreateAudioStreams() {
@@ -400,8 +527,9 @@
 }
 
 void CallTest::ConnectVideoSourcesToStreams() {
-  GetVideoSendStream()->SetSource(frame_generator_capturer_.get(),
-                                  degradation_preference_);
+  for (size_t i = 0; i < video_sources_.size(); ++i)
+    video_send_streams_[i]->SetSource(video_sources_[i],
+                                      degradation_preference_);
 }
 
 void CallTest::AssociateFlexfecStreamsWithVideoStreams() {
@@ -432,29 +560,37 @@
 }
 
 void CallTest::StartVideoStreams() {
-  if (video_send_stream_)
-    video_send_stream_->Start();
+  for (VideoSendStream* video_send_stream : video_send_streams_)
+    video_send_stream->Start();
   for (VideoReceiveStream* video_recv_stream : video_receive_streams_)
     video_recv_stream->Start();
 }
 
 void CallTest::StartVideoCapture() {
-  if (frame_generator_capturer_.get() != NULL)
-    frame_generator_capturer_->Start();
+  for (auto& capturer : video_capturers_)
+    capturer->Start();
 }
 
 void CallTest::Stop() {
-  if (frame_generator_capturer_.get() != NULL)
-    frame_generator_capturer_->Stop();
+  StopVideoCapture();
   for (AudioReceiveStream* audio_recv_stream : audio_receive_streams_)
     audio_recv_stream->Stop();
   if (audio_send_stream_) {
     audio_send_stream_->Stop();
   }
+  StopVideoStreams();
+}
+
+void CallTest::StopVideoCapture() {
+  for (auto& capturer : video_capturers_)
+    capturer->Stop();
+}
+
+void CallTest::StopVideoStreams() {
+  for (VideoSendStream* video_send_stream : video_send_streams_)
+    video_send_stream->Stop();
   for (VideoReceiveStream* video_recv_stream : video_receive_streams_)
     video_recv_stream->Stop();
-  if (video_send_stream_)
-    video_send_stream_->Stop();
 }
 
 void CallTest::DestroyStreams() {
@@ -479,9 +615,9 @@
 }
 
 void CallTest::DestroyVideoSendStreams() {
-  if (video_send_stream_)
-    sender_call_->DestroyVideoSendStream(video_send_stream_);
-  video_send_stream_ = nullptr;
+  for (VideoSendStream* video_send_stream : video_send_streams_)
+    sender_call_->DestroyVideoSendStream(video_send_stream);
+  video_send_streams_.clear();
 }
 
 void CallTest::SetFakeVideoCaptureRotation(VideoRotation rotation) {
@@ -489,27 +625,32 @@
 }
 
 void CallTest::SetVideoDegradation(DegradationPreference preference) {
-  GetVideoSendStream()->SetSource(frame_generator_capturer_.get(), preference);
+  GetVideoSendStream()->SetSource(frame_generator_capturer_, preference);
 }
 
 VideoSendStream::Config* CallTest::GetVideoSendConfig() {
-  return &video_send_config_;
+  return &video_send_configs_[0];
 }
 
 void CallTest::SetVideoSendConfig(const VideoSendStream::Config& config) {
-  video_send_config_ = config.Copy();
+  video_send_configs_.clear();
+  video_send_configs_.push_back(config.Copy());
 }
 
 VideoEncoderConfig* CallTest::GetVideoEncoderConfig() {
-  return &video_encoder_config_;
+  return &video_encoder_configs_[0];
 }
 
 void CallTest::SetVideoEncoderConfig(const VideoEncoderConfig& config) {
-  video_encoder_config_ = config.Copy();
+  video_encoder_configs_.clear();
+  video_encoder_configs_.push_back(config.Copy());
 }
 
 VideoSendStream* CallTest::GetVideoSendStream() {
-  return video_send_stream_;
+  return video_send_streams_[0];
+}
+FlexfecReceiveStream::Config* CallTest::GetFlexFecConfig() {
+  return &flexfec_receive_configs_[0];
 }
 
 constexpr size_t CallTest::kNumSsrcs;