/* * 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 TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_H_ #define TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_H_ #include #include #include #include #include "api/task_queue/task_queue_factory.h" #include "api/test/audio_quality_analyzer_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" #include "rtc_base/thread_annotations.h" #include "system_wrappers/include/clock.h" #include "test/field_trial.h" #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/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 { class PeerConfigurerImpl final : public PeerConnectionE2EQualityTestFixture::PeerConfigurer { public: PeerConfigurerImpl(rtc::Thread* network_thread, rtc::NetworkManager* network_manager) : components_(std::make_unique(network_thread, network_manager)), params_(std::make_unique()) {} PeerConfigurer* SetTaskQueueFactory( std::unique_ptr task_queue_factory) override { components_->pcf_dependencies->task_queue_factory = std::move(task_queue_factory); return this; } PeerConfigurer* SetCallFactory( std::unique_ptr call_factory) override { components_->pcf_dependencies->call_factory = std::move(call_factory); return this; } PeerConfigurer* SetEventLogFactory( std::unique_ptr event_log_factory) override { components_->pcf_dependencies->event_log_factory = std::move(event_log_factory); return this; } PeerConfigurer* SetFecControllerFactory( std::unique_ptr fec_controller_factory) override { components_->pcf_dependencies->fec_controller_factory = std::move(fec_controller_factory); return this; } PeerConfigurer* SetNetworkControllerFactory( std::unique_ptr network_controller_factory) override { components_->pcf_dependencies->network_controller_factory = std::move(network_controller_factory); return this; } PeerConfigurer* SetMediaTransportFactory( std::unique_ptr media_transport_factory) override { components_->pcf_dependencies->media_transport_factory = std::move(media_transport_factory); return this; } PeerConfigurer* SetVideoEncoderFactory( std::unique_ptr video_encoder_factory) override { components_->pcf_dependencies->video_encoder_factory = std::move(video_encoder_factory); return this; } PeerConfigurer* SetVideoDecoderFactory( std::unique_ptr video_decoder_factory) override { components_->pcf_dependencies->video_decoder_factory = std::move(video_decoder_factory); return this; } PeerConfigurer* SetAsyncResolverFactory( std::unique_ptr async_resolver_factory) override { components_->pc_dependencies->async_resolver_factory = std::move(async_resolver_factory); return this; } PeerConfigurer* SetRTCCertificateGenerator( std::unique_ptr cert_generator) override { components_->pc_dependencies->cert_generator = std::move(cert_generator); return this; } PeerConfigurer* SetSSLCertificateVerifier( std::unique_ptr tls_cert_verifier) override { components_->pc_dependencies->tls_cert_verifier = std::move(tls_cert_verifier); return this; } PeerConfigurer* AddVideoConfig( PeerConnectionE2EQualityTestFixture::VideoConfig config) override { params_->video_configs.push_back(std::move(config)); video_sources_.push_back(nullptr); return this; } PeerConfigurer* AddVideoConfig( PeerConnectionE2EQualityTestFixture::VideoConfig config, std::unique_ptr> source) override { params_->video_configs.push_back(std::move(config)); video_sources_.push_back(std::move(source)); return this; } PeerConfigurer* SetAudioConfig( PeerConnectionE2EQualityTestFixture::AudioConfig config) override { params_->audio_config = std::move(config); return this; } PeerConfigurer* SetRtcEventLogPath(std::string path) override { params_->rtc_event_log_path = std::move(path); return this; } PeerConfigurer* SetAecDumpPath(std::string path) override { params_->aec_dump_path = std::move(path); return this; } PeerConfigurer* SetRTCConfiguration( PeerConnectionInterface::RTCConfiguration configuration) override { params_->rtc_configuration = std::move(configuration); return this; } PeerConfigurer* SetBitrateParameters( PeerConnectionInterface::BitrateParameters bitrate_params) override { params_->bitrate_params = bitrate_params; return this; } protected: friend class PeerConnectionE2EQualityTest; std::unique_ptr ReleaseComponents() { return std::move(components_); } std::unique_ptr ReleaseParams() { return std::move(params_); } std::vector>> ReleaseVideoSources() { return std::move(video_sources_); } private: std::unique_ptr components_; std::unique_ptr params_; std::vector>> video_sources_; }; 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: using VideoGeneratorType = PeerConnectionE2EQualityTestFixture::VideoGeneratorType; using RunParams = PeerConnectionE2EQualityTestFixture::RunParams; using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig; using VideoSimulcastConfig = PeerConnectionE2EQualityTestFixture::VideoSimulcastConfig; using PeerConfigurer = PeerConnectionE2EQualityTestFixture::PeerConfigurer; using QualityMetricsReporter = PeerConnectionE2EQualityTestFixture::QualityMetricsReporter; PeerConnectionE2EQualityTest( std::string test_case_name, std::unique_ptr audio_quality_analyzer, std::unique_ptr video_quality_analyzer); ~PeerConnectionE2EQualityTest() override = default; void ExecuteAt(TimeDelta target_time_since_start, std::function func) override; void ExecuteEvery(TimeDelta initial_delay_since_start, TimeDelta interval, std::function func) override; void AddQualityMetricsReporter(std::unique_ptr quality_metrics_reporter) override; void AddPeer(rtc::Thread* network_thread, rtc::NetworkManager* network_manager, rtc::FunctionView configurer) override; void Run(RunParams run_params) override; TimeDelta GetRealTestDuration() const override { rtc::CritScope crit(&lock_); RTC_CHECK_NE(real_test_duration_, TimeDelta::Zero()); return real_test_duration_; } private: struct ScheduledActivity { ScheduledActivity(TimeDelta initial_delay_since_start, absl::optional interval, std::function func); TimeDelta initial_delay_since_start; absl::optional interval; std::function func; }; void ExecuteTask(TimeDelta initial_delay_since_start, absl::optional interval, std::function func); void PostTask(ScheduledActivity activity) RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); // Set missing params to default values if it is required: // * Generate video stream labels if some of them missed // * Generate audio stream labels if some of them missed // * Set video source generation mode if it is not specified void SetDefaultValuesForMissingParams( std::vector params, std::vector< std::vector>>*> video_sources); // Validate peer's parameters, also ensure uniqueness of all video stream // labels. void ValidateParams( const RunParams& run_params, std::vector params, std::vector< std::vector>>*> video_sources); // For some functionality some field trials have to be enabled, so we will // enable them here. void SetupRequiredFieldTrials(const RunParams& run_params); void OnTrackCallback(rtc::scoped_refptr transceiver, std::vector remote_video_configs); // 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> source, 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); void ExchangeIceCandidates(SignalingInterceptor* signaling_interceptor); void StartVideo( const std::vector>& sources); void TearDownCall(); test::VideoFrameWriter* MaybeCreateVideoWriter( absl::optional file_name, const VideoConfig& config); Timestamp Now() const; Clock* const clock_; const std::unique_ptr task_queue_factory_; std::string test_case_name_; std::unique_ptr video_quality_analyzer_injection_helper_; std::unique_ptr encoded_image_id_controller_; std::unique_ptr audio_quality_analyzer_; std::vector> peer_configurations_; std::unique_ptr override_field_trials_ = nullptr; std::unique_ptr alice_; std::unique_ptr bob_; std::vector> quality_metrics_reporters_; std::vector> alice_video_sources_; std::vector> bob_video_sources_; std::vector> video_writers_; std::vector>> output_video_sinks_; AnalyzerHelper analyzer_helper_; rtc::CriticalSection lock_; // Time when test call was started. Minus infinity means that call wasn't // started yet. Timestamp start_time_ RTC_GUARDED_BY(lock_) = Timestamp::MinusInfinity(); TimeDelta real_test_duration_ RTC_GUARDED_BY(lock_) = TimeDelta::Zero(); // Queue of activities that were added before test call was started. // Activities from this queue will be posted on the |task_queue_| after test // call will be set up and then this queue will be unused. std::queue scheduled_activities_ RTC_GUARDED_BY(lock_); // List of task handles for activities, that are posted on |task_queue_| as // repeated during the call. std::vector repeating_task_handles_ RTC_GUARDED_BY(lock_); RepeatingTaskHandle stats_polling_task_ RTC_GUARDED_BY(&task_queue_); // Task queue, that is used for running activities during test call. // This task queue will be created before call set up and will be destroyed // immediately before call tear down. std::unique_ptr task_queue_; }; } // namespace webrtc_pc_e2e } // namespace webrtc #endif // TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_H_