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:
29
api/BUILD.gn
29
api/BUILD.gn
@ -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") {
|
||||
|
@ -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",
|
||||
],
|
||||
}
|
||||
|
60
api/test/create_frame_generator.cc
Normal file
60
api/test/create_frame_generator.cc
Normal 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
|
72
api/test/create_frame_generator.h
Normal file
72
api/test/create_frame_generator.h
Normal 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_
|
50
api/test/frame_generator_interface.h
Normal file
50
api/test/frame_generator_interface.h
Normal 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_
|
@ -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",
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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_);
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user