From 68063a25dedd8165528e3177d8847f758b3e096d Mon Sep 17 00:00:00 2001 From: Artem Titov Date: Thu, 2 Apr 2020 16:31:40 +0200 Subject: [PATCH] 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 Commit-Queue: Artem Titov Cr-Commit-Position: refs/heads/master@{#30985} --- test/DEPS | 3 + test/pc/e2e/BUILD.gn | 34 ++- test/pc/e2e/media/media_helper.cc | 217 ++++++++++++++++++ test/pc/e2e/media/media_helper.h | 70 ++++++ .../test_video_capturer_video_track_source.h | 55 +++++ test/pc/e2e/peer_connection_quality_test.cc | 208 +---------------- test/pc/e2e/peer_connection_quality_test.h | 48 +--- 7 files changed, 384 insertions(+), 251 deletions(-) create mode 100644 test/pc/e2e/media/media_helper.cc create mode 100644 test/pc/e2e/media/media_helper.h create mode 100644 test/pc/e2e/media/test_video_capturer_video_track_source.h diff --git a/test/DEPS b/test/DEPS index 9bf5867bc5..62fd6d3ff7 100644 --- a/test/DEPS +++ b/test/DEPS @@ -70,4 +70,7 @@ specific_include_rules = { "+pc", "+p2p", ], + ".*test_video_capturer_video_track_source.h": [ + "+pc", + ] } diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn index c01c749dc8..8a5607a1e1 100644 --- a/test/pc/e2e/BUILD.gn +++ b/test/pc/e2e/BUILD.gn @@ -258,6 +258,29 @@ if (rtc_include_tests) { ] } + rtc_library("media_helper") { + visibility = [ "*" ] + testonly = true + sources = [ + "media/media_helper.cc", + "media/media_helper.h", + "media/test_video_capturer_video_track_source.h", + ] + deps = [ + ":test_peer", + ":video_quality_analyzer_injection_helper", + "../..:fileutils", + "../..:platform_video_capturer", + "../..:video_test_common", + "../..:video_test_support", + "../../../api:create_frame_generator", + "../../../api:frame_generator_api", + "../../../api:peer_connection_quality_test_fixture_api", + "../../../api/video:video_frame", + "../../../pc:peerconnection", + ] + } + rtc_library("peerconnection_quality_test") { visibility = [ "*" ] testonly = true @@ -270,6 +293,7 @@ if (rtc_include_tests) { ":analyzer_helper", ":default_audio_quality_analyzer", ":default_video_quality_analyzer", + ":media_helper", ":peer_connection_quality_test_params", ":sdp_changer", ":single_process_encoded_image_data_injector", @@ -279,11 +303,8 @@ if (rtc_include_tests) { ":video_quality_analyzer_injection_helper", ":video_quality_metrics_reporter", "../..:field_trial", - "../..:platform_video_capturer", - "../..:video_test_common", + "../..:fileutils", "../../../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", @@ -295,20 +316,17 @@ if (rtc_include_tests) { "../../../api/task_queue:default_task_queue_factory", "../../../api/units:time_delta", "../../../api/units:timestamp", - "../../../api/video:video_frame", "../../../pc:pc_test_utils", "../../../pc:peerconnection", "../../../rtc_base", "../../../rtc_base:gunit_helpers", + "../../../rtc_base:macromagic", "../../../rtc_base:rtc_base_approved", - "../../../rtc_base:rtc_task_queue", "../../../rtc_base:safe_conversions", "../../../rtc_base:task_queue_for_test", "../../../rtc_base/task_utils:repeating_task", "../../../system_wrappers", "../../../system_wrappers:field_trial", - "../../../test:fileutils", - "../../../test:video_test_support", ] } diff --git a/test/pc/e2e/media/media_helper.cc b/test/pc/e2e/media/media_helper.cc new file mode 100644 index 0000000000..e584795a3a --- /dev/null +++ b/test/pc/e2e/media/media_helper.cc @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2020 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/pc/e2e/media/media_helper.h" + +#include + +#include "api/test/create_frame_generator.h" +#include "test/frame_generator_capturer.h" +#include "test/platform_video_capturer.h" +#include "test/testsupport/file_utils.h" + +namespace webrtc { +namespace webrtc_pc_e2e { +namespace { + +using VideoConfig = + ::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig; +using AudioConfig = + ::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::AudioConfig; +using VideoGeneratorType = ::webrtc::webrtc_pc_e2e:: + PeerConnectionE2EQualityTestFixture::VideoGeneratorType; + +} // namespace + +MediaHelper::~MediaHelper() { + for (const auto& video_writer : video_writers_) { + video_writer->Close(); + } + video_writers_.clear(); +} + +void MediaHelper::MaybeAddAudio(TestPeer* peer) { + if (!peer->params()->audio_config) { + return; + } + const AudioConfig& audio_config = peer->params()->audio_config.value(); + rtc::scoped_refptr source = + peer->pc_factory()->CreateAudioSource(audio_config.audio_options); + rtc::scoped_refptr track = + peer->pc_factory()->CreateAudioTrack(*audio_config.stream_label, source); + std::string sync_group = audio_config.sync_group + ? audio_config.sync_group.value() + : audio_config.stream_label.value(); + peer->AddTrack(track, {sync_group, *audio_config.stream_label}); +} + +std::vector> +MediaHelper::MaybeAddVideo(TestPeer* peer) { + // Params here valid because of pre-run validation. + Params* params = peer->params(); + std::vector> out; + for (size_t i = 0; i < params->video_configs.size(); ++i) { + auto video_config = params->video_configs[i]; + // Setup input video source into peer connection. + test::VideoFrameWriter* writer = + MaybeCreateVideoWriter(video_config.input_dump_file_name, video_config); + std::unique_ptr capturer = CreateVideoCapturer( + video_config, peer->ReleaseVideoGenerator(i), + video_quality_analyzer_injection_helper_->CreateFramePreprocessor( + video_config, writer)); + rtc::scoped_refptr source = + new rtc::RefCountedObject( + std::move(capturer), + /*is_screencast=*/video_config.screen_share_config && + video_config.screen_share_config->use_text_content_hint); + out.push_back(source); + RTC_LOG(INFO) << "Adding video with video_config.stream_label=" + << video_config.stream_label.value(); + rtc::scoped_refptr track = + peer->pc_factory()->CreateVideoTrack(video_config.stream_label.value(), + source); + if (video_config.screen_share_config && + video_config.screen_share_config->use_text_content_hint) { + track->set_content_hint(VideoTrackInterface::ContentHint::kText); + } + std::string sync_group = video_config.sync_group + ? video_config.sync_group.value() + : video_config.stream_label.value(); + RTCErrorOr> sender = + peer->AddTrack(track, {sync_group, *video_config.stream_label}); + RTC_CHECK(sender.ok()); + if (video_config.temporal_layers_count) { + RtpParameters rtp_parameters = sender.value()->GetParameters(); + for (auto& encoding_parameters : rtp_parameters.encodings) { + encoding_parameters.num_temporal_layers = + video_config.temporal_layers_count; + } + RTCError res = sender.value()->SetParameters(rtp_parameters); + RTC_CHECK(res.ok()) << "Failed to set RTP parameters"; + } + } + return out; +} + +test::VideoFrameWriter* MediaHelper::MaybeCreateVideoWriter( + absl::optional file_name, + const VideoConfig& config) { + if (!file_name) { + return nullptr; + } + // TODO(titovartem) create only one file writer for simulcast video track. + // For now this code will be invoked for each simulcast stream separately, but + // only one file will be used. + auto video_writer = std::make_unique( + file_name.value(), config.width, config.height, config.fps); + test::VideoFrameWriter* out = video_writer.get(); + video_writers_.push_back(std::move(video_writer)); + return out; +} + +std::unique_ptr MediaHelper::CreateVideoCapturer( + const VideoConfig& video_config, + std::unique_ptr generator, + std::unique_ptr + frame_preprocessor) { + if (video_config.capturing_device_index) { + std::unique_ptr capturer = + test::CreateVideoCapturer(video_config.width, video_config.height, + video_config.fps, + *video_config.capturing_device_index); + RTC_CHECK(capturer) + << "Failed to obtain input stream from capturing device #" + << *video_config.capturing_device_index; + capturer->SetFramePreprocessor(std::move(frame_preprocessor)); + return capturer; + } + + std::unique_ptr frame_generator = nullptr; + if (generator) { + frame_generator = std::move(generator); + } + + if (video_config.generator) { + absl::optional + frame_generator_type = absl::nullopt; + if (video_config.generator == VideoGeneratorType::kDefault) { + frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420; + } else if (video_config.generator == VideoGeneratorType::kI420A) { + frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420A; + } else if (video_config.generator == VideoGeneratorType::kI010) { + frame_generator_type = test::FrameGeneratorInterface::OutputType::kI010; + } + frame_generator = + test::CreateSquareFrameGenerator(static_cast(video_config.width), + static_cast(video_config.height), + frame_generator_type, absl::nullopt); + } + if (video_config.input_file_name) { + frame_generator = test::CreateFromYuvFileFrameGenerator( + std::vector(/*count=*/1, + video_config.input_file_name.value()), + video_config.width, video_config.height, /*frame_repeat_count=*/1); + } + if (video_config.screen_share_config) { + frame_generator = CreateScreenShareFrameGenerator(video_config); + } + RTC_CHECK(frame_generator) << "Unsupported video_config input source"; + + auto capturer = std::make_unique( + clock_, std::move(frame_generator), video_config.fps, + *task_queue_factory_); + capturer->SetFramePreprocessor(std::move(frame_preprocessor)); + capturer->Init(); + return capturer; +} + +std::unique_ptr +MediaHelper::CreateScreenShareFrameGenerator(const VideoConfig& video_config) { + RTC_CHECK(video_config.screen_share_config); + if (video_config.screen_share_config->generate_slides) { + return test::CreateSlideFrameGenerator( + video_config.width, video_config.height, + video_config.screen_share_config->slide_change_interval.seconds() * + video_config.fps); + } + std::vector slides = + video_config.screen_share_config->slides_yuv_file_names; + if (slides.empty()) { + // If slides is empty we need to add default slides as source. In such case + // video width and height is validated to be equal to kDefaultSlidesWidth + // and kDefaultSlidesHeight. + slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); + slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); + slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); + slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); + } + if (!video_config.screen_share_config->scrolling_params) { + // Cycle image every slide_change_interval seconds. + return test::CreateFromYuvFileFrameGenerator( + slides, video_config.width, video_config.height, + video_config.screen_share_config->slide_change_interval.seconds() * + video_config.fps); + } + + // |pause_duration| is nonnegative. It is validated in ValidateParams(...). + TimeDelta pause_duration = + video_config.screen_share_config->slide_change_interval - + video_config.screen_share_config->scrolling_params->duration; + + return test::CreateScrollingInputFromYuvFilesFrameGenerator( + clock_, slides, + video_config.screen_share_config->scrolling_params->source_width, + video_config.screen_share_config->scrolling_params->source_height, + video_config.width, video_config.height, + video_config.screen_share_config->scrolling_params->duration.ms(), + pause_duration.ms()); +} + +} // namespace webrtc_pc_e2e +} // namespace webrtc diff --git a/test/pc/e2e/media/media_helper.h b/test/pc/e2e/media/media_helper.h new file mode 100644 index 0000000000..740cd2c00a --- /dev/null +++ b/test/pc/e2e/media/media_helper.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 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 TEST_PC_E2E_MEDIA_MEDIA_HELPER_H_ +#define TEST_PC_E2E_MEDIA_MEDIA_HELPER_H_ + +#include +#include +#include + +#include "api/test/frame_generator_interface.h" +#include "api/test/peerconnection_quality_test_fixture.h" +#include "test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h" +#include "test/pc/e2e/media/test_video_capturer_video_track_source.h" +#include "test/pc/e2e/test_peer.h" +#include "test/testsupport/video_frame_writer.h" + +namespace webrtc { +namespace webrtc_pc_e2e { + +class MediaHelper { + public: + MediaHelper(VideoQualityAnalyzerInjectionHelper* + video_quality_analyzer_injection_helper, + TaskQueueFactory* task_queue_factory) + : clock_(Clock::GetRealTimeClock()), + task_queue_factory_(task_queue_factory), + video_quality_analyzer_injection_helper_( + video_quality_analyzer_injection_helper) {} + ~MediaHelper(); + + void MaybeAddAudio(TestPeer* peer); + + std::vector> + MaybeAddVideo(TestPeer* peer); + + // Creates a video file writer if |file_name| is not empty. Created writer + // will be owned by MediaHelper and will be closed on MediaHelper destruction. + // If |file_name| is empty will return nullptr. + test::VideoFrameWriter* MaybeCreateVideoWriter( + absl::optional file_name, + const PeerConnectionE2EQualityTestFixture::VideoConfig& config); + + private: + std::unique_ptr CreateVideoCapturer( + const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config, + std::unique_ptr generator, + std::unique_ptr + frame_preprocessor); + std::unique_ptr + CreateScreenShareFrameGenerator( + const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config); + + Clock* const clock_; + TaskQueueFactory* const task_queue_factory_; + VideoQualityAnalyzerInjectionHelper* video_quality_analyzer_injection_helper_; + std::vector> video_writers_; +}; + +} // namespace webrtc_pc_e2e +} // namespace webrtc + +#endif // TEST_PC_E2E_MEDIA_MEDIA_HELPER_H_ diff --git a/test/pc/e2e/media/test_video_capturer_video_track_source.h b/test/pc/e2e/media/test_video_capturer_video_track_source.h new file mode 100644 index 0000000000..c883a2e8e9 --- /dev/null +++ b/test/pc/e2e/media/test_video_capturer_video_track_source.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 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 TEST_PC_E2E_MEDIA_TEST_VIDEO_CAPTURER_VIDEO_TRACK_SOURCE_H_ +#define TEST_PC_E2E_MEDIA_TEST_VIDEO_CAPTURER_VIDEO_TRACK_SOURCE_H_ + +#include +#include + +#include "api/video/video_frame.h" +#include "api/video/video_source_interface.h" +#include "pc/video_track_source.h" +#include "test/test_video_capturer.h" + +namespace webrtc { +namespace webrtc_pc_e2e { + +class TestVideoCapturerVideoTrackSource : public VideoTrackSource { + public: + TestVideoCapturerVideoTrackSource( + std::unique_ptr video_capturer, + bool is_screencast) + : VideoTrackSource(/*remote=*/false), + video_capturer_(std::move(video_capturer)), + is_screencast_(is_screencast) {} + + ~TestVideoCapturerVideoTrackSource() = default; + + void Start() { SetState(kLive); } + + void Stop() { SetState(kMuted); } + + bool is_screencast() const override { return is_screencast_; } + + protected: + rtc::VideoSourceInterface* source() override { + return video_capturer_.get(); + } + + private: + std::unique_ptr video_capturer_; + const bool is_screencast_; +}; + +} // namespace webrtc_pc_e2e +} // namespace webrtc + +#endif // TEST_PC_E2E_MEDIA_TEST_VIDEO_CAPTURER_VIDEO_TRACK_SOURCE_H_ diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc index bf25443eab..3d1ab66cf5 100644 --- a/test/pc/e2e/peer_connection_quality_test.cc +++ b/test/pc/e2e/peer_connection_quality_test.cc @@ -21,10 +21,8 @@ #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" #include "pc/sdp_utils.h" #include "pc/test/mock_peer_connection_observers.h" #include "rtc_base/bind.h" @@ -32,13 +30,11 @@ #include "rtc_base/numerics/safe_conversions.h" #include "system_wrappers/include/cpu_info.h" #include "system_wrappers/include/field_trial.h" -#include "test/frame_generator_capturer.h" #include "test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h" #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer.h" #include "test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h" #include "test/pc/e2e/stats_poller.h" #include "test/pc/e2e/test_peer_factory.h" -#include "test/platform_video_capturer.h" #include "test/testsupport/file_utils.h" namespace webrtc { @@ -271,6 +267,9 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { const std::unique_ptr signaling_thread = rtc::Thread::Create(); signaling_thread->SetName(kSignalThreadName, nullptr); signaling_thread->Start(); + media_helper_ = std::make_unique( + video_quality_analyzer_injection_helper_.get(), + task_queue_factory_.get()); // Create a |task_queue_|. task_queue_ = std::make_unique("pc_e2e_quality_test"); @@ -449,11 +448,10 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { // Audio dumps. RTC_CHECK(!alice_); RTC_CHECK(!bob_); - // Ensuring that TestVideoCapturerVideoTrackSource and VideoFrameWriter - // are destroyed on the right thread. + // Ensuring that TestVideoCapturerVideoTrackSource are destroyed on the right + // thread. RTC_CHECK(alice_video_sources_.empty()); RTC_CHECK(bob_video_sources_.empty()); - RTC_CHECK(video_writers_.empty()); } void PeerConnectionE2EQualityTest::SetDefaultValuesForMissingParams( @@ -649,7 +647,7 @@ void PeerConnectionE2EQualityTest::OnTrackCallback( } } RTC_CHECK(video_config); - test::VideoFrameWriter* writer = MaybeCreateVideoWriter( + test::VideoFrameWriter* writer = media_helper_->MaybeCreateVideoWriter( video_config->output_dump_file_name, *video_config); // It is safe to cast here, because it is checked above that // track->kind() is kVideoKind. @@ -727,8 +725,10 @@ void PeerConnectionE2EQualityTest::SetupCallOnSignalingThread( } // Then add media for Alice and Bob - alice_video_sources_ = MaybeAddMedia(alice_.get()); - bob_video_sources_ = MaybeAddMedia(bob_.get()); + media_helper_->MaybeAddAudio(alice_.get()); + alice_video_sources_ = media_helper_->MaybeAddVideo(alice_.get()); + media_helper_->MaybeAddAudio(bob_.get()); + bob_video_sources_ = media_helper_->MaybeAddVideo(bob_.get()); SetPeerCodecPreferences(alice_.get(), run_params); SetPeerCodecPreferences(bob_.get(), run_params); @@ -740,175 +740,6 @@ void PeerConnectionE2EQualityTest::TearDownCallOnSignalingThread() { TearDownCall(); } -std::vector> -PeerConnectionE2EQualityTest::MaybeAddMedia(TestPeer* peer) { - MaybeAddAudio(peer); - return MaybeAddVideo(peer); -} - -std::vector> -PeerConnectionE2EQualityTest::MaybeAddVideo(TestPeer* peer) { - // Params here valid because of pre-run validation. - Params* params = peer->params(); - std::vector> out; - for (size_t i = 0; i < params->video_configs.size(); ++i) { - auto video_config = params->video_configs[i]; - // Setup input video source into peer connection. - test::VideoFrameWriter* writer = - MaybeCreateVideoWriter(video_config.input_dump_file_name, video_config); - std::unique_ptr capturer = CreateVideoCapturer( - video_config, peer->ReleaseVideoGenerator(i), - video_quality_analyzer_injection_helper_->CreateFramePreprocessor( - video_config, writer)); - rtc::scoped_refptr source = - new rtc::RefCountedObject( - std::move(capturer), - /*is_screencast=*/video_config.screen_share_config && - video_config.screen_share_config->use_text_content_hint); - out.push_back(source); - RTC_LOG(INFO) << "Adding video with video_config.stream_label=" - << video_config.stream_label.value(); - rtc::scoped_refptr track = - peer->pc_factory()->CreateVideoTrack(video_config.stream_label.value(), - source); - if (video_config.screen_share_config && - video_config.screen_share_config->use_text_content_hint) { - track->set_content_hint(VideoTrackInterface::ContentHint::kText); - } - std::string sync_group = video_config.sync_group - ? video_config.sync_group.value() - : video_config.stream_label.value(); - RTCErrorOr> sender = - peer->AddTrack(track, {sync_group, *video_config.stream_label}); - RTC_CHECK(sender.ok()); - if (video_config.temporal_layers_count) { - RtpParameters rtp_parameters = sender.value()->GetParameters(); - for (auto& encoding_parameters : rtp_parameters.encodings) { - encoding_parameters.num_temporal_layers = - video_config.temporal_layers_count; - } - RTCError res = sender.value()->SetParameters(rtp_parameters); - RTC_CHECK(res.ok()) << "Failed to set RTP parameters"; - } - } - return out; -} - -std::unique_ptr -PeerConnectionE2EQualityTest::CreateVideoCapturer( - const VideoConfig& video_config, - std::unique_ptr generator, - std::unique_ptr - frame_preprocessor) { - if (video_config.capturing_device_index) { - std::unique_ptr capturer = - test::CreateVideoCapturer(video_config.width, video_config.height, - video_config.fps, - *video_config.capturing_device_index); - RTC_CHECK(capturer) - << "Failed to obtain input stream from capturing device #" - << *video_config.capturing_device_index; - capturer->SetFramePreprocessor(std::move(frame_preprocessor)); - return capturer; - } - - std::unique_ptr frame_generator = nullptr; - if (generator) { - frame_generator = std::move(generator); - } - - if (video_config.generator) { - absl::optional - frame_generator_type = absl::nullopt; - if (video_config.generator == VideoGeneratorType::kDefault) { - frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420; - } else if (video_config.generator == VideoGeneratorType::kI420A) { - frame_generator_type = test::FrameGeneratorInterface::OutputType::kI420A; - } else if (video_config.generator == VideoGeneratorType::kI010) { - frame_generator_type = test::FrameGeneratorInterface::OutputType::kI010; - } - frame_generator = - test::CreateSquareFrameGenerator(static_cast(video_config.width), - static_cast(video_config.height), - frame_generator_type, absl::nullopt); - } - if (video_config.input_file_name) { - frame_generator = test::CreateFromYuvFileFrameGenerator( - std::vector(/*count=*/1, - video_config.input_file_name.value()), - video_config.width, video_config.height, /*frame_repeat_count=*/1); - } - if (video_config.screen_share_config) { - frame_generator = CreateScreenShareFrameGenerator(video_config); - } - RTC_CHECK(frame_generator) << "Unsupported video_config input source"; - - auto capturer = std::make_unique( - clock_, std::move(frame_generator), video_config.fps, - *task_queue_factory_); - capturer->SetFramePreprocessor(std::move(frame_preprocessor)); - capturer->Init(); - return capturer; -} - -std::unique_ptr -PeerConnectionE2EQualityTest::CreateScreenShareFrameGenerator( - const VideoConfig& video_config) { - RTC_CHECK(video_config.screen_share_config); - if (video_config.screen_share_config->generate_slides) { - return test::CreateSlideFrameGenerator( - video_config.width, video_config.height, - video_config.screen_share_config->slide_change_interval.seconds() * - video_config.fps); - } - std::vector slides = - video_config.screen_share_config->slides_yuv_file_names; - if (slides.empty()) { - // If slides is empty we need to add default slides as source. In such case - // video width and height is validated to be equal to kDefaultSlidesWidth - // and kDefaultSlidesHeight. - slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); - slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); - slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); - slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); - } - if (!video_config.screen_share_config->scrolling_params) { - // Cycle image every slide_change_interval seconds. - return test::CreateFromYuvFileFrameGenerator( - slides, video_config.width, video_config.height, - video_config.screen_share_config->slide_change_interval.seconds() * - video_config.fps); - } - - // |pause_duration| is nonnegative. It is validated in ValidateParams(...). - TimeDelta pause_duration = - video_config.screen_share_config->slide_change_interval - - video_config.screen_share_config->scrolling_params->duration; - - return test::CreateScrollingInputFromYuvFilesFrameGenerator( - clock_, slides, - video_config.screen_share_config->scrolling_params->source_width, - video_config.screen_share_config->scrolling_params->source_height, - video_config.width, video_config.height, - video_config.screen_share_config->scrolling_params->duration.ms(), - pause_duration.ms()); -} - -void PeerConnectionE2EQualityTest::MaybeAddAudio(TestPeer* peer) { - if (!peer->params()->audio_config) { - return; - } - const AudioConfig& audio_config = peer->params()->audio_config.value(); - rtc::scoped_refptr source = - peer->pc_factory()->CreateAudioSource(audio_config.audio_options); - rtc::scoped_refptr track = - peer->pc_factory()->CreateAudioTrack(*audio_config.stream_label, source); - std::string sync_group = audio_config.sync_group - ? audio_config.sync_group.value() - : audio_config.stream_label.value(); - peer->AddTrack(track, {sync_group, *audio_config.stream_label}); -} - void PeerConnectionE2EQualityTest::SetPeerCodecPreferences( TestPeer* peer, const RunParams& run_params) { @@ -1065,24 +896,7 @@ void PeerConnectionE2EQualityTest::TearDownCall() { alice_.reset(); bob_.reset(); - for (const auto& video_writer : video_writers_) { - video_writer->Close(); - } - video_writers_.clear(); -} - -test::VideoFrameWriter* PeerConnectionE2EQualityTest::MaybeCreateVideoWriter( - absl::optional file_name, - const VideoConfig& config) { - if (!file_name) { - return nullptr; - } - // TODO(titovartem) create only one file writer for simulcast video track. - auto video_writer = std::make_unique( - file_name.value(), config.width, config.height, config.fps); - test::VideoFrameWriter* out = video_writer.get(); - video_writers_.push_back(std::move(video_writer)); - return out; + media_helper_.reset(); } Timestamp PeerConnectionE2EQualityTest::Now() const { diff --git a/test/pc/e2e/peer_connection_quality_test.h b/test/pc/e2e/peer_connection_quality_test.h index 894e78f6b0..8fc7a42303 100644 --- a/test/pc/e2e/peer_connection_quality_test.h +++ b/test/pc/e2e/peer_connection_quality_test.h @@ -17,11 +17,9 @@ #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" -#include "pc/video_track_source.h" #include "rtc_base/task_queue_for_test.h" #include "rtc_base/task_utils/repeating_task.h" #include "rtc_base/thread.h" @@ -31,10 +29,10 @@ #include "test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h" #include "test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h" #include "test/pc/e2e/analyzer_helper.h" +#include "test/pc/e2e/media/media_helper.h" #include "test/pc/e2e/peer_connection_quality_test_params.h" #include "test/pc/e2e/sdp/sdp_changer.h" #include "test/pc/e2e/test_peer.h" -#include "test/testsupport/video_frame_writer.h" namespace webrtc { namespace webrtc_pc_e2e { @@ -184,33 +182,6 @@ class PeerConfigurerImpl final std::vector> video_generators_; }; -class TestVideoCapturerVideoTrackSource : public VideoTrackSource { - public: - TestVideoCapturerVideoTrackSource( - std::unique_ptr video_capturer, - bool is_screencast) - : VideoTrackSource(/*remote=*/false), - video_capturer_(std::move(video_capturer)), - is_screencast_(is_screencast) {} - - ~TestVideoCapturerVideoTrackSource() = default; - - void Start() { SetState(kLive); } - - void Stop() { SetState(kMuted); } - - bool is_screencast() const override { return is_screencast_; } - - protected: - rtc::VideoSourceInterface* source() override { - return video_capturer_.get(); - } - - private: - std::unique_ptr video_capturer_; - const bool is_screencast_; -}; - class PeerConnectionE2EQualityTest : public PeerConnectionE2EQualityTestFixture { public: @@ -291,18 +262,6 @@ class PeerConnectionE2EQualityTest // Have to be run on the signaling thread. void SetupCallOnSignalingThread(const RunParams& run_params); void TearDownCallOnSignalingThread(); - std::vector> - MaybeAddMedia(TestPeer* peer); - std::vector> - MaybeAddVideo(TestPeer* peer); - std::unique_ptr CreateVideoCapturer( - const VideoConfig& video_config, - std::unique_ptr generator, - std::unique_ptr - frame_preprocessor); - std::unique_ptr - CreateScreenShareFrameGenerator(const VideoConfig& video_config); - void MaybeAddAudio(TestPeer* peer); void SetPeerCodecPreferences(TestPeer* peer, const RunParams& run_params); void SetupCall(const RunParams& run_params); void ExchangeOfferAnswer(SignalingInterceptor* signaling_interceptor); @@ -311,9 +270,6 @@ class PeerConnectionE2EQualityTest const std::vector>& sources); void TearDownCall(); - test::VideoFrameWriter* MaybeCreateVideoWriter( - absl::optional file_name, - const VideoConfig& config); Timestamp Now() const; Clock* const clock_; @@ -321,6 +277,7 @@ class PeerConnectionE2EQualityTest std::string test_case_name_; std::unique_ptr video_quality_analyzer_injection_helper_; + std::unique_ptr media_helper_; std::unique_ptr encoded_image_id_controller_; std::unique_ptr audio_quality_analyzer_; @@ -338,7 +295,6 @@ class PeerConnectionE2EQualityTest alice_video_sources_; std::vector> bob_video_sources_; - std::vector> video_writers_; std::vector>> output_video_sinks_; AnalyzerHelper analyzer_helper_;