Add FlexFEC to CallTest.

This is needed for the following coming tests: VideoSendStream, end-to-end,
full stack, and video_loopback.

BUG=webrtc:5654

Review-Url: https://codereview.webrtc.org/2500943002
Cr-Commit-Position: refs/heads/master@{#15087}
diff --git a/webrtc/call/call_perf_tests.cc b/webrtc/call/call_perf_tests.cc
index 39c333e..ed1eb09 100644
--- a/webrtc/call/call_perf_tests.cc
+++ b/webrtc/call/call_perf_tests.cc
@@ -213,7 +213,7 @@
 
   test::FakeDecoder fake_decoder;
 
-  CreateSendConfig(1, 0, &video_send_transport);
+  CreateSendConfig(1, 0, 0, &video_send_transport);
   CreateMatchingReceiveConfigs(&receive_transport);
 
   AudioSendStream::Config audio_send_config(&audio_send_transport);
diff --git a/webrtc/call/packet_injection_tests.cc b/webrtc/call/packet_injection_tests.cc
index df19cf3..10de8f6 100644
--- a/webrtc/call/packet_injection_tests.cc
+++ b/webrtc/call/packet_injection_tests.cc
@@ -42,7 +42,7 @@
   CreateReceiverCall(Call::Config(&event_log_));
 
   test::NullTransport null_transport;
-  CreateSendConfig(1, 0, &null_transport);
+  CreateSendConfig(1, 0, 0, &null_transport);
   CreateMatchingReceiveConfigs(&null_transport);
   video_receive_configs_[0].decoders[0].payload_type = payload_type;
   switch (codec_type) {
diff --git a/webrtc/test/call_test.cc b/webrtc/test/call_test.cc
index be43743..ddff552 100644
--- a/webrtc/test/call_test.cc
+++ b/webrtc/test/call_test.cc
@@ -7,10 +7,14 @@
  *  in the file PATENTS.  All contributing project authors may
  *  be found in the AUTHORS file in the root of the source tree.
  */
+
+#include "webrtc/test/call_test.h"
+
+#include <algorithm>
+
 #include "webrtc/base/checks.h"
 #include "webrtc/config.h"
 #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
-#include "webrtc/test/call_test.h"
 #include "webrtc/test/testsupport/fileutils.h"
 #include "webrtc/voice_engine/include/voe_base.h"
 
@@ -30,6 +34,7 @@
       fake_encoder_(clock_),
       num_video_streams_(1),
       num_audio_streams_(0),
+      num_flexfec_streams_(0),
       decoder_factory_(CreateBuiltinAudioDecoderFactory()),
       fake_send_audio_device_(nullptr),
       fake_recv_audio_device_(nullptr) {}
@@ -40,6 +45,7 @@
 void CallTest::RunBaseTest(BaseTest* test) {
   num_video_streams_ = test->GetNumVideoStreams();
   num_audio_streams_ = test->GetNumAudioStreams();
+  num_flexfec_streams_ = test->GetNumFlexfecStreams();
   RTC_DCHECK(num_video_streams_ > 0 || num_audio_streams_ > 0);
   Call::Config send_config(test->GetSenderCallConfig());
   if (num_audio_streams_ > 0) {
@@ -71,7 +77,7 @@
     receive_transport_->SetReceiver(nullptr);
   }
 
-  CreateSendConfig(num_video_streams_, num_audio_streams_,
+  CreateSendConfig(num_video_streams_, num_audio_streams_, num_flexfec_streams_,
                    send_transport_.get());
   if (test->ShouldCreateReceivers()) {
     CreateMatchingReceiveConfigs(receive_transport_.get());
@@ -80,8 +86,12 @@
     test->ModifyVideoConfigs(&video_send_config_, &video_receive_configs_,
                              &video_encoder_config_);
   }
-  if (num_audio_streams_ > 0)
+  if (num_audio_streams_ > 0) {
     test->ModifyAudioConfigs(&audio_send_config_, &audio_receive_configs_);
+  }
+  if (num_flexfec_streams_ > 0) {
+    test->ModifyFlexfecConfigs(&flexfec_receive_configs_);
+  }
 
   if (num_video_streams_ > 0) {
     CreateVideoStreams();
@@ -91,6 +101,10 @@
     CreateAudioStreams();
     test->OnAudioStreamsCreated(audio_send_stream_, audio_receive_streams_);
   }
+  if (num_flexfec_streams_ > 0) {
+    CreateFlexfecStreams();
+    test->OnFlexfecStreamsCreated(flexfec_receive_streams_);
+  }
 
   if (num_video_streams_ > 0) {
     int width = kDefaultWidth;
@@ -129,6 +143,8 @@
     fake_recv_audio_device_->Start();
     EXPECT_EQ(0, voe_recv_.base->StartPlayout(voe_recv_.channel_id));
   }
+  for (FlexfecReceiveStream* flexfec_recv_stream : flexfec_receive_streams_)
+    flexfec_recv_stream->Start();
   if (frame_generator_capturer_.get() != NULL)
     frame_generator_capturer_->Start();
 }
@@ -136,6 +152,8 @@
 void CallTest::Stop() {
   if (frame_generator_capturer_.get() != NULL)
     frame_generator_capturer_->Stop();
+  for (FlexfecReceiveStream* flexfec_recv_stream : flexfec_receive_streams_)
+    flexfec_recv_stream->Stop();
   if (!audio_receive_streams_.empty()) {
     fake_recv_audio_device_->Stop();
     EXPECT_EQ(0, voe_recv_.base->StopPlayout(voe_recv_.channel_id));
@@ -174,9 +192,11 @@
 
 void CallTest::CreateSendConfig(size_t num_video_streams,
                                 size_t num_audio_streams,
+                                size_t num_flexfec_streams,
                                 Transport* send_transport) {
   RTC_DCHECK(num_video_streams <= kNumSsrcs);
   RTC_DCHECK_LE(num_audio_streams, 1u);
+  RTC_DCHECK_LE(num_flexfec_streams, 1u);
   RTC_DCHECK(num_audio_streams == 0 || voe_send_.channel_id >= 0);
   if (num_video_streams > 0) {
     video_send_config_ = VideoSendStream::Config(send_transport);
@@ -201,6 +221,13 @@
     audio_send_config_.send_codec_spec.codec_inst =
         CodecInst{kAudioSendPayloadType, "ISAC", 16000, 480, 1, 32000};
   }
+
+  // TODO(brandtr): Update this when we support multistream protection.
+  if (num_flexfec_streams > 0) {
+    video_send_config_.rtp.flexfec.flexfec_payload_type = kFlexfecPayloadType;
+    video_send_config_.rtp.flexfec.flexfec_ssrc = kFlexfecSendSsrc;
+    video_send_config_.rtp.flexfec.protected_media_ssrcs = {kVideoSendSsrcs[0]};
+  }
 }
 
 void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
@@ -237,6 +264,16 @@
     audio_config.decoder_factory = decoder_factory_;
     audio_receive_configs_.push_back(audio_config);
   }
+
+  // TODO(brandtr): Update this when we support multistream protection.
+  RTC_DCHECK(num_flexfec_streams_ <= 1);
+  if (num_flexfec_streams_ == 1) {
+    FlexfecReceiveStream::Config flexfec_config;
+    flexfec_config.flexfec_payload_type = kFlexfecPayloadType;
+    flexfec_config.flexfec_ssrc = kFlexfecSendSsrc;
+    flexfec_config.protected_media_ssrcs = {kVideoSendSsrcs[0]};
+    flexfec_receive_configs_.push_back(flexfec_config);
+  }
 }
 
 void CallTest::CreateFrameGeneratorCapturerWithDrift(Clock* clock,
@@ -296,6 +333,14 @@
   }
 }
 
+void CallTest::CreateFlexfecStreams() {
+  for (size_t i = 0; i < flexfec_receive_configs_.size(); ++i) {
+    flexfec_receive_streams_.push_back(
+        receiver_call_->CreateFlexfecReceiveStream(
+            flexfec_receive_configs_[i]));
+  }
+}
+
 void CallTest::DestroyStreams() {
   if (video_send_stream_)
     sender_call_->DestroyVideoSendStream(video_send_stream_);
@@ -308,8 +353,11 @@
   audio_send_stream_ = nullptr;
   for (AudioReceiveStream* audio_recv_stream : audio_receive_streams_)
     receiver_call_->DestroyAudioReceiveStream(audio_recv_stream);
-  video_receive_streams_.clear();
 
+  for (FlexfecReceiveStream* flexfec_recv_stream : flexfec_receive_streams_)
+    receiver_call_->DestroyFlexfecReceiveStream(flexfec_recv_stream);
+
+  video_receive_streams_.clear();
   allocated_decoders_.clear();
 }
 
@@ -360,12 +408,14 @@
 const uint8_t CallTest::kRedPayloadType = 118;
 const uint8_t CallTest::kRtxRedPayloadType = 99;
 const uint8_t CallTest::kUlpfecPayloadType = 119;
+const uint8_t CallTest::kFlexfecPayloadType = 120;
 const uint8_t CallTest::kAudioSendPayloadType = 103;
 const uint32_t CallTest::kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE,
                                                      0xBADCAFF};
 const uint32_t CallTest::kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE,
                                                        0xC0FFEF};
 const uint32_t CallTest::kAudioSendSsrc = 0xDEADBEEF;
+const uint32_t CallTest::kFlexfecSendSsrc = 0xBADBEEF;
 const uint32_t CallTest::kReceiverLocalVideoSsrc = 0x123456;
 const uint32_t CallTest::kReceiverLocalAudioSsrc = 0x1234567;
 const int CallTest::kNackRtpHistoryMs = 1000;
@@ -405,6 +455,10 @@
   return 0;
 }
 
+size_t BaseTest::GetNumFlexfecStreams() const {
+  return 0;
+}
+
 void BaseTest::ModifyVideoConfigs(
     VideoSendStream::Config* send_config,
     std::vector<VideoReceiveStream::Config>* receive_configs,
@@ -426,6 +480,12 @@
     AudioSendStream* send_stream,
     const std::vector<AudioReceiveStream*>& receive_streams) {}
 
+void BaseTest::ModifyFlexfecConfigs(
+    std::vector<FlexfecReceiveStream::Config>* receive_configs) {}
+
+void BaseTest::OnFlexfecStreamsCreated(
+    const std::vector<FlexfecReceiveStream*>& receive_streams) {}
+
 void BaseTest::OnFrameGeneratorCapturerCreated(
     FrameGeneratorCapturer* frame_generator_capturer) {
 }
diff --git a/webrtc/test/call_test.h b/webrtc/test/call_test.h
index 74a5451..5843f7b 100644
--- a/webrtc/test/call_test.h
+++ b/webrtc/test/call_test.h
@@ -48,12 +48,15 @@
   static const uint8_t kRedPayloadType;
   static const uint8_t kRtxRedPayloadType;
   static const uint8_t kUlpfecPayloadType;
+  static const uint8_t kFlexfecPayloadType;
   static const uint8_t kAudioSendPayloadType;
   static const uint32_t kSendRtxSsrcs[kNumSsrcs];
   static const uint32_t kVideoSendSsrcs[kNumSsrcs];
   static const uint32_t kAudioSendSsrc;
+  static const uint32_t kFlexfecSendSsrc;
   static const uint32_t kReceiverLocalVideoSsrc;
   static const uint32_t kReceiverLocalAudioSsrc;
+  static const uint32_t kReceiverLocalFlexfecSsrc;
   static const int kNackRtpHistoryMs;
 
  protected:
@@ -70,6 +73,7 @@
 
   void CreateSendConfig(size_t num_video_streams,
                         size_t num_audio_streams,
+                        size_t num_flexfec_streams,
                         Transport* send_transport);
   void CreateMatchingReceiveConfigs(Transport* rtcp_send_transport);
 
@@ -83,6 +87,7 @@
 
   void CreateVideoStreams();
   void CreateAudioStreams();
+  void CreateFlexfecStreams();
   void Start();
   void Stop();
   void DestroyStreams();
@@ -105,12 +110,15 @@
   std::vector<VideoReceiveStream*> video_receive_streams_;
   std::vector<AudioReceiveStream::Config> audio_receive_configs_;
   std::vector<AudioReceiveStream*> audio_receive_streams_;
+  std::vector<FlexfecReceiveStream::Config> flexfec_receive_configs_;
+  std::vector<FlexfecReceiveStream*> flexfec_receive_streams_;
 
   std::unique_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
   test::FakeEncoder fake_encoder_;
   std::vector<std::unique_ptr<VideoDecoder>> allocated_decoders_;
   size_t num_video_streams_;
   size_t num_audio_streams_;
+  size_t num_flexfec_streams_;
   rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
   test::FakeVideoRenderer fake_renderer_;
 
@@ -150,6 +158,7 @@
 
   virtual size_t GetNumVideoStreams() const;
   virtual size_t GetNumAudioStreams() const;
+  virtual size_t GetNumFlexfecStreams() const;
 
   virtual Call::Config GetSenderCallConfig();
   virtual Call::Config GetReceiverCallConfig();
@@ -176,6 +185,11 @@
       AudioSendStream* send_stream,
       const std::vector<AudioReceiveStream*>& receive_streams);
 
+  virtual void ModifyFlexfecConfigs(
+      std::vector<FlexfecReceiveStream::Config>* receive_configs);
+  virtual void OnFlexfecStreamsCreated(
+      const std::vector<FlexfecReceiveStream*>& receive_streams);
+
   virtual void OnFrameGeneratorCapturerCreated(
       FrameGeneratorCapturer* frame_generator_capturer);
 
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index fcd3c5c..52ff43e 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -134,7 +134,7 @@
   CreateCalls(Call::Config(&event_log_), Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   CreateMatchingReceiveConfigs(&transport);
 
   CreateVideoStreams();
@@ -149,7 +149,7 @@
   CreateCalls(Call::Config(&event_log_), Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   CreateMatchingReceiveConfigs(&transport);
 
   CreateVideoStreams();
@@ -164,7 +164,7 @@
   CreateCalls(Call::Config(&event_log_), Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   CreateMatchingReceiveConfigs(&transport);
 
   CreateVideoStreams();
@@ -217,7 +217,7 @@
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
-  CreateSendConfig(1, 0, &sender_transport);
+  CreateSendConfig(1, 0, 0, &sender_transport);
   CreateMatchingReceiveConfigs(&receiver_transport);
 
   TestFrameCallback pre_render_callback;
@@ -268,7 +268,7 @@
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
-  CreateSendConfig(1, 0, &sender_transport);
+  CreateSendConfig(1, 0, 0, &sender_transport);
   CreateMatchingReceiveConfigs(&receiver_transport);
   video_receive_configs_[0].renderer = &renderer;
 
@@ -1105,7 +1105,7 @@
   send_transport.SetReceiver(&input_observer);
   receive_transport.SetReceiver(sender_call_->Receiver());
 
-  CreateSendConfig(1, 0, &send_transport);
+  CreateSendConfig(1, 0, 0, &send_transport);
   CreateMatchingReceiveConfigs(&receive_transport);
 
   CreateVideoStreams();
@@ -1728,7 +1728,7 @@
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
-  CreateSendConfig(1, 0, &sender_transport);
+  CreateSendConfig(1, 0, 0, &sender_transport);
   CreateMatchingReceiveConfigs(&receiver_transport);
   video_send_config_.post_encode_callback = &post_encode_observer;
   video_receive_configs_[0].pre_decode_callback = &pre_decode_observer;
@@ -3264,7 +3264,7 @@
   send_transport.SetReceiver(receiver_call_->Receiver());
   receive_transport.SetReceiver(sender_call_->Receiver());
 
-  CreateSendConfig(kNumSsrcs, 0, &send_transport);
+  CreateSendConfig(kNumSsrcs, 0, 0, &send_transport);
 
   if (use_rtx) {
     for (size_t i = 0; i < kNumSsrcs; ++i) {
@@ -3558,7 +3558,7 @@
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
-  CreateSendConfig(1, 0, &sender_transport);
+  CreateSendConfig(1, 0, 0, &sender_transport);
   CreateMatchingReceiveConfigs(&receiver_transport);
 
   CreateVideoStreams();
@@ -3593,7 +3593,7 @@
   CreateSenderCall(Call::Config(&event_log_));
   sender_call_->SignalChannelNetworkState(network_to_bring_down, kNetworkDown);
 
-  CreateSendConfig(1, 0, transport);
+  CreateSendConfig(1, 0, 0, transport);
   video_send_config_.encoder_settings.encoder = encoder;
   CreateVideoStreams();
   CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
@@ -3616,7 +3616,7 @@
 
   test::DirectTransport sender_transport(sender_call_.get());
   sender_transport.SetReceiver(receiver_call_->Receiver());
-  CreateSendConfig(1, 0, &sender_transport);
+  CreateSendConfig(1, 0, 0, &sender_transport);
   CreateMatchingReceiveConfigs(transport);
   CreateVideoStreams();
   CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc
index a3a1cf8..7186fed 100644
--- a/webrtc/video/video_quality_test.cc
+++ b/webrtc/video/video_quality_test.cc
@@ -1001,7 +1001,7 @@
     trace_to_stderr_.reset(new test::TraceToStderr);
 
   size_t num_streams = params_.ss.streams.size();
-  CreateSendConfig(num_streams, 0, send_transport);
+  CreateSendConfig(num_streams, 0, 0, send_transport);
 
   int payload_type;
   if (params_.video.codec == "H264") {
diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc
index 088bdf5..f6112f9 100644
--- a/webrtc/video/video_send_stream_tests.cc
+++ b/webrtc/video/video_send_stream_tests.cc
@@ -65,7 +65,7 @@
   CreateSenderCall(Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   CreateVideoStreams();
   video_send_stream_->Start();
   video_send_stream_->Start();
@@ -76,7 +76,7 @@
   CreateSenderCall(Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   CreateVideoStreams();
   video_send_stream_->Stop();
   video_send_stream_->Stop();
@@ -1517,7 +1517,7 @@
 
   CreateSenderCall(Call::Config(&event_log_));
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   EncoderObserver encoder;
   video_send_config_.encoder_settings.encoder = &encoder;
   CreateVideoStreams();
@@ -1574,7 +1574,7 @@
   CreateSenderCall(Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
 
   Call::Config::BitrateConfig bitrate_config;
   bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
@@ -1655,7 +1655,7 @@
   CreateSenderCall(Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
 
   StartStopBitrateObserver encoder;
   video_send_config_.encoder_settings.encoder = &encoder;
@@ -1710,7 +1710,7 @@
   CreateSenderCall(Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   FrameObserver observer;
   video_send_config_.pre_encode_callback = &observer;
   CreateVideoStreams();
@@ -2965,7 +2965,7 @@
   CreateSenderCall(Call::Config(&event_log_));
 
   test::NullTransport transport;
-  CreateSendConfig(1, 0, &transport);
+  CreateSendConfig(1, 0, 0, &transport);
   video_send_config_.rtp.extensions.clear();
   if (support_orientation_ext) {
     video_send_config_.rtp.extensions.push_back(