Split VideoFrameWriter into yuv and y4m writers

Bug: webrtc:10138
Change-Id: I5eae094a1a4b426281d291273f7feb9555497139
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/147645
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28781}
diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc
index 20ad73b..f43ef3a 100644
--- a/test/pc/e2e/peer_connection_quality_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test.cc
@@ -956,7 +956,7 @@
     return nullptr;
   }
   // TODO(titovartem) create only one file writer for simulcast video track.
-  auto video_writer = absl::make_unique<test::VideoFrameWriter>(
+  auto video_writer = absl::make_unique<test::Y4mVideoFrameWriterImpl>(
       file_name.value(), config.width, config.height, config.fps);
   test::VideoFrameWriter* out = video_writer.get();
   video_writers_.push_back(std::move(video_writer));
diff --git a/test/testsupport/video_frame_writer.cc b/test/testsupport/video_frame_writer.cc
index 2e2964f..311f74a 100644
--- a/test/testsupport/video_frame_writer.cc
+++ b/test/testsupport/video_frame_writer.cc
@@ -23,40 +23,11 @@
 
 namespace webrtc {
 namespace test {
+namespace {
 
-VideoFrameWriter::VideoFrameWriter(std::string output_file_name,
-                                   int width,
-                                   int height,
-                                   int fps)
-    // We will move string here to prevent extra copy. We won't use const ref
-    // to not corrupt caller variable with move and don't assume that caller's
-    // variable won't be destructed before writer.
-    : output_file_name_(std::move(output_file_name)),
-      width_(width),
-      height_(height),
-      fps_(fps),
-      frame_writer_(absl::make_unique<Y4mFrameWriterImpl>(output_file_name_,
-                                                          width_,
-                                                          height_,
-                                                          fps_)) {
-  // Init underlying frame writer and ensure that it is operational.
-  RTC_CHECK(frame_writer_->Init());
-}
-VideoFrameWriter::~VideoFrameWriter() = default;
-
-bool VideoFrameWriter::WriteFrame(const webrtc::VideoFrame& frame) {
-  rtc::Buffer frame_buffer = ExtractI420BufferWithSize(frame, width_, height_);
-  RTC_CHECK_EQ(frame_buffer.size(), frame_writer_->FrameLength());
-  return frame_writer_->WriteFrame(frame_buffer.data());
-}
-
-void VideoFrameWriter::Close() {
-  frame_writer_->Close();
-}
-
-rtc::Buffer VideoFrameWriter::ExtractI420BufferWithSize(const VideoFrame& frame,
-                                                        int width,
-                                                        int height) {
+rtc::Buffer ExtractI420BufferWithSize(const VideoFrame& frame,
+                                      int width,
+                                      int height) {
   if (frame.width() != width || frame.height() != height) {
     RTC_CHECK_LE(std::abs(static_cast<double>(width) / height -
                           static_cast<double>(frame.width()) / frame.height()),
@@ -80,5 +51,61 @@
   return buffer;
 }
 
+}  // namespace
+
+Y4mVideoFrameWriterImpl::Y4mVideoFrameWriterImpl(std::string output_file_name,
+                                                 int width,
+                                                 int height,
+                                                 int fps)
+    // We will move string here to prevent extra copy. We won't use const ref
+    // to not corrupt caller variable with move and don't assume that caller's
+    // variable won't be destructed before writer.
+    : width_(width),
+      height_(height),
+      frame_writer_(
+          absl::make_unique<Y4mFrameWriterImpl>(std::move(output_file_name),
+                                                width_,
+                                                height_,
+                                                fps)) {
+  // Init underlying frame writer and ensure that it is operational.
+  RTC_CHECK(frame_writer_->Init());
+}
+
+bool Y4mVideoFrameWriterImpl::WriteFrame(const webrtc::VideoFrame& frame) {
+  rtc::Buffer frame_buffer = ExtractI420BufferWithSize(frame, width_, height_);
+  RTC_CHECK_EQ(frame_buffer.size(), frame_writer_->FrameLength());
+  return frame_writer_->WriteFrame(frame_buffer.data());
+}
+
+void Y4mVideoFrameWriterImpl::Close() {
+  frame_writer_->Close();
+}
+
+YuvVideoFrameWriterImpl::YuvVideoFrameWriterImpl(std::string output_file_name,
+                                                 int width,
+                                                 int height)
+    // We will move string here to prevent extra copy. We won't use const ref
+    // to not corrupt caller variable with move and don't assume that caller's
+    // variable won't be destructed before writer.
+    : width_(width),
+      height_(height),
+      frame_writer_(
+          absl::make_unique<YuvFrameWriterImpl>(std::move(output_file_name),
+                                                width_,
+                                                height_)) {
+  // Init underlying frame writer and ensure that it is operational.
+  RTC_CHECK(frame_writer_->Init());
+}
+
+bool YuvVideoFrameWriterImpl::WriteFrame(const webrtc::VideoFrame& frame) {
+  rtc::Buffer frame_buffer = ExtractI420BufferWithSize(frame, width_, height_);
+  RTC_CHECK_EQ(frame_buffer.size(), frame_writer_->FrameLength());
+  return frame_writer_->WriteFrame(frame_buffer.data());
+}
+
+void YuvVideoFrameWriterImpl::Close() {
+  frame_writer_->Close();
+}
+
 }  // namespace test
 }  // namespace webrtc
diff --git a/test/testsupport/video_frame_writer.h b/test/testsupport/video_frame_writer.h
index c96faf6..db1d453 100644
--- a/test/testsupport/video_frame_writer.h
+++ b/test/testsupport/video_frame_writer.h
@@ -22,27 +22,46 @@
 namespace webrtc {
 namespace test {
 
-// Writes webrtc::VideoFrame to specified file with y4m frame writer
 class VideoFrameWriter {
  public:
-  VideoFrameWriter(std::string output_file_name,
-                   int width,
-                   int height,
-                   int fps);
-  virtual ~VideoFrameWriter();
+  virtual ~VideoFrameWriter() = default;
 
-  bool WriteFrame(const webrtc::VideoFrame& frame);
-  void Close();
+  virtual bool WriteFrame(const webrtc::VideoFrame& frame) = 0;
+
+  virtual void Close() = 0;
+};
+
+// Writes webrtc::VideoFrame to specified file with y4m frame writer
+class Y4mVideoFrameWriterImpl : public VideoFrameWriter {
+ public:
+  Y4mVideoFrameWriterImpl(std::string output_file_name,
+                          int width,
+                          int height,
+                          int fps);
+  ~Y4mVideoFrameWriterImpl() override = default;
+
+  bool WriteFrame(const webrtc::VideoFrame& frame) override;
+  void Close() override;
 
  private:
-  rtc::Buffer ExtractI420BufferWithSize(const VideoFrame& frame,
-                                        int width,
-                                        int height);
-
-  const std::string output_file_name_;
   const int width_;
   const int height_;
-  const int fps_;
+
+  std::unique_ptr<FrameWriter> frame_writer_;
+};
+
+// Writes webrtc::VideoFrame to specified file with yuv frame writer
+class YuvVideoFrameWriterImpl : public VideoFrameWriter {
+ public:
+  YuvVideoFrameWriterImpl(std::string output_file_name, int width, int height);
+  ~YuvVideoFrameWriterImpl() override = default;
+
+  bool WriteFrame(const webrtc::VideoFrame& frame) override;
+  void Close() override;
+
+ private:
+  const int width_;
+  const int height_;
 
   std::unique_ptr<FrameWriter> frame_writer_;
 };
diff --git a/test/testsupport/video_frame_writer_unittest.cc b/test/testsupport/video_frame_writer_unittest.cc
index 67fe903..c712a6e 100644
--- a/test/testsupport/video_frame_writer_unittest.cc
+++ b/test/testsupport/video_frame_writer_unittest.cc
@@ -96,19 +96,36 @@
   void SetUp() override {
     temp_filename_ = webrtc::test::TempFilename(webrtc::test::OutputPath(),
                                                 "video_frame_writer_unittest");
-    frame_writer_ = absl::make_unique<VideoFrameWriter>(
-        temp_filename_, kFrameWidth, kFrameHeight, kFrameRate);
+    frame_writer_ = CreateFrameWriter();
   }
 
+  virtual std::unique_ptr<VideoFrameWriter> CreateFrameWriter() = 0;
+
   void TearDown() override { remove(temp_filename_.c_str()); }
 
   std::unique_ptr<VideoFrameWriter> frame_writer_;
   std::string temp_filename_;
 };
 
-TEST_F(VideoFrameWriterTest, InitSuccess) {}
+class Y4mVideoFrameWriterTest : public VideoFrameWriterTest {
+ protected:
+  std::unique_ptr<VideoFrameWriter> CreateFrameWriter() override {
+    return absl::make_unique<Y4mVideoFrameWriterImpl>(
+        temp_filename_, kFrameWidth, kFrameHeight, kFrameRate);
+  }
+};
 
-TEST_F(VideoFrameWriterTest, WriteFrame) {
+class YuvVideoFrameWriterTest : public VideoFrameWriterTest {
+ protected:
+  std::unique_ptr<VideoFrameWriter> CreateFrameWriter() override {
+    return absl::make_unique<YuvVideoFrameWriterImpl>(
+        temp_filename_, kFrameWidth, kFrameHeight);
+  }
+};
+
+TEST_F(Y4mVideoFrameWriterTest, InitSuccess) {}
+
+TEST_F(Y4mVideoFrameWriterTest, WriteFrame) {
   rtc::scoped_refptr<I420Buffer> expected_buffer =
       CreateI420Buffer(kFrameWidth, kFrameHeight);
 
@@ -132,5 +149,30 @@
   frame_reader->Close();
 }
 
+TEST_F(YuvVideoFrameWriterTest, InitSuccess) {}
+
+TEST_F(YuvVideoFrameWriterTest, WriteFrame) {
+  rtc::scoped_refptr<I420Buffer> expected_buffer =
+      CreateI420Buffer(kFrameWidth, kFrameHeight);
+
+  VideoFrame frame =
+      VideoFrame::Builder().set_video_frame_buffer(expected_buffer).build();
+
+  ASSERT_TRUE(frame_writer_->WriteFrame(frame));
+  ASSERT_TRUE(frame_writer_->WriteFrame(frame));
+
+  frame_writer_->Close();
+  EXPECT_EQ(2 * kFrameLength, GetFileSize(temp_filename_));
+
+  std::unique_ptr<FrameReader> frame_reader =
+      absl::make_unique<YuvFrameReaderImpl>(temp_filename_, kFrameWidth,
+                                            kFrameHeight);
+  ASSERT_TRUE(frame_reader->Init());
+  AssertI420BuffersEq(frame_reader->ReadFrame(), expected_buffer);
+  AssertI420BuffersEq(frame_reader->ReadFrame(), expected_buffer);
+  EXPECT_FALSE(frame_reader->ReadFrame());  // End of file.
+  frame_reader->Close();
+}
+
 }  // namespace test
 }  // namespace webrtc