From d77f2212b0d1339e7a235c9c5a82b57a1e9e2a43 Mon Sep 17 00:00:00 2001 From: Artem Titov Date: Thu, 13 Apr 2023 14:34:59 +0200 Subject: [PATCH] Move FrameGeneratorCapturerConfig and Create family methods Move FrameGeneratorCapturerConfig and Create family methods from frame_generator_capturer.h to the create_frame_generator_capturer.h Bug: b/272350185 Change-Id: I95674f5238ac0d0a5e395840bbab7f205b160c37 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301220 Reviewed-by: Mirko Bonadei Commit-Queue: Artem Titov Cr-Commit-Position: refs/heads/main@{#39850} --- test/BUILD.gn | 15 ++- test/create_frame_generator_capturer.cc | 133 ++++++++++++++++++++++ test/create_frame_generator_capturer.h | 88 +++++++++++--- test/frame_generator_capturer.cc | 100 ---------------- test/frame_generator_capturer.h | 82 ------------- test/frame_generator_capturer_unittest.cc | 8 +- test/peer_scenario/peer_scenario_client.h | 1 + 7 files changed, 221 insertions(+), 206 deletions(-) create mode 100644 test/create_frame_generator_capturer.cc diff --git a/test/BUILD.gn b/test/BUILD.gn index ea2c669626..2ef7d6ac79 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -129,15 +129,24 @@ rtc_library("test_video_capturer") { rtc_library("create_frame_generator_capturer") { visibility = [ "*" ] testonly = true - sources = [ "create_frame_generator_capturer.h" ] + sources = [ + "create_frame_generator_capturer.cc", + "create_frame_generator_capturer.h", + ] deps = [ + ":fileutils", ":frame_generator_capturer", + "../api:create_frame_generator", "../api:frame_generator_api", "../api/task_queue", "../api/units:time_delta", + "../rtc_base:checks", "../system_wrappers", ] - absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + absl_deps = [ + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/types:optional", + ] } rtc_library("frame_generator_capturer") { @@ -148,7 +157,6 @@ rtc_library("frame_generator_capturer") { "frame_generator_capturer.h", ] deps = [ - ":fileutils", ":test_video_capturer", "../api:create_frame_generator", "../api:frame_generator_api", @@ -693,6 +701,7 @@ if (rtc_include_tests) { deps = [ ":call_config_utils", ":copy_to_file_audio_capturer_unittest", + ":create_frame_generator_capturer", ":direct_transport", ":fake_video_codecs", ":fileutils", diff --git a/test/create_frame_generator_capturer.cc b/test/create_frame_generator_capturer.cc new file mode 100644 index 0000000000..a4088d90e5 --- /dev/null +++ b/test/create_frame_generator_capturer.cc @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023 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 "test/create_frame_generator_capturer.h" + +#include +#include +#include +#include + +#include "absl/strings/match.h" +#include "api/task_queue/task_queue_factory.h" +#include "api/test/create_frame_generator.h" +#include "api/test/frame_generator_interface.h" +#include "api/units/time_delta.h" +#include "rtc_base/checks.h" +#include "system_wrappers/include/clock.h" +#include "test/testsupport/file_utils.h" + +namespace webrtc { +namespace test { +namespace { + +std::string TransformFilePath(std::string path) { + static const std::string resource_prefix = "res://"; + int ext_pos = path.rfind('.'); + if (ext_pos < 0) { + return test::ResourcePath(path, "yuv"); + } else if (absl::StartsWith(path, resource_prefix)) { + std::string name = path.substr(resource_prefix.length(), ext_pos); + std::string ext = path.substr(ext_pos, path.size()); + return test::ResourcePath(name, ext); + } + return path; +} + +} // namespace + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::SquaresVideo config) { + return std::make_unique( + clock, + CreateSquareFrameGenerator(config.width, config.height, + config.pixel_format, config.num_squares), + config.framerate, task_queue_factory); +} +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::SquareSlides config) { + return std::make_unique( + clock, + CreateSlideFrameGenerator( + config.width, config.height, + /*frame_repeat_count*/ config.change_interval.seconds() * + config.framerate), + config.framerate, task_queue_factory); +} +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::VideoFile config) { + RTC_CHECK(config.width && config.height); + return std::make_unique( + clock, + CreateFromYuvFileFrameGenerator({TransformFilePath(config.name)}, + config.width, config.height, + /*frame_repeat_count*/ 1), + config.framerate, task_queue_factory); +} + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::ImageSlides config) { + std::unique_ptr slides_generator; + std::vector paths = config.paths; + for (std::string& path : paths) + path = TransformFilePath(path); + + if (config.crop.width || config.crop.height) { + TimeDelta pause_duration = + config.change_interval - config.crop.scroll_duration; + RTC_CHECK_GE(pause_duration, TimeDelta::Zero()); + int crop_width = config.crop.width.value_or(config.width); + int crop_height = config.crop.height.value_or(config.height); + RTC_CHECK_LE(crop_width, config.width); + RTC_CHECK_LE(crop_height, config.height); + slides_generator = CreateScrollingInputFromYuvFilesFrameGenerator( + clock, paths, config.width, config.height, crop_width, crop_height, + config.crop.scroll_duration.ms(), pause_duration.ms()); + } else { + slides_generator = CreateFromYuvFileFrameGenerator( + paths, config.width, config.height, + /*frame_repeat_count*/ config.change_interval.seconds() * + config.framerate); + } + return std::make_unique( + clock, std::move(slides_generator), config.framerate, task_queue_factory); +} + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + const FrameGeneratorCapturerConfig& config) { + if (config.video_file) { + return CreateFrameGeneratorCapturer(clock, task_queue_factory, + *config.video_file); + } else if (config.image_slides) { + return CreateFrameGeneratorCapturer(clock, task_queue_factory, + *config.image_slides); + } else if (config.squares_slides) { + return CreateFrameGeneratorCapturer(clock, task_queue_factory, + *config.squares_slides); + } else { + return CreateFrameGeneratorCapturer( + clock, task_queue_factory, + config.squares_video.value_or( + FrameGeneratorCapturerConfig::SquaresVideo())); + } +} + +} // namespace test +} // namespace webrtc diff --git a/test/create_frame_generator_capturer.h b/test/create_frame_generator_capturer.h index 22039edf8c..0d8ec71df3 100644 --- a/test/create_frame_generator_capturer.h +++ b/test/create_frame_generator_capturer.h @@ -24,40 +24,92 @@ namespace webrtc { namespace test { -std::unique_ptr CreateFrameGeneratorCapturer( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquaresVideo config) { - return FrameGeneratorCapturer::Create(clock, task_queue_factory, config); -} +namespace frame_gen_cap_impl { +template +class AutoOpt : public absl::optional { + public: + using absl::optional::optional; + T* operator->() { + if (!absl::optional::has_value()) + this->emplace(T()); + return absl::optional::operator->(); + } +}; +} // namespace frame_gen_cap_impl + +struct FrameGeneratorCapturerConfig { + struct SquaresVideo { + int framerate = 30; + FrameGeneratorInterface::OutputType pixel_format = + FrameGeneratorInterface::OutputType::kI420; + int width = 320; + int height = 180; + int num_squares = 10; + }; + + struct SquareSlides { + int framerate = 30; + TimeDelta change_interval = TimeDelta::Seconds(10); + int width = 1600; + int height = 1200; + }; + + struct VideoFile { + int framerate = 30; + std::string name; + // Must be set to width and height of the source video file. + int width = 0; + int height = 0; + }; + + struct ImageSlides { + int framerate = 30; + TimeDelta change_interval = TimeDelta::Seconds(10); + struct Crop { + TimeDelta scroll_duration = TimeDelta::Seconds(0); + absl::optional width; + absl::optional height; + } crop; + int width = 1850; + int height = 1110; + std::vector paths = { + "web_screenshot_1850_1110", + "presentation_1850_1110", + "photo_1850_1110", + "difficult_photo_1850_1110", + }; + }; + + frame_gen_cap_impl::AutoOpt squares_video; + frame_gen_cap_impl::AutoOpt squares_slides; + frame_gen_cap_impl::AutoOpt video_file; + frame_gen_cap_impl::AutoOpt image_slides; +}; std::unique_ptr CreateFrameGeneratorCapturer( Clock* clock, TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquareSlides config) { - return FrameGeneratorCapturer::Create(clock, task_queue_factory, config); -} + FrameGeneratorCapturerConfig::SquaresVideo config); std::unique_ptr CreateFrameGeneratorCapturer( Clock* clock, TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::VideoFile config) { - return FrameGeneratorCapturer::Create(clock, task_queue_factory, config); -} + FrameGeneratorCapturerConfig::SquareSlides config); std::unique_ptr CreateFrameGeneratorCapturer( Clock* clock, TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::ImageSlides config) { - return FrameGeneratorCapturer::Create(clock, task_queue_factory, config); -} + FrameGeneratorCapturerConfig::VideoFile config); std::unique_ptr CreateFrameGeneratorCapturer( Clock* clock, TaskQueueFactory& task_queue_factory, - const FrameGeneratorCapturerConfig& config) { - return FrameGeneratorCapturer::Create(clock, task_queue_factory, config); -} + FrameGeneratorCapturerConfig::ImageSlides config); + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + const FrameGeneratorCapturerConfig& config); } // namespace test } // namespace webrtc diff --git a/test/frame_generator_capturer.cc b/test/frame_generator_capturer.cc index 5d0e2e8d9a..c47f88e21a 100644 --- a/test/frame_generator_capturer.cc +++ b/test/frame_generator_capturer.cc @@ -17,33 +17,15 @@ #include #include -#include "absl/strings/match.h" #include "api/test/create_frame_generator.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/task_queue.h" #include "rtc_base/time_utils.h" #include "system_wrappers/include/clock.h" -#include "test/testsupport/file_utils.h" namespace webrtc { namespace test { -namespace { - -std::string TransformFilePath(std::string path) { - static const std::string resource_prefix = "res://"; - int ext_pos = path.rfind('.'); - if (ext_pos < 0) { - return test::ResourcePath(path, "yuv"); - } else if (absl::StartsWith(path, resource_prefix)) { - std::string name = path.substr(resource_prefix.length(), ext_pos); - std::string ext = path.substr(ext_pos, path.size()); - return test::ResourcePath(name, ext); - } - return path; -} - -} // namespace FrameGeneratorCapturer::FrameGeneratorCapturer( Clock* clock, @@ -68,88 +50,6 @@ FrameGeneratorCapturer::~FrameGeneratorCapturer() { Stop(); } -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquaresVideo config) { - return std::make_unique( - clock, - CreateSquareFrameGenerator(config.width, config.height, - config.pixel_format, config.num_squares), - config.framerate, task_queue_factory); -} -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquareSlides config) { - return std::make_unique( - clock, - CreateSlideFrameGenerator( - config.width, config.height, - /*frame_repeat_count*/ config.change_interval.seconds() * - config.framerate), - config.framerate, task_queue_factory); -} -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::VideoFile config) { - RTC_CHECK(config.width && config.height); - return std::make_unique( - clock, - CreateFromYuvFileFrameGenerator({TransformFilePath(config.name)}, - config.width, config.height, - /*frame_repeat_count*/ 1), - config.framerate, task_queue_factory); -} - -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::ImageSlides config) { - std::unique_ptr slides_generator; - std::vector paths = config.paths; - for (std::string& path : paths) - path = TransformFilePath(path); - - if (config.crop.width || config.crop.height) { - TimeDelta pause_duration = - config.change_interval - config.crop.scroll_duration; - RTC_CHECK_GE(pause_duration, TimeDelta::Zero()); - int crop_width = config.crop.width.value_or(config.width); - int crop_height = config.crop.height.value_or(config.height); - RTC_CHECK_LE(crop_width, config.width); - RTC_CHECK_LE(crop_height, config.height); - slides_generator = CreateScrollingInputFromYuvFilesFrameGenerator( - clock, paths, config.width, config.height, crop_width, crop_height, - config.crop.scroll_duration.ms(), pause_duration.ms()); - } else { - slides_generator = CreateFromYuvFileFrameGenerator( - paths, config.width, config.height, - /*frame_repeat_count*/ config.change_interval.seconds() * - config.framerate); - } - return std::make_unique( - clock, std::move(slides_generator), config.framerate, task_queue_factory); -} - -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - const FrameGeneratorCapturerConfig& config) { - if (config.video_file) { - return Create(clock, task_queue_factory, *config.video_file); - } else if (config.image_slides) { - return Create(clock, task_queue_factory, *config.image_slides); - } else if (config.squares_slides) { - return Create(clock, task_queue_factory, *config.squares_slides); - } else { - return Create(clock, task_queue_factory, - config.squares_video.value_or( - FrameGeneratorCapturerConfig::SquaresVideo())); - } -} - void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) { MutexLock lock(&lock_); fake_rotation_ = rotation; diff --git a/test/frame_generator_capturer.h b/test/frame_generator_capturer.h index 20b355669f..ff240cc0c5 100644 --- a/test/frame_generator_capturer.h +++ b/test/frame_generator_capturer.h @@ -23,68 +23,7 @@ #include "test/test_video_capturer.h" namespace webrtc { - namespace test { -namespace frame_gen_cap_impl { -template -class AutoOpt : public absl::optional { - public: - using absl::optional::optional; - T* operator->() { - if (!absl::optional::has_value()) - this->emplace(T()); - return absl::optional::operator->(); - } -}; -} // namespace frame_gen_cap_impl -struct FrameGeneratorCapturerConfig { - struct SquaresVideo { - int framerate = 30; - FrameGeneratorInterface::OutputType pixel_format = - FrameGeneratorInterface::OutputType::kI420; - int width = 320; - int height = 180; - int num_squares = 10; - }; - - struct SquareSlides { - int framerate = 30; - TimeDelta change_interval = TimeDelta::Seconds(10); - int width = 1600; - int height = 1200; - }; - - struct VideoFile { - int framerate = 30; - std::string name; - // Must be set to width and height of the source video file. - int width = 0; - int height = 0; - }; - - struct ImageSlides { - int framerate = 30; - TimeDelta change_interval = TimeDelta::Seconds(10); - struct Crop { - TimeDelta scroll_duration = TimeDelta::Seconds(0); - absl::optional width; - absl::optional height; - } crop; - int width = 1850; - int height = 1110; - std::vector paths = { - "web_screenshot_1850_1110", - "presentation_1850_1110", - "photo_1850_1110", - "difficult_photo_1850_1110", - }; - }; - - frame_gen_cap_impl::AutoOpt squares_video; - frame_gen_cap_impl::AutoOpt squares_slides; - frame_gen_cap_impl::AutoOpt video_file; - frame_gen_cap_impl::AutoOpt image_slides; -}; class FrameGeneratorCapturer : public TestVideoCapturer { public: @@ -106,27 +45,6 @@ class FrameGeneratorCapturer : public TestVideoCapturer { TaskQueueFactory& task_queue_factory); virtual ~FrameGeneratorCapturer(); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquaresVideo config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquareSlides config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::VideoFile config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::ImageSlides config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - const FrameGeneratorCapturerConfig& config); - void Start(); void Stop(); void ChangeResolution(size_t width, size_t height); diff --git a/test/frame_generator_capturer_unittest.cc b/test/frame_generator_capturer_unittest.cc index 0098b0e3b6..8bf70cffd5 100644 --- a/test/frame_generator_capturer_unittest.cc +++ b/test/frame_generator_capturer_unittest.cc @@ -9,6 +9,8 @@ */ #include "test/frame_generator_capturer.h" + +#include "test/create_frame_generator_capturer.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/time_controller/simulated_time_controller.h" @@ -36,7 +38,7 @@ TEST(FrameGeneratorCapturerTest, CreateFromConfig) { config.squares_video->width = 300; config.squares_video->height = 200; config.squares_video->framerate = 20; - auto capturer = FrameGeneratorCapturer::Create( + auto capturer = CreateFrameGeneratorCapturer( time.GetClock(), *time.GetTaskQueueFactory(), config); testing::StrictMock mock_sink; capturer->AddOrUpdateSink(&mock_sink, rtc::VideoSinkWants()); @@ -52,7 +54,7 @@ TEST(FrameGeneratorCapturerTest, OnOutputFormatRequest) { config.squares_video->width = kWidth; config.squares_video->height = kHeight; config.squares_video->framerate = 20; - auto capturer = FrameGeneratorCapturer::Create( + auto capturer = CreateFrameGeneratorCapturer( time.GetClock(), *time.GetTaskQueueFactory(), config); testing::StrictMock mock_sink; capturer->AddOrUpdateSink(&mock_sink, rtc::VideoSinkWants()); @@ -69,7 +71,7 @@ TEST(FrameGeneratorCapturerTest, ChangeResolution) { config.squares_video->width = kWidth; config.squares_video->height = kHeight; config.squares_video->framerate = 20; - auto capturer = FrameGeneratorCapturer::Create( + auto capturer = CreateFrameGeneratorCapturer( time.GetClock(), *time.GetTaskQueueFactory(), config); EXPECT_TRUE(capturer->GetResolution()); EXPECT_EQ(kWidth, capturer->GetResolution()->width); diff --git a/test/peer_scenario/peer_scenario_client.h b/test/peer_scenario/peer_scenario_client.h index ab6aac9cf8..e863757759 100644 --- a/test/peer_scenario/peer_scenario_client.h +++ b/test/peer_scenario/peer_scenario_client.h @@ -22,6 +22,7 @@ #include "api/test/network_emulation_manager.h" #include "api/test/time_controller.h" #include "pc/test/frame_generator_capturer_video_track_source.h" +#include "test/create_frame_generator_capturer.h" #include "test/logging/log_writer.h" namespace webrtc {