Refactor PeerConnectionIntegrationTest to not use cricket::VideoCapturer

Bug: webrtc:6353
Change-Id: Ie3f6411d8e21eaad6927c94af126213e650994ca
Reviewed-on: https://webrtc-review.googlesource.com/74587
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23203}
diff --git a/media/base/fakeframesource.cc b/media/base/fakeframesource.cc
index f03dd83..ffc3eee 100644
--- a/media/base/fakeframesource.cc
+++ b/media/base/fakeframesource.cc
@@ -11,6 +11,7 @@
 #include "media/base/fakeframesource.h"
 
 #include "api/video/i420_buffer.h"
+#include "rtc_base/checks.h"
 
 namespace cricket {
 
@@ -21,7 +22,7 @@
   RTC_CHECK_GT(interval_us_, 0);
 }
 
-webrtc::VideoRotation FakeFrameSource::GetRotation() {
+webrtc::VideoRotation FakeFrameSource::GetRotation() const {
   return rotation_;
 }
 
@@ -29,12 +30,28 @@
   rotation_ = rotation;
 }
 
+webrtc::VideoFrame FakeFrameSource::GetFrameRotationApplied() {
+  switch (rotation_) {
+    case webrtc::kVideoRotation_0:
+    case webrtc::kVideoRotation_180:
+      return GetFrame(width_, height_, webrtc::kVideoRotation_0, interval_us_);
+    case webrtc::kVideoRotation_90:
+    case webrtc::kVideoRotation_270:
+      return GetFrame(height_, width_, webrtc::kVideoRotation_0, interval_us_);
+  }
+  RTC_NOTREACHED() << "Invalid rotation value: " << static_cast<int>(rotation_);
+  // Without this return, the Windows Visual Studio compiler complains
+  // "not all control paths return a value".
+  return GetFrame();
+}
+
 webrtc::VideoFrame FakeFrameSource::GetFrame() {
-  return GetFrame(width_, height_, interval_us_);
+  return GetFrame(width_, height_, rotation_, interval_us_);
 }
 
 webrtc::VideoFrame FakeFrameSource::GetFrame(int width,
                                              int height,
+                                             webrtc::VideoRotation rotation,
                                              int interval_us) {
   RTC_CHECK_GT(width, 0);
   RTC_CHECK_GT(height, 0);
@@ -45,7 +62,7 @@
 
   buffer->InitializeData();
   webrtc::VideoFrame frame =
-      webrtc::VideoFrame(buffer, rotation_, next_timestamp_us_);
+      webrtc::VideoFrame(buffer, rotation, next_timestamp_us_);
 
   next_timestamp_us_ += interval_us;
   return frame;
diff --git a/media/base/fakeframesource.h b/media/base/fakeframesource.h
index b9ac4a7..db44045 100644
--- a/media/base/fakeframesource.h
+++ b/media/base/fakeframesource.h
@@ -21,12 +21,17 @@
  public:
   FakeFrameSource(int width, int height, int interval_us);
 
-  webrtc::VideoRotation GetRotation();
+  webrtc::VideoRotation GetRotation() const;
   void SetRotation(webrtc::VideoRotation rotation);
 
   webrtc::VideoFrame GetFrame();
-  // Override default size and interval.
-  webrtc::VideoFrame GetFrame(int width, int height, int interval_us);
+  webrtc::VideoFrame GetFrameRotationApplied();
+
+  // Override configuration.
+  webrtc::VideoFrame GetFrame(int width,
+                              int height,
+                              webrtc::VideoRotation rotation,
+                              int interval_us);
 
  private:
   const int width_;
diff --git a/media/base/fakevideocapturer.cc b/media/base/fakevideocapturer.cc
index 80021e5..845cceb 100644
--- a/media/base/fakevideocapturer.cc
+++ b/media/base/fakevideocapturer.cc
@@ -53,8 +53,8 @@
   // Default to 30fps.
   // TODO(nisse): Would anything break if we always stick to
   // the configure frame interval?
-  return CaptureFrame(
-      frame_source_->GetFrame(width, height, rtc::kNumMicrosecsPerSec / 30));
+  return CaptureFrame(frame_source_->GetFrame(width, height, rotation_,
+                                              rtc::kNumMicrosecsPerSec / 30));
 }
 
 bool FakeVideoCapturer::CaptureFrame(const webrtc::VideoFrame& frame) {
diff --git a/pc/peerconnection_integrationtest.cc b/pc/peerconnection_integrationtest.cc
index 969fc80..e5f3ad4 100644
--- a/pc/peerconnection_integrationtest.cc
+++ b/pc/peerconnection_integrationtest.cc
@@ -48,7 +48,7 @@
 #include "pc/rtpmediautils.h"
 #include "pc/sessiondescription.h"
 #include "pc/test/fakeaudiocapturemodule.h"
-#include "pc/test/fakeperiodicvideocapturer.h"
+#include "pc/test/fakeperiodicvideosource.h"
 #include "pc/test/fakertccertificategenerator.h"
 #include "pc/test/fakevideotrackrenderer.h"
 #include "pc/test/mockpeerconnectionobservers.h"
@@ -238,6 +238,20 @@
     return client;
   }
 
+  ~PeerConnectionWrapper() {
+    // Tear down video sources in the proper order.
+    for (const auto& video_source : fake_video_sources_) {
+      // No more calls to downstream OnFrame
+      video_source->Stop();
+    }
+    for (const auto& track_source : video_track_sources_) {
+      // No more calls to upstream AddOrUpdateSink
+      track_source->OnSourceDestroyed();
+    }
+    fake_video_sources_.clear();
+    video_track_sources_.clear();
+  }
+
   webrtc::PeerConnectionFactoryInterface* pc_factory() const {
     return peer_connection_factory_.get();
   }
@@ -325,18 +339,21 @@
   }
 
   rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
-    return CreateLocalVideoTrackInternal(FakeConstraints(),
-                                         webrtc::kVideoRotation_0);
+    return CreateLocalVideoTrackInternal(
+        webrtc::FakePeriodicVideoSource::Config());
   }
 
   rtc::scoped_refptr<webrtc::VideoTrackInterface>
-  CreateLocalVideoTrackWithConstraints(const FakeConstraints& constraints) {
-    return CreateLocalVideoTrackInternal(constraints, webrtc::kVideoRotation_0);
+  CreateLocalVideoTrackWithConfig(
+      webrtc::FakePeriodicVideoSource::Config config) {
+    return CreateLocalVideoTrackInternal(config);
   }
 
   rtc::scoped_refptr<webrtc::VideoTrackInterface>
   CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
-    return CreateLocalVideoTrackInternal(FakeConstraints(), rotation);
+    webrtc::FakePeriodicVideoSource::Config config;
+    config.rotation = rotation;
+    return CreateLocalVideoTrackInternal(config);
   }
 
   rtc::scoped_refptr<RtpSenderInterface> AddTrack(
@@ -679,23 +696,20 @@
   }
 
   rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
-      const FakeConstraints& constraints,
-      webrtc::VideoRotation rotation) {
+      webrtc::FakePeriodicVideoSource::Config config) {
     // Set max frame rate to 10fps to reduce the risk of test flakiness.
     // TODO(deadbeef): Do something more robust.
-    FakeConstraints source_constraints = constraints;
-    source_constraints.SetMandatoryMaxFrameRate(10);
+    config.frame_interval_ms = 100;
 
-    cricket::FakeVideoCapturer* fake_capturer =
-        new webrtc::FakePeriodicVideoCapturer();
-    fake_capturer->SetRotation(rotation);
-    video_capturers_.push_back(fake_capturer);
-    rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source =
-        peer_connection_factory_->CreateVideoSource(fake_capturer,
-                                                    &source_constraints);
+    fake_video_sources_.emplace_back(
+        rtc::MakeUnique<webrtc::FakePeriodicVideoSource>(config));
+
+    video_track_sources_.emplace_back(
+        new rtc::RefCountedObject<webrtc::VideoTrackSource>(
+            fake_video_sources_.back().get(), false /* remote */));
     rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
-        peer_connection_factory_->CreateVideoTrack(rtc::CreateRandomUuid(),
-                                                   source));
+        peer_connection_factory_->CreateVideoTrack(
+            rtc::CreateRandomUuid(), video_track_sources_.back()));
     if (!local_video_renderer_) {
       local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
     }
@@ -975,9 +989,12 @@
   int signaling_delay_ms_ = 0;
   bool signal_ice_candidates_ = true;
 
-  // Store references to the video capturers we've created, so that we can stop
+  // Store references to the video sources we've created, so that we can stop
   // them, if required.
-  std::vector<cricket::FakeVideoCapturer*> video_capturers_;
+  std::vector<std::unique_ptr<webrtc::FakePeriodicVideoSource>>
+      fake_video_sources_;
+  std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
+      video_track_sources_;
   // |local_video_renderer_| attached to the first created local video track.
   std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
 
@@ -1750,35 +1767,6 @@
             remote_cert->ToPEMString());
 }
 
-// This test sets up a call between two parties (using DTLS) and tests that we
-// can get a video aspect ratio of 16:9.
-TEST_P(PeerConnectionIntegrationTest, SendAndReceive16To9AspectRatio) {
-  ASSERT_TRUE(CreatePeerConnectionWrappers());
-  ConnectFakeSignaling();
-
-  // Add video tracks with 16:9 constraint.
-  FakeConstraints constraints;
-  double requested_ratio = 16.0 / 9;
-  constraints.SetMandatoryMinAspectRatio(requested_ratio);
-  caller()->AddTrack(
-      caller()->CreateLocalVideoTrackWithConstraints(constraints));
-  callee()->AddTrack(
-      callee()->CreateLocalVideoTrackWithConstraints(constraints));
-
-  // Do normal offer/answer and wait for at least one frame to be received in
-  // each direction.
-  caller()->CreateAndSetAndSignalOffer();
-  ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
-                       callee()->min_video_frames_received_per_track() > 0,
-                   kMaxWaitForFramesMs);
-
-  // Check rendered aspect ratio.
-  EXPECT_EQ(requested_ratio, caller()->local_rendered_aspect_ratio());
-  EXPECT_EQ(requested_ratio, caller()->rendered_aspect_ratio());
-  EXPECT_EQ(requested_ratio, callee()->local_rendered_aspect_ratio());
-  EXPECT_EQ(requested_ratio, callee()->rendered_aspect_ratio());
-}
-
 // This test sets up a call between two parties with a source resolution of
 // 1280x720 and verifies that a 16:9 aspect ratio is received.
 TEST_P(PeerConnectionIntegrationTest,
@@ -1786,15 +1774,12 @@
   ASSERT_TRUE(CreatePeerConnectionWrappers());
   ConnectFakeSignaling();
 
-  // Similar to above test, but uses MandatoryMin[Width/Height] constraint
-  // instead of aspect ratio constraint.
-  FakeConstraints constraints;
-  constraints.SetMandatoryMinWidth(1280);
-  constraints.SetMandatoryMinHeight(720);
-  caller()->AddTrack(
-      caller()->CreateLocalVideoTrackWithConstraints(constraints));
-  callee()->AddTrack(
-      callee()->CreateLocalVideoTrackWithConstraints(constraints));
+  // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
+  webrtc::FakePeriodicVideoSource::Config config;
+  config.width = 1280;
+  config.height = 720;
+  caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
+  callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
 
   // Do normal offer/answer and wait for at least one frame to be received in
   // each direction.
diff --git a/pc/test/fakeperiodicvideosource.h b/pc/test/fakeperiodicvideosource.h
index fd5a3da..6207635 100644
--- a/pc/test/fakeperiodicvideosource.h
+++ b/pc/test/fakeperiodicvideosource.h
@@ -24,15 +24,23 @@
 class FakePeriodicVideoSource final
     : public rtc::VideoSourceInterface<VideoFrame> {
  public:
-  static constexpr int kFrameIntervalMs = 33;
-  static constexpr int kWidth = 640;
-  static constexpr int kHeight = 480;
+  static constexpr int kDefaultFrameIntervalMs = 33;
+  static constexpr int kDefaultWidth = 640;
+  static constexpr int kDefaultHeight = 480;
 
-  FakePeriodicVideoSource()
+  struct Config {
+    int width = kDefaultWidth;
+    int height = kDefaultHeight;
+    int frame_interval_ms = kDefaultFrameIntervalMs;
+    VideoRotation rotation = kVideoRotation_0;
+  };
+
+  FakePeriodicVideoSource() : FakePeriodicVideoSource(Config()) {}
+  explicit FakePeriodicVideoSource(Config config)
       : task_queue_(
             rtc::MakeUnique<rtc::TaskQueue>("FakePeriodicVideoTrackSource")) {
     thread_checker_.DetachFromThread();
-    task_queue_->PostTask(rtc::MakeUnique<FrameTask>(&broadcaster_));
+    task_queue_->PostTask(rtc::MakeUnique<FrameTask>(config, &broadcaster_));
   }
 
   void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override {
@@ -54,23 +62,32 @@
  private:
   class FrameTask : public rtc::QueuedTask {
    public:
-    explicit FrameTask(rtc::VideoSinkInterface<VideoFrame>* sink)
-        : frame_source_(kWidth,
-                        kHeight,
-                        kFrameIntervalMs * rtc::kNumMicrosecsPerMillisec),
-          sink_(sink) {}
+    FrameTask(Config config, rtc::VideoBroadcaster* broadcaster)
+        : frame_interval_ms_(config.frame_interval_ms),
+          frame_source_(
+              config.width,
+              config.height,
+              config.frame_interval_ms * rtc::kNumMicrosecsPerMillisec),
+          broadcaster_(broadcaster) {
+      frame_source_.SetRotation(config.rotation);
+    }
 
     bool Run() override {
-      sink_->OnFrame(frame_source_.GetFrame());
+      if (broadcaster_->wants().rotation_applied) {
+        broadcaster_->OnFrame(frame_source_.GetFrameRotationApplied());
+      } else {
+        broadcaster_->OnFrame(frame_source_.GetFrame());
+      }
+
       rtc::TaskQueue::Current()->PostDelayedTask(rtc::WrapUnique(this),
-                                                 kFrameIntervalMs);
+                                                 frame_interval_ms_);
       return false;
     }
+    int frame_interval_ms_;
     cricket::FakeFrameSource frame_source_;
-    rtc::VideoSinkInterface<VideoFrame>* sink_;
+    rtc::VideoBroadcaster* broadcaster_;
   };
 
-  void OnFrame(const webrtc::VideoFrame& frame) { broadcaster_.OnFrame(frame); }
   rtc::ThreadChecker thread_checker_;
 
   rtc::VideoBroadcaster broadcaster_;