Introduce FrameGeneratorInterface
Introduce FrameGeneratorInterface to make FrameGenerator API available
for downstream projects.
Bug: webrtc:10138
Change-Id: I4216775e4b8b54c3f1c72d67ffbda31eb082fd7e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161234
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30009}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 48d3770..4265f97 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -374,6 +374,20 @@
]
}
+rtc_source_set("frame_generator_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/frame_generator_interface.h",
+ ]
+
+ deps = [
+ ":scoped_refptr",
+ "video:video_frame",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
rtc_library("test_dependency_factory") {
visibility = [ "*" ]
testonly = true
@@ -433,6 +447,21 @@
"../test/pc/e2e:peerconnection_quality_test",
]
}
+
+ rtc_library("create_frame_generator") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_frame_generator.cc",
+ "test/create_frame_generator.h",
+ ]
+ deps = [
+ ":frame_generator_api",
+ "../system_wrappers",
+ "../test:video_test_common",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+ }
}
rtc_source_set("libjingle_logging_api") {
diff --git a/api/test/DEPS b/api/test/DEPS
index 1fced5d..b5bbed6 100644
--- a/api/test/DEPS
+++ b/api/test/DEPS
@@ -37,4 +37,7 @@
"+rtc_base/synchronization/yield_policy.h",
"+system_wrappers/include/clock.h",
],
+ "create_frame_generator\.h": [
+ "+system_wrappers/include/clock.h",
+ ],
}
diff --git a/api/test/create_frame_generator.cc b/api/test/create_frame_generator.cc
new file mode 100644
index 0000000..b6e62a4
--- /dev/null
+++ b/api/test/create_frame_generator.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_frame_generator.h"
+
+#include <utility>
+
+#include "test/frame_generator.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<FrameGeneratorInterface> CreateSquareFrameGenerator(
+ int width,
+ int height,
+ absl::optional<FrameGeneratorInterface::OutputType> type,
+ absl::optional<int> num_squares) {
+ return FrameGenerator::CreateSquareGenerator(width, height, type,
+ num_squares);
+}
+
+std::unique_ptr<FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
+ std::vector<std::string> files,
+ size_t width,
+ size_t height,
+ int frame_repeat_count) {
+ return FrameGenerator::CreateFromYuvFile(std::move(files), width, height,
+ frame_repeat_count);
+}
+
+std::unique_ptr<FrameGeneratorInterface>
+CreateScrollingInputFromYuvFilesFrameGenerator(
+ Clock* clock,
+ std::vector<std::string> filenames,
+ size_t source_width,
+ size_t source_height,
+ size_t target_width,
+ size_t target_height,
+ int64_t scroll_time_ms,
+ int64_t pause_time_ms) {
+ return FrameGenerator::CreateScrollingInputFromYuvFiles(
+ clock, std::move(filenames), source_width, source_height, target_width,
+ target_height, scroll_time_ms, pause_time_ms);
+}
+
+std::unique_ptr<FrameGeneratorInterface>
+CreateSlideFrameGenerator(int width, int height, int frame_repeat_count) {
+ return FrameGenerator::CreateSlideGenerator(width, height,
+ frame_repeat_count);
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/api/test/create_frame_generator.h b/api/test/create_frame_generator.h
new file mode 100644
index 0000000..692c964
--- /dev/null
+++ b/api/test/create_frame_generator.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_CREATE_FRAME_GENERATOR_H_
+#define API_TEST_CREATE_FRAME_GENERATOR_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/test/frame_generator_interface.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+namespace test {
+
+// Creates a frame generator that produces frames with small squares that
+// move randomly towards the lower right corner.
+// |type| has the default value FrameGeneratorInterface::OutputType::I420.
+// |num_squares| has the default value 10.
+std::unique_ptr<FrameGeneratorInterface> CreateSquareFrameGenerator(
+ int width,
+ int height,
+ absl::optional<FrameGeneratorInterface::OutputType> type,
+ absl::optional<int> num_squares);
+
+// Creates a frame generator that repeatedly plays a set of yuv files.
+// The frame_repeat_count determines how many times each frame is shown,
+// with 1 = show each frame once, etc.
+std::unique_ptr<FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
+ std::vector<std::string> files,
+ size_t width,
+ size_t height,
+ int frame_repeat_count);
+
+// Creates a frame generator which takes a set of yuv files (wrapping a
+// frame generator created by CreateFromYuvFile() above), but outputs frames
+// that have been cropped to specified resolution: source_width/source_height
+// is the size of the source images, target_width/target_height is the size of
+// the cropped output. For each source image read, the cropped viewport will
+// be scrolled top to bottom/left to right for scroll_tim_ms milliseconds.
+// After that the image will stay in place for pause_time_ms milliseconds,
+// and then this will be repeated with the next file from the input set.
+std::unique_ptr<FrameGeneratorInterface>
+CreateScrollingInputFromYuvFilesFrameGenerator(
+ Clock* clock,
+ std::vector<std::string> filenames,
+ size_t source_width,
+ size_t source_height,
+ size_t target_width,
+ size_t target_height,
+ int64_t scroll_time_ms,
+ int64_t pause_time_ms);
+
+// Creates a frame generator that produces randomly generated slides. It fills
+// the frames with randomly sized and colored squares.
+// |frame_repeat_count| determines how many times each slide is shown.
+std::unique_ptr<FrameGeneratorInterface>
+CreateSlideFrameGenerator(int width, int height, int frame_repeat_count);
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_FRAME_GENERATOR_H_
diff --git a/api/test/frame_generator_interface.h b/api/test/frame_generator_interface.h
new file mode 100644
index 0000000..691b6ee
--- /dev/null
+++ b/api/test/frame_generator_interface.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_FRAME_GENERATOR_INTERFACE_H_
+#define API_TEST_FRAME_GENERATOR_INTERFACE_H_
+
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame.h"
+#include "api/video/video_frame_buffer.h"
+
+namespace webrtc {
+namespace test {
+
+class FrameGeneratorInterface {
+ public:
+ struct VideoFrameData {
+ VideoFrameData(rtc::scoped_refptr<VideoFrameBuffer> buffer,
+ absl::optional<VideoFrame::UpdateRect> update_rect)
+ : buffer(std::move(buffer)), update_rect(update_rect) {}
+
+ rtc::scoped_refptr<VideoFrameBuffer> buffer;
+ absl::optional<VideoFrame::UpdateRect> update_rect;
+ };
+
+ enum class OutputType { kI420, kI420A, kI010 };
+
+ virtual ~FrameGeneratorInterface() = default;
+
+ // Returns VideoFrameBuffer and area where most of update was done to set them
+ // on the VideoFrame object.
+ virtual VideoFrameData NextFrame() = 0;
+
+ // Change the capture resolution.
+ virtual void ChangeResolution(size_t width, size_t height) = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_FRAME_GENERATOR_INTERFACE_H_
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 8c22c92..a5519d2 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -53,6 +53,7 @@
deps = [
":fileutils",
+ "../api:frame_generator_api",
"../api:scoped_refptr",
"../api/task_queue",
"../api/video:video_frame",
diff --git a/test/frame_generator.h b/test/frame_generator.h
index 95b710f..47251b3 100644
--- a/test/frame_generator.h
+++ b/test/frame_generator.h
@@ -14,6 +14,7 @@
#include <string>
#include <vector>
+#include "api/test/frame_generator_interface.h"
#include "api/video/video_frame.h"
#include "api/video/video_source_interface.h"
#include "rtc_base/critical_section.h"
@@ -45,31 +46,12 @@
rtc::VideoSinkWants sink_wants_ RTC_GUARDED_BY(crit_);
};
-class FrameGenerator {
+class FrameGenerator : public FrameGeneratorInterface {
public:
- struct VideoFrameData {
- VideoFrameData(rtc::scoped_refptr<VideoFrameBuffer> buffer,
- absl::optional<VideoFrame::UpdateRect> update_rect)
- : buffer(std::move(buffer)), update_rect(update_rect) {}
-
- rtc::scoped_refptr<VideoFrameBuffer> buffer;
- absl::optional<VideoFrame::UpdateRect> update_rect;
- };
-
virtual ~FrameGenerator() = default;
- // Returns VideoFrameBuffer and area where most of update was done to set them
- // on the VideoFrame object. Returned frames can share same buffer.
- virtual VideoFrameData NextFrame() = 0;
-
// Change the capture resolution.
- virtual void ChangeResolution(size_t width, size_t height);
-
- enum class OutputType {
- kI420,
- kI420A,
- kI010
- };
+ void ChangeResolution(size_t width, size_t height) override;
// Creates a frame generator that produces frames with small squares that
// move randomly towards the lower right corner.
diff --git a/test/frame_generator_capturer.cc b/test/frame_generator_capturer.cc
index 5f1c6e0..e817db9 100644
--- a/test/frame_generator_capturer.cc
+++ b/test/frame_generator_capturer.cc
@@ -44,7 +44,7 @@
FrameGeneratorCapturer::FrameGeneratorCapturer(
Clock* clock,
- std::unique_ptr<FrameGenerator> frame_generator,
+ std::unique_ptr<FrameGeneratorInterface> frame_generator,
int target_fps,
TaskQueueFactory& task_queue_factory)
: clock_(clock),
diff --git a/test/frame_generator_capturer.h b/test/frame_generator_capturer.h
index faf0498..6220870 100644
--- a/test/frame_generator_capturer.h
+++ b/test/frame_generator_capturer.h
@@ -96,10 +96,11 @@
virtual ~SinkWantsObserver() {}
};
- FrameGeneratorCapturer(Clock* clock,
- std::unique_ptr<FrameGenerator> frame_generator,
- int target_fps,
- TaskQueueFactory& task_queue_factory);
+ FrameGeneratorCapturer(
+ Clock* clock,
+ std::unique_ptr<FrameGeneratorInterface> frame_generator,
+ int target_fps,
+ TaskQueueFactory& task_queue_factory);
virtual ~FrameGeneratorCapturer();
static std::unique_ptr<FrameGeneratorCapturer> Create(
@@ -154,7 +155,7 @@
SinkWantsObserver* sink_wants_observer_ RTC_GUARDED_BY(&lock_);
rtc::CriticalSection lock_;
- std::unique_ptr<FrameGenerator> frame_generator_;
+ std::unique_ptr<FrameGeneratorInterface> frame_generator_;
int source_fps_ RTC_GUARDED_BY(&lock_);
int target_capture_fps_ RTC_GUARDED_BY(&lock_);
diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn
index ae6bc74..9263014 100644
--- a/test/pc/e2e/BUILD.gn
+++ b/test/pc/e2e/BUILD.gn
@@ -292,6 +292,8 @@
"../..:platform_video_capturer",
"../..:video_test_common",
"../../../api:audio_quality_analyzer_api",
+ "../../../api:create_frame_generator",
+ "../../../api:frame_generator_api",
"../../../api:libjingle_peerconnection_api",
"../../../api:media_stream_interface",
"../../../api:peer_connection_quality_test_fixture_api",
diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc
index a5fa65a..9baa3de 100644
--- a/test/pc/e2e/peer_connection_quality_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test.cc
@@ -21,6 +21,7 @@
#include "api/rtc_event_log_output_file.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/default_task_queue_factory.h"
+#include "api/test/create_frame_generator.h"
#include "api/test/video_quality_analyzer_interface.h"
#include "api/units/time_delta.h"
#include "api/video/video_source_interface.h"
@@ -791,24 +792,24 @@
return capturer;
}
- std::unique_ptr<test::FrameGenerator> frame_generator = nullptr;
+ std::unique_ptr<test::FrameGeneratorInterface> frame_generator = nullptr;
if (video_config.generator) {
- absl::optional<test::FrameGenerator::OutputType> frame_generator_type =
- absl::nullopt;
+ absl::optional<test::FrameGeneratorInterface::OutputType>
+ frame_generator_type = absl::nullopt;
if (video_config.generator == VideoGeneratorType::kDefault) {
- frame_generator_type = test::FrameGenerator::OutputType::kI420;
+ frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420;
} else if (video_config.generator == VideoGeneratorType::kI420A) {
- frame_generator_type = test::FrameGenerator::OutputType::kI420A;
+ frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420A;
} else if (video_config.generator == VideoGeneratorType::kI010) {
- frame_generator_type = test::FrameGenerator::OutputType::kI010;
+ frame_generator_type = test::FrameGeneratorInterface::OutputType::kI010;
}
- frame_generator = test::FrameGenerator::CreateSquareGenerator(
- static_cast<int>(video_config.width),
- static_cast<int>(video_config.height), frame_generator_type,
- absl::nullopt);
+ frame_generator =
+ test::CreateSquareFrameGenerator(static_cast<int>(video_config.width),
+ static_cast<int>(video_config.height),
+ frame_generator_type, absl::nullopt);
}
if (video_config.input_file_name) {
- frame_generator = test::FrameGenerator::CreateFromYuvFile(
+ frame_generator = test::CreateFromYuvFileFrameGenerator(
std::vector<std::string>(/*count=*/1,
video_config.input_file_name.value()),
video_config.width, video_config.height, /*frame_repeat_count=*/1);
@@ -826,12 +827,12 @@
return capturer;
}
-std::unique_ptr<test::FrameGenerator>
+std::unique_ptr<test::FrameGeneratorInterface>
PeerConnectionE2EQualityTest::CreateScreenShareFrameGenerator(
const VideoConfig& video_config) {
RTC_CHECK(video_config.screen_share_config);
if (video_config.screen_share_config->generate_slides) {
- return test::FrameGenerator::CreateSlideGenerator(
+ return test::CreateSlideFrameGenerator(
video_config.width, video_config.height,
video_config.screen_share_config->slide_change_interval.seconds() *
video_config.fps);
@@ -849,7 +850,7 @@
}
if (!video_config.screen_share_config->scrolling_params) {
// Cycle image every slide_change_interval seconds.
- return test::FrameGenerator::CreateFromYuvFile(
+ return test::CreateFromYuvFileFrameGenerator(
slides, video_config.width, video_config.height,
video_config.screen_share_config->slide_change_interval.seconds() *
video_config.fps);
@@ -860,7 +861,7 @@
video_config.screen_share_config->slide_change_interval -
video_config.screen_share_config->scrolling_params->duration;
- return test::FrameGenerator::CreateScrollingInputFromYuvFiles(
+ return test::CreateScrollingInputFromYuvFilesFrameGenerator(
clock_, slides,
video_config.screen_share_config->scrolling_params->source_width,
video_config.screen_share_config->scrolling_params->source_height,
diff --git a/test/pc/e2e/peer_connection_quality_test.h b/test/pc/e2e/peer_connection_quality_test.h
index 669cdb3..aeff087 100644
--- a/test/pc/e2e/peer_connection_quality_test.h
+++ b/test/pc/e2e/peer_connection_quality_test.h
@@ -17,6 +17,7 @@
#include "api/task_queue/task_queue_factory.h"
#include "api/test/audio_quality_analyzer_interface.h"
+#include "api/test/frame_generator_interface.h"
#include "api/test/peerconnection_quality_test_fixture.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
@@ -289,8 +290,8 @@
std::unique_ptr<rtc::VideoSourceInterface<VideoFrame>> source,
std::unique_ptr<test::TestVideoCapturer::FramePreprocessor>
frame_preprocessor);
- std::unique_ptr<test::FrameGenerator> CreateScreenShareFrameGenerator(
- const VideoConfig& video_config);
+ std::unique_ptr<test::FrameGeneratorInterface>
+ CreateScreenShareFrameGenerator(const VideoConfig& video_config);
void MaybeAddAudio(TestPeer* peer);
void SetPeerCodecPreferences(TestPeer* peer, const RunParams& run_params);
void SetupCall(const RunParams& run_params);