Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 68063a2

Browse files
titov-artemCommit Bot
authored andcommitted
Move media configuration for PC level tests into separate class
Bug: webrtc:11479 Change-Id: I325e5c6f5d571dde0fdb5d579bf85cf32a81e174 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172783 Reviewed-by: Mirko Bonadei <[email protected]> Commit-Queue: Artem Titov <[email protected]> Cr-Commit-Position: refs/heads/master@{#30985}
1 parent 06d3559 commit 68063a2

File tree

7 files changed

+384
-251
lines changed

7 files changed

+384
-251
lines changed

test/DEPS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,7 @@ specific_include_rules = {
7070
"+pc",
7171
"+p2p",
7272
],
73+
".*test_video_capturer_video_track_source.h": [
74+
"+pc",
75+
]
7376
}

test/pc/e2e/BUILD.gn

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,29 @@ if (rtc_include_tests) {
258258
]
259259
}
260260

261+
rtc_library("media_helper") {
262+
visibility = [ "*" ]
263+
testonly = true
264+
sources = [
265+
"media/media_helper.cc",
266+
"media/media_helper.h",
267+
"media/test_video_capturer_video_track_source.h",
268+
]
269+
deps = [
270+
":test_peer",
271+
":video_quality_analyzer_injection_helper",
272+
"../..:fileutils",
273+
"../..:platform_video_capturer",
274+
"../..:video_test_common",
275+
"../..:video_test_support",
276+
"../../../api:create_frame_generator",
277+
"../../../api:frame_generator_api",
278+
"../../../api:peer_connection_quality_test_fixture_api",
279+
"../../../api/video:video_frame",
280+
"../../../pc:peerconnection",
281+
]
282+
}
283+
261284
rtc_library("peerconnection_quality_test") {
262285
visibility = [ "*" ]
263286
testonly = true
@@ -270,6 +293,7 @@ if (rtc_include_tests) {
270293
":analyzer_helper",
271294
":default_audio_quality_analyzer",
272295
":default_video_quality_analyzer",
296+
":media_helper",
273297
":peer_connection_quality_test_params",
274298
":sdp_changer",
275299
":single_process_encoded_image_data_injector",
@@ -279,11 +303,8 @@ if (rtc_include_tests) {
279303
":video_quality_analyzer_injection_helper",
280304
":video_quality_metrics_reporter",
281305
"../..:field_trial",
282-
"../..:platform_video_capturer",
283-
"../..:video_test_common",
306+
"../..:fileutils",
284307
"../../../api:audio_quality_analyzer_api",
285-
"../../../api:create_frame_generator",
286-
"../../../api:frame_generator_api",
287308
"../../../api:libjingle_peerconnection_api",
288309
"../../../api:media_stream_interface",
289310
"../../../api:peer_connection_quality_test_fixture_api",
@@ -295,20 +316,17 @@ if (rtc_include_tests) {
295316
"../../../api/task_queue:default_task_queue_factory",
296317
"../../../api/units:time_delta",
297318
"../../../api/units:timestamp",
298-
"../../../api/video:video_frame",
299319
"../../../pc:pc_test_utils",
300320
"../../../pc:peerconnection",
301321
"../../../rtc_base",
302322
"../../../rtc_base:gunit_helpers",
323+
"../../../rtc_base:macromagic",
303324
"../../../rtc_base:rtc_base_approved",
304-
"../../../rtc_base:rtc_task_queue",
305325
"../../../rtc_base:safe_conversions",
306326
"../../../rtc_base:task_queue_for_test",
307327
"../../../rtc_base/task_utils:repeating_task",
308328
"../../../system_wrappers",
309329
"../../../system_wrappers:field_trial",
310-
"../../../test:fileutils",
311-
"../../../test:video_test_support",
312330
]
313331
}
314332

test/pc/e2e/media/media_helper.cc

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree. An additional intellectual property rights grant can be found
7+
* in the file PATENTS. All contributing project authors may
8+
* be found in the AUTHORS file in the root of the source tree.
9+
*/
10+
#include "test/pc/e2e/media/media_helper.h"
11+
12+
#include <utility>
13+
14+
#include "api/test/create_frame_generator.h"
15+
#include "test/frame_generator_capturer.h"
16+
#include "test/platform_video_capturer.h"
17+
#include "test/testsupport/file_utils.h"
18+
19+
namespace webrtc {
20+
namespace webrtc_pc_e2e {
21+
namespace {
22+
23+
using VideoConfig =
24+
::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig;
25+
using AudioConfig =
26+
::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::AudioConfig;
27+
using VideoGeneratorType = ::webrtc::webrtc_pc_e2e::
28+
PeerConnectionE2EQualityTestFixture::VideoGeneratorType;
29+
30+
} // namespace
31+
32+
MediaHelper::~MediaHelper() {
33+
for (const auto& video_writer : video_writers_) {
34+
video_writer->Close();
35+
}
36+
video_writers_.clear();
37+
}
38+
39+
void MediaHelper::MaybeAddAudio(TestPeer* peer) {
40+
if (!peer->params()->audio_config) {
41+
return;
42+
}
43+
const AudioConfig& audio_config = peer->params()->audio_config.value();
44+
rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
45+
peer->pc_factory()->CreateAudioSource(audio_config.audio_options);
46+
rtc::scoped_refptr<AudioTrackInterface> track =
47+
peer->pc_factory()->CreateAudioTrack(*audio_config.stream_label, source);
48+
std::string sync_group = audio_config.sync_group
49+
? audio_config.sync_group.value()
50+
: audio_config.stream_label.value();
51+
peer->AddTrack(track, {sync_group, *audio_config.stream_label});
52+
}
53+
54+
std::vector<rtc::scoped_refptr<TestVideoCapturerVideoTrackSource>>
55+
MediaHelper::MaybeAddVideo(TestPeer* peer) {
56+
// Params here valid because of pre-run validation.
57+
Params* params = peer->params();
58+
std::vector<rtc::scoped_refptr<TestVideoCapturerVideoTrackSource>> out;
59+
for (size_t i = 0; i < params->video_configs.size(); ++i) {
60+
auto video_config = params->video_configs[i];
61+
// Setup input video source into peer connection.
62+
test::VideoFrameWriter* writer =
63+
MaybeCreateVideoWriter(video_config.input_dump_file_name, video_config);
64+
std::unique_ptr<test::TestVideoCapturer> capturer = CreateVideoCapturer(
65+
video_config, peer->ReleaseVideoGenerator(i),
66+
video_quality_analyzer_injection_helper_->CreateFramePreprocessor(
67+
video_config, writer));
68+
rtc::scoped_refptr<TestVideoCapturerVideoTrackSource> source =
69+
new rtc::RefCountedObject<TestVideoCapturerVideoTrackSource>(
70+
std::move(capturer),
71+
/*is_screencast=*/video_config.screen_share_config &&
72+
video_config.screen_share_config->use_text_content_hint);
73+
out.push_back(source);
74+
RTC_LOG(INFO) << "Adding video with video_config.stream_label="
75+
<< video_config.stream_label.value();
76+
rtc::scoped_refptr<VideoTrackInterface> track =
77+
peer->pc_factory()->CreateVideoTrack(video_config.stream_label.value(),
78+
source);
79+
if (video_config.screen_share_config &&
80+
video_config.screen_share_config->use_text_content_hint) {
81+
track->set_content_hint(VideoTrackInterface::ContentHint::kText);
82+
}
83+
std::string sync_group = video_config.sync_group
84+
? video_config.sync_group.value()
85+
: video_config.stream_label.value();
86+
RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> sender =
87+
peer->AddTrack(track, {sync_group, *video_config.stream_label});
88+
RTC_CHECK(sender.ok());
89+
if (video_config.temporal_layers_count) {
90+
RtpParameters rtp_parameters = sender.value()->GetParameters();
91+
for (auto& encoding_parameters : rtp_parameters.encodings) {
92+
encoding_parameters.num_temporal_layers =
93+
video_config.temporal_layers_count;
94+
}
95+
RTCError res = sender.value()->SetParameters(rtp_parameters);
96+
RTC_CHECK(res.ok()) << "Failed to set RTP parameters";
97+
}
98+
}
99+
return out;
100+
}
101+
102+
test::VideoFrameWriter* MediaHelper::MaybeCreateVideoWriter(
103+
absl::optional<std::string> file_name,
104+
const VideoConfig& config) {
105+
if (!file_name) {
106+
return nullptr;
107+
}
108+
// TODO(titovartem) create only one file writer for simulcast video track.
109+
// For now this code will be invoked for each simulcast stream separately, but
110+
// only one file will be used.
111+
auto video_writer = std::make_unique<test::Y4mVideoFrameWriterImpl>(
112+
file_name.value(), config.width, config.height, config.fps);
113+
test::VideoFrameWriter* out = video_writer.get();
114+
video_writers_.push_back(std::move(video_writer));
115+
return out;
116+
}
117+
118+
std::unique_ptr<test::TestVideoCapturer> MediaHelper::CreateVideoCapturer(
119+
const VideoConfig& video_config,
120+
std::unique_ptr<test::FrameGeneratorInterface> generator,
121+
std::unique_ptr<test::TestVideoCapturer::FramePreprocessor>
122+
frame_preprocessor) {
123+
if (video_config.capturing_device_index) {
124+
std::unique_ptr<test::TestVideoCapturer> capturer =
125+
test::CreateVideoCapturer(video_config.width, video_config.height,
126+
video_config.fps,
127+
*video_config.capturing_device_index);
128+
RTC_CHECK(capturer)
129+
<< "Failed to obtain input stream from capturing device #"
130+
<< *video_config.capturing_device_index;
131+
capturer->SetFramePreprocessor(std::move(frame_preprocessor));
132+
return capturer;
133+
}
134+
135+
std::unique_ptr<test::FrameGeneratorInterface> frame_generator = nullptr;
136+
if (generator) {
137+
frame_generator = std::move(generator);
138+
}
139+
140+
if (video_config.generator) {
141+
absl::optional<test::FrameGeneratorInterface::OutputType>
142+
frame_generator_type = absl::nullopt;
143+
if (video_config.generator == VideoGeneratorType::kDefault) {
144+
frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420;
145+
} else if (video_config.generator == VideoGeneratorType::kI420A) {
146+
frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420A;
147+
} else if (video_config.generator == VideoGeneratorType::kI010) {
148+
frame_generator_type = test::FrameGeneratorInterface::OutputType::kI010;
149+
}
150+
frame_generator =
151+
test::CreateSquareFrameGenerator(static_cast<int>(video_config.width),
152+
static_cast<int>(video_config.height),
153+
frame_generator_type, absl::nullopt);
154+
}
155+
if (video_config.input_file_name) {
156+
frame_generator = test::CreateFromYuvFileFrameGenerator(
157+
std::vector<std::string>(/*count=*/1,
158+
video_config.input_file_name.value()),
159+
video_config.width, video_config.height, /*frame_repeat_count=*/1);
160+
}
161+
if (video_config.screen_share_config) {
162+
frame_generator = CreateScreenShareFrameGenerator(video_config);
163+
}
164+
RTC_CHECK(frame_generator) << "Unsupported video_config input source";
165+
166+
auto capturer = std::make_unique<test::FrameGeneratorCapturer>(
167+
clock_, std::move(frame_generator), video_config.fps,
168+
*task_queue_factory_);
169+
capturer->SetFramePreprocessor(std::move(frame_preprocessor));
170+
capturer->Init();
171+
return capturer;
172+
}
173+
174+
std::unique_ptr<test::FrameGeneratorInterface>
175+
MediaHelper::CreateScreenShareFrameGenerator(const VideoConfig& video_config) {
176+
RTC_CHECK(video_config.screen_share_config);
177+
if (video_config.screen_share_config->generate_slides) {
178+
return test::CreateSlideFrameGenerator(
179+
video_config.width, video_config.height,
180+
video_config.screen_share_config->slide_change_interval.seconds() *
181+
video_config.fps);
182+
}
183+
std::vector<std::string> slides =
184+
video_config.screen_share_config->slides_yuv_file_names;
185+
if (slides.empty()) {
186+
// If slides is empty we need to add default slides as source. In such case
187+
// video width and height is validated to be equal to kDefaultSlidesWidth
188+
// and kDefaultSlidesHeight.
189+
slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv"));
190+
slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv"));
191+
slides.push_back(test::ResourcePath("photo_1850_1110", "yuv"));
192+
slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv"));
193+
}
194+
if (!video_config.screen_share_config->scrolling_params) {
195+
// Cycle image every slide_change_interval seconds.
196+
return test::CreateFromYuvFileFrameGenerator(
197+
slides, video_config.width, video_config.height,
198+
video_config.screen_share_config->slide_change_interval.seconds() *
199+
video_config.fps);
200+
}
201+
202+
// |pause_duration| is nonnegative. It is validated in ValidateParams(...).
203+
TimeDelta pause_duration =
204+
video_config.screen_share_config->slide_change_interval -
205+
video_config.screen_share_config->scrolling_params->duration;
206+
207+
return test::CreateScrollingInputFromYuvFilesFrameGenerator(
208+
clock_, slides,
209+
video_config.screen_share_config->scrolling_params->source_width,
210+
video_config.screen_share_config->scrolling_params->source_height,
211+
video_config.width, video_config.height,
212+
video_config.screen_share_config->scrolling_params->duration.ms(),
213+
pause_duration.ms());
214+
}
215+
216+
} // namespace webrtc_pc_e2e
217+
} // namespace webrtc

test/pc/e2e/media/media_helper.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree. An additional intellectual property rights grant can be found
7+
* in the file PATENTS. All contributing project authors may
8+
* be found in the AUTHORS file in the root of the source tree.
9+
*/
10+
11+
#ifndef TEST_PC_E2E_MEDIA_MEDIA_HELPER_H_
12+
#define TEST_PC_E2E_MEDIA_MEDIA_HELPER_H_
13+
14+
#include <memory>
15+
#include <string>
16+
#include <vector>
17+
18+
#include "api/test/frame_generator_interface.h"
19+
#include "api/test/peerconnection_quality_test_fixture.h"
20+
#include "test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h"
21+
#include "test/pc/e2e/media/test_video_capturer_video_track_source.h"
22+
#include "test/pc/e2e/test_peer.h"
23+
#include "test/testsupport/video_frame_writer.h"
24+
25+
namespace webrtc {
26+
namespace webrtc_pc_e2e {
27+
28+
class MediaHelper {
29+
public:
30+
MediaHelper(VideoQualityAnalyzerInjectionHelper*
31+
video_quality_analyzer_injection_helper,
32+
TaskQueueFactory* task_queue_factory)
33+
: clock_(Clock::GetRealTimeClock()),
34+
task_queue_factory_(task_queue_factory),
35+
video_quality_analyzer_injection_helper_(
36+
video_quality_analyzer_injection_helper) {}
37+
~MediaHelper();
38+
39+
void MaybeAddAudio(TestPeer* peer);
40+
41+
std::vector<rtc::scoped_refptr<TestVideoCapturerVideoTrackSource>>
42+
MaybeAddVideo(TestPeer* peer);
43+
44+
// Creates a video file writer if |file_name| is not empty. Created writer
45+
// will be owned by MediaHelper and will be closed on MediaHelper destruction.
46+
// If |file_name| is empty will return nullptr.
47+
test::VideoFrameWriter* MaybeCreateVideoWriter(
48+
absl::optional<std::string> file_name,
49+
const PeerConnectionE2EQualityTestFixture::VideoConfig& config);
50+
51+
private:
52+
std::unique_ptr<test::TestVideoCapturer> CreateVideoCapturer(
53+
const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config,
54+
std::unique_ptr<test::FrameGeneratorInterface> generator,
55+
std::unique_ptr<test::TestVideoCapturer::FramePreprocessor>
56+
frame_preprocessor);
57+
std::unique_ptr<test::FrameGeneratorInterface>
58+
CreateScreenShareFrameGenerator(
59+
const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config);
60+
61+
Clock* const clock_;
62+
TaskQueueFactory* const task_queue_factory_;
63+
VideoQualityAnalyzerInjectionHelper* video_quality_analyzer_injection_helper_;
64+
std::vector<std::unique_ptr<test::VideoFrameWriter>> video_writers_;
65+
};
66+
67+
} // namespace webrtc_pc_e2e
68+
} // namespace webrtc
69+
70+
#endif // TEST_PC_E2E_MEDIA_MEDIA_HELPER_H_

0 commit comments

Comments
 (0)