Add tests for verifying transport feedback for audio and video.

BUG=webrtc:5263
R=mflodman@webrtc.org

Review URL: https://codereview.webrtc.org/1589523002 .

Cr-Commit-Position: refs/heads/master@{#11255}
diff --git a/webrtc/test/call_test.cc b/webrtc/test/call_test.cc
index 850e487..e9651e3 100644
--- a/webrtc/test/call_test.cc
+++ b/webrtc/test/call_test.cc
@@ -31,7 +31,7 @@
       audio_send_config_(nullptr),
       audio_send_stream_(nullptr),
       fake_encoder_(clock_),
-      num_video_streams_(0),
+      num_video_streams_(1),
       num_audio_streams_(0),
       fake_send_audio_device_(nullptr),
       fake_recv_audio_device_(nullptr) {}
@@ -60,9 +60,9 @@
     }
     CreateReceiverCall(recv_config);
   }
+  test->OnCallsCreated(sender_call_.get(), receiver_call_.get());
   send_transport_.reset(test->CreateSendTransport(sender_call_.get()));
   receive_transport_.reset(test->CreateReceiveTransport());
-  test->OnCallsCreated(sender_call_.get(), receiver_call_.get());
 
   if (test->ShouldCreateReceivers()) {
     send_transport_->SetReceiver(receiver_call_->Receiver());
@@ -97,8 +97,10 @@
     test->OnAudioStreamsCreated(audio_send_stream_, audio_receive_streams_);
   }
 
-  CreateFrameGeneratorCapturer();
-  test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get());
+  if (num_video_streams_ > 0) {
+    CreateFrameGeneratorCapturer();
+    test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get());
+  }
 
   Start();
   test->PerformTest();
@@ -179,17 +181,20 @@
   RTC_DCHECK(num_video_streams <= kNumSsrcs);
   RTC_DCHECK_LE(num_audio_streams, 1u);
   RTC_DCHECK(num_audio_streams == 0 || voe_send_.channel_id >= 0);
-  video_send_config_ = VideoSendStream::Config(send_transport);
-  video_send_config_.encoder_settings.encoder = &fake_encoder_;
-  video_send_config_.encoder_settings.payload_name = "FAKE";
-  video_send_config_.encoder_settings.payload_type = kFakeVideoSendPayloadType;
-  video_send_config_.rtp.extensions.push_back(
-      RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
-  video_encoder_config_.streams = test::CreateVideoStreams(num_video_streams);
-  for (size_t i = 0; i < num_video_streams; ++i)
-    video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[i]);
-  video_send_config_.rtp.extensions.push_back(
-      RtpExtension(RtpExtension::kVideoRotation, kVideoRotationRtpExtensionId));
+  if (num_video_streams > 0) {
+    video_send_config_ = VideoSendStream::Config(send_transport);
+    video_send_config_.encoder_settings.encoder = &fake_encoder_;
+    video_send_config_.encoder_settings.payload_name = "FAKE";
+    video_send_config_.encoder_settings.payload_type =
+        kFakeVideoSendPayloadType;
+    video_send_config_.rtp.extensions.push_back(
+        RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
+    video_encoder_config_.streams = test::CreateVideoStreams(num_video_streams);
+    for (size_t i = 0; i < num_video_streams; ++i)
+      video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[i]);
+    video_send_config_.rtp.extensions.push_back(RtpExtension(
+        RtpExtension::kVideoRotation, kVideoRotationRtpExtensionId));
+  }
 
   if (num_audio_streams > 0) {
     audio_send_config_ = AudioSendStream::Config(send_transport);
@@ -199,27 +204,29 @@
 }
 
 void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
-  RTC_DCHECK(!video_send_config_.rtp.ssrcs.empty());
   RTC_DCHECK(video_receive_configs_.empty());
   RTC_DCHECK(allocated_decoders_.empty());
-  RTC_DCHECK(num_audio_streams_ == 0 || voe_send_.channel_id >= 0);
-  VideoReceiveStream::Config video_config(rtcp_send_transport);
-  video_config.rtp.remb = true;
-  video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
-  for (const RtpExtension& extension : video_send_config_.rtp.extensions)
-    video_config.rtp.extensions.push_back(extension);
-  for (size_t i = 0; i < video_send_config_.rtp.ssrcs.size(); ++i) {
-    VideoReceiveStream::Decoder decoder =
-        test::CreateMatchingDecoder(video_send_config_.encoder_settings);
-    allocated_decoders_.push_back(decoder.decoder);
-    video_config.decoders.clear();
-    video_config.decoders.push_back(decoder);
-    video_config.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[i];
-    video_receive_configs_.push_back(video_config);
+  if (num_video_streams_ > 0) {
+    RTC_DCHECK(!video_send_config_.rtp.ssrcs.empty());
+    VideoReceiveStream::Config video_config(rtcp_send_transport);
+    video_config.rtp.remb = true;
+    video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
+    for (const RtpExtension& extension : video_send_config_.rtp.extensions)
+      video_config.rtp.extensions.push_back(extension);
+    for (size_t i = 0; i < video_send_config_.rtp.ssrcs.size(); ++i) {
+      VideoReceiveStream::Decoder decoder =
+          test::CreateMatchingDecoder(video_send_config_.encoder_settings);
+      allocated_decoders_.push_back(decoder.decoder);
+      video_config.decoders.clear();
+      video_config.decoders.push_back(decoder);
+      video_config.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[i];
+      video_receive_configs_.push_back(video_config);
+    }
   }
 
   RTC_DCHECK(num_audio_streams_ <= 1);
   if (num_audio_streams_ == 1) {
+    RTC_DCHECK(voe_send_.channel_id >= 0);
     AudioReceiveStream::Config audio_config;
     audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc;
     audio_config.rtcp_send_transport = rtcp_send_transport;
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 51d1d2c..48dc3e8 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -1542,82 +1542,115 @@
   tester.RunTest();
 }
 
-void TransportFeedbackTest(bool feedback_enabled) {
+class TransportFeedbackTester : public test::EndToEndTest {
+ public:
+  explicit TransportFeedbackTester(bool feedback_enabled,
+                                   size_t num_video_streams,
+                                   size_t num_audio_streams)
+      : EndToEndTest(::webrtc::EndToEndTest::kDefaultTimeoutMs),
+        feedback_enabled_(feedback_enabled),
+        num_video_streams_(num_video_streams),
+        num_audio_streams_(num_audio_streams) {
+    // Only one stream of each supported for now.
+    EXPECT_LE(num_video_streams, 1u);
+    EXPECT_LE(num_audio_streams, 1u);
+  }
+
+ protected:
+  Action OnSendRtcp(const uint8_t* data, size_t length) override {
+    EXPECT_FALSE(HasTransportFeedback(data, length));
+    return SEND_PACKET;
+  }
+
+  Action OnReceiveRtcp(const uint8_t* data, size_t length) override {
+    if (HasTransportFeedback(data, length))
+      observation_complete_.Set();
+    return SEND_PACKET;
+  }
+
+  bool HasTransportFeedback(const uint8_t* data, size_t length) const {
+    RTCPUtility::RTCPParserV2 parser(data, length, true);
+    EXPECT_TRUE(parser.IsValid());
+
+    RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
+    while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
+      if (packet_type == RTCPUtility::RTCPPacketTypes::kTransportFeedback)
+        return true;
+      packet_type = parser.Iterate();
+    }
+
+    return false;
+  }
+
+  void PerformTest() override {
+    const int64_t kDisabledFeedbackTimeoutMs = 5000;
+    EXPECT_EQ(feedback_enabled_,
+              observation_complete_.Wait(feedback_enabled_
+                                             ? test::CallTest::kDefaultTimeoutMs
+                                             : kDisabledFeedbackTimeoutMs));
+  }
+
+  void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
+    receiver_call_ = receiver_call;
+  }
+
+  size_t GetNumVideoStreams() const override { return num_video_streams_; }
+  size_t GetNumAudioStreams() const override { return num_audio_streams_; }
+
+  void ModifyVideoConfigs(
+      VideoSendStream::Config* send_config,
+      std::vector<VideoReceiveStream::Config>* receive_configs,
+      VideoEncoderConfig* encoder_config) override {
+    send_config->rtp.extensions.clear();
+    send_config->rtp.extensions.push_back(
+        RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
+    (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
+    (*receive_configs)[0].rtp.transport_cc = feedback_enabled_;
+  }
+
+  void ModifyAudioConfigs(
+      AudioSendStream::Config* send_config,
+      std::vector<AudioReceiveStream::Config>* receive_configs) override {
+    send_config->rtp.extensions.clear();
+    send_config->rtp.extensions.push_back(
+        RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
+    (*receive_configs)[0].rtp.extensions.clear();
+    (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
+    (*receive_configs)[0].rtp.transport_cc = feedback_enabled_;
+    (*receive_configs)[0].combined_audio_video_bwe = true;
+  }
+
+ private:
   static const int kExtensionId = 5;
-  class TransportFeedbackObserver : public test::DirectTransport {
-   public:
-    TransportFeedbackObserver(Call* receiver_call, rtc::Event* done_event)
-        : DirectTransport(receiver_call), done_(done_event) {}
-    virtual ~TransportFeedbackObserver() {}
+  const bool feedback_enabled_;
+  const size_t num_video_streams_;
+  const size_t num_audio_streams_;
+  Call* receiver_call_;
+};
 
-    bool SendRtcp(const uint8_t* data, size_t length) override {
-      RTCPUtility::RTCPParserV2 parser(data, length, true);
-      EXPECT_TRUE(parser.IsValid());
-
-      RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
-      while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
-        if (packet_type == RTCPUtility::RTCPPacketTypes::kTransportFeedback) {
-          done_->Set();
-          break;
-        }
-        packet_type = parser.Iterate();
-      }
-
-      return test::DirectTransport::SendRtcp(data, length);
-    }
-
-    rtc::Event* done_;
-  };
-
-  class TransportFeedbackTester : public MultiStreamTest {
-   public:
-    explicit TransportFeedbackTester(bool feedback_enabled)
-        : feedback_enabled_(feedback_enabled), done_(false, false) {}
-    virtual ~TransportFeedbackTester() {}
-
-   protected:
-    void Wait() override {
-      const int64_t kDisabledFeedbackTimeoutMs = 5000;
-      EXPECT_EQ(feedback_enabled_, done_.Wait(feedback_enabled_
-                                  ? test::CallTest::kDefaultTimeoutMs
-                                  : kDisabledFeedbackTimeoutMs));
-    }
-
-    void UpdateSendConfig(
-        size_t stream_index,
-        VideoSendStream::Config* send_config,
-        VideoEncoderConfig* encoder_config,
-        test::FrameGeneratorCapturer** frame_generator) override {
-      send_config->rtp.extensions.push_back(
-          RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
-    }
-
-    void UpdateReceiveConfig(
-        size_t stream_index,
-        VideoReceiveStream::Config* receive_config) override {
-      receive_config->rtp.extensions.push_back(
-          RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
-      receive_config->rtp.transport_cc = feedback_enabled_;
-    }
-
-    test::DirectTransport* CreateReceiveTransport(
-        Call* receiver_call) override {
-      return new TransportFeedbackObserver(receiver_call, &done_);
-    }
-
-   private:
-    const bool feedback_enabled_;
-    rtc::Event done_;
-  } tester(feedback_enabled);
-  tester.RunTest();
+TEST_F(EndToEndTest, VideoReceivesTransportFeedback) {
+  TransportFeedbackTester test(true, 1, 0);
+  RunBaseTest(&test);
 }
 
-TEST_F(EndToEndTest, ReceivesTransportFeedback) {
-  TransportFeedbackTest(true);
+TEST_F(EndToEndTest, VideoTransportFeedbackNotConfigured) {
+  TransportFeedbackTester test(false, 1, 0);
+  RunBaseTest(&test);
 }
 
-TEST_F(EndToEndTest, TransportFeedbackNotConfigured) {
-  TransportFeedbackTest(false);
+TEST_F(EndToEndTest, AudioReceivesTransportFeedback) {
+  TransportFeedbackTester test(true, 0, 1);
+  RunBaseTest(&test);
+}
+
+TEST_F(EndToEndTest, AudioTransportFeedbackNotConfigured) {
+  TransportFeedbackTester test(false, 0, 1);
+  RunBaseTest(&test);
+}
+
+TEST_F(EndToEndTest, AudioVideoReceivesTransportFeedback) {
+  TransportFeedbackTester test(true, 1, 1);
+  RunBaseTest(&test);
 }
 
 TEST_F(EndToEndTest, ObserversEncodedFrames) {