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}
This commit is contained in:
Artem Titov
2019-12-04 12:37:13 +01:00
committed by Commit Bot
parent 340af975e9
commit 503d7237ce
12 changed files with 246 additions and 44 deletions

View File

@ -374,6 +374,20 @@ rtc_source_set("peer_connection_quality_test_fixture_api") {
]
}
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 @@ if (rtc_include_tests) {
"../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") {

View File

@ -37,4 +37,7 @@ specific_include_rules = {
"+rtc_base/synchronization/yield_policy.h",
"+system_wrappers/include/clock.h",
],
"create_frame_generator\.h": [
"+system_wrappers/include/clock.h",
],
}

View File

@ -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

View File

@ -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_

View File

@ -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_

View File

@ -53,6 +53,7 @@ rtc_library("video_test_common") {
deps = [
":fileutils",
"../api:frame_generator_api",
"../api:scoped_refptr",
"../api/task_queue",
"../api/video:video_frame",

View File

@ -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 @@ class FrameForwarder : public rtc::VideoSourceInterface<VideoFrame> {
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.

View File

@ -44,7 +44,7 @@ std::string TransformFilePath(std::string path) {
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),

View File

@ -96,10 +96,11 @@ class FrameGeneratorCapturer : public TestVideoCapturer {
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 @@ class FrameGeneratorCapturer : public TestVideoCapturer {
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_);

View File

@ -292,6 +292,8 @@ if (rtc_include_tests) {
"../..: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",

View File

@ -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 @@ PeerConnectionE2EQualityTest::CreateVideoCapturer(
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 @@ PeerConnectionE2EQualityTest::CreateVideoCapturer(
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 @@ PeerConnectionE2EQualityTest::CreateScreenShareFrameGenerator(
}
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 @@ PeerConnectionE2EQualityTest::CreateScreenShareFrameGenerator(
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,

View File

@ -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 @@ class PeerConnectionE2EQualityTest
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);