diff --git a/api/test/create_peerconnection_quality_test_fixture.cc b/api/test/create_peerconnection_quality_test_fixture.cc index 8c9f97c715..2d9d0821fc 100644 --- a/api/test/create_peerconnection_quality_test_fixture.cc +++ b/api/test/create_peerconnection_quality_test_fixture.cc @@ -22,12 +22,12 @@ namespace webrtc_pc_e2e { std::unique_ptr CreatePeerConnectionE2EQualityTestFixture( std::string test_case_name, - TimeController& /*time_controller*/, + TimeController& time_controller, std::unique_ptr audio_quality_analyzer, std::unique_ptr video_quality_analyzer) { return std::make_unique( - std::move(test_case_name), std::move(audio_quality_analyzer), - std::move(video_quality_analyzer)); + std::move(test_case_name), time_controller, + std::move(audio_quality_analyzer), std::move(video_quality_analyzer)); } } // namespace webrtc_pc_e2e diff --git a/api/test/time_controller.h b/api/test/time_controller.h index 4d7f9e6c39..419bd203a3 100644 --- a/api/test/time_controller.h +++ b/api/test/time_controller.h @@ -46,6 +46,7 @@ class TimeController { const char* thread_name) = 0; // Creates an rtc::Thread instance. If |socket_server| is nullptr, a default // noop socket server is created. + // Returned thread is not null and started. virtual std::unique_ptr CreateThread( const std::string& name, std::unique_ptr socket_server = nullptr) = 0; diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn index dd5e8d7665..8ce9ca1ad5 100644 --- a/test/pc/e2e/BUILD.gn +++ b/test/pc/e2e/BUILD.gn @@ -260,6 +260,7 @@ if (!build_with_chromium) { ":test_peer", ":video_quality_analyzer_injection_helper", "../..:copy_to_file_audio_capturer", + "../../../api:create_time_controller", "../../../api:peer_connection_quality_test_fixture_api", "../../../api:time_controller", "../../../api/rtc_event_log:rtc_event_log_factory", @@ -385,6 +386,7 @@ if (!build_with_chromium) { "../../../api:peer_connection_quality_test_fixture_api", "../../../api:rtc_event_log_output_file", "../../../api:scoped_refptr", + "../../../api:time_controller", "../../../api:video_quality_analyzer_api", "../../../api/rtc_event_log", "../../../api/task_queue", diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc index 851238f1e7..075abebee5 100644 --- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc +++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc @@ -120,13 +120,19 @@ bool operator==(const InternalStatsKey& a, const InternalStatsKey& b) { a.receiver == b.receiver; } +DefaultVideoQualityAnalyzer::DefaultVideoQualityAnalyzer( + webrtc::Clock* clock, + DefaultVideoQualityAnalyzerOptions options) + : options_(options), clock_(clock) {} DefaultVideoQualityAnalyzer::DefaultVideoQualityAnalyzer( bool heavy_metrics_computation_enabled, size_t max_frames_in_flight_per_stream_count) - : heavy_metrics_computation_enabled_(heavy_metrics_computation_enabled), - max_frames_in_flight_per_stream_count_( - max_frames_in_flight_per_stream_count), - clock_(Clock::GetRealTimeClock()) {} + : clock_(Clock::GetRealTimeClock()) { + options_.heavy_metrics_computation_enabled = + heavy_metrics_computation_enabled; + options_.max_frames_in_flight_per_stream_count = + max_frames_in_flight_per_stream_count; +} DefaultVideoQualityAnalyzer::~DefaultVideoQualityAnalyzer() { Stop(); } @@ -256,7 +262,8 @@ uint16_t DefaultVideoQualityAnalyzer::OnFrameCaptured( // If state has too many frames that are in flight => remove the oldest // queued frame in order to avoid to use too much memory. - if (state->GetAliveFramesCount() > max_frames_in_flight_per_stream_count_) { + if (state->GetAliveFramesCount() > + options_.max_frames_in_flight_per_stream_count) { uint16_t frame_id_to_remove = state->MarkNextAliveFrameAsDead(); auto it = captured_frames_in_flight_.find(frame_id_to_remove); RTC_CHECK(it != captured_frames_in_flight_.end()) @@ -677,7 +684,7 @@ void DefaultVideoQualityAnalyzer::ProcessComparison( // Perform expensive psnr and ssim calculations while not holding lock. double psnr = -1.0; double ssim = -1.0; - if (heavy_metrics_computation_enabled_ && comparison.captured && + if (options_.heavy_metrics_computation_enabled && comparison.captured && !comparison.dropped) { psnr = I420PSNR(&*comparison.captured, &*comparison.rendered); ssim = I420SSIM(&*comparison.captured, &*comparison.rendered); diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h index 95049b1054..75449412f8 100644 --- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h +++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h @@ -166,8 +166,24 @@ struct InternalStatsKey { bool operator<(const InternalStatsKey& a, const InternalStatsKey& b); bool operator==(const InternalStatsKey& a, const InternalStatsKey& b); +struct DefaultVideoQualityAnalyzerOptions { + // Tells DefaultVideoQualityAnalyzer if heavy metrics like PSNR and SSIM have + // to be computed or not. + bool heavy_metrics_computation_enabled = true; + // Amount of frames that are queued in the DefaultVideoQualityAnalyzer from + // the point they were captured to the point they were rendered on all + // receivers per stream. + size_t max_frames_in_flight_per_stream_count = + kDefaultMaxFramesInFlightPerStream; +}; + class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { public: + explicit DefaultVideoQualityAnalyzer( + webrtc::Clock* clock, + DefaultVideoQualityAnalyzerOptions options = + DefaultVideoQualityAnalyzerOptions()); + // Keep for backward compatibility during migration. Will be removed soon. explicit DefaultVideoQualityAnalyzer( bool heavy_metrics_computation_enabled = true, size_t max_frames_in_flight_per_stream_count = @@ -483,8 +499,8 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { void StopExcludingCpuThreadTime(); double GetCpuUsagePercent(); - const bool heavy_metrics_computation_enabled_; - const size_t max_frames_in_flight_per_stream_count_; + // TODO(titovartem) restore const when old constructor will be removed. + DefaultVideoQualityAnalyzerOptions options_; webrtc::Clock* const clock_; std::atomic next_frame_id_{0}; diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc index 55cc438b9d..9c9a19fc91 100644 --- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc +++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc @@ -37,6 +37,13 @@ constexpr char kStreamLabel[] = "video-stream"; constexpr char kSenderPeerName[] = "alice"; constexpr char kReceiverPeerName[] = "bob"; +DefaultVideoQualityAnalyzerOptions AnalyzerOptionsForTest() { + DefaultVideoQualityAnalyzerOptions options; + options.heavy_metrics_computation_enabled = false; + options.max_frames_in_flight_per_stream_count = kMaxFramesInFlightPerStream; + return options; +} + VideoFrame NextFrame(test::FrameGeneratorInterface* frame_generator, int64_t timestamp_us) { test::FrameGeneratorInterface::VideoFrameData frame_data = @@ -94,8 +101,8 @@ TEST(DefaultVideoQualityAnalyzerTest, /*type=*/absl::nullopt, /*num_squares=*/absl::nullopt); - DefaultVideoQualityAnalyzer analyzer( - /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + AnalyzerOptionsForTest()); analyzer.Start("test_case", std::vector{kSenderPeerName, kReceiverPeerName}, kAnalyzerMaxThreadsCount); @@ -145,8 +152,8 @@ TEST(DefaultVideoQualityAnalyzerTest, /*type=*/absl::nullopt, /*num_squares=*/absl::nullopt); - DefaultVideoQualityAnalyzer analyzer( - /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + AnalyzerOptionsForTest()); analyzer.Start("test_case", std::vector{kSenderPeerName, kReceiverPeerName}, kAnalyzerMaxThreadsCount); @@ -226,8 +233,8 @@ TEST(DefaultVideoQualityAnalyzerTest, /*type=*/absl::nullopt, /*num_squares=*/absl::nullopt); - DefaultVideoQualityAnalyzer analyzer( - /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + AnalyzerOptionsForTest()); analyzer.Start("test_case", std::vector{kSenderPeerName, kReceiverPeerName}, kAnalyzerMaxThreadsCount); @@ -276,8 +283,8 @@ TEST(DefaultVideoQualityAnalyzerTest, NormalScenario) { /*type=*/absl::nullopt, /*num_squares=*/absl::nullopt); - DefaultVideoQualityAnalyzer analyzer( - /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + AnalyzerOptionsForTest()); analyzer.Start("test_case", std::vector{kSenderPeerName, kReceiverPeerName}, kAnalyzerMaxThreadsCount); @@ -334,8 +341,8 @@ TEST(DefaultVideoQualityAnalyzerTest, OneFrameReceivedTwice) { /*type=*/absl::nullopt, /*num_squares=*/absl::nullopt); - DefaultVideoQualityAnalyzer analyzer( - /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + AnalyzerOptionsForTest()); analyzer.Start("test_case", std::vector{kSenderPeerName, kReceiverPeerName}, kAnalyzerMaxThreadsCount); @@ -390,8 +397,8 @@ TEST(DefaultVideoQualityAnalyzerTest, NormalScenario2Receivers) { constexpr char kBob[] = "bob"; constexpr char kCharlie[] = "charlie"; - DefaultVideoQualityAnalyzer analyzer( - /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + AnalyzerOptionsForTest()); analyzer.Start("test_case", std::vector{kAlice, kBob, kCharlie}, kAnalyzerMaxThreadsCount); @@ -508,8 +515,8 @@ TEST(DefaultVideoQualityAnalyzerTest, OneFrameReceivedTwiceWith2Receivers) { constexpr char kBob[] = "bob"; constexpr char kCharlie[] = "charlie"; - DefaultVideoQualityAnalyzer analyzer( - /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + AnalyzerOptionsForTest()); analyzer.Start("test_case", std::vector{kAlice, kBob, kCharlie}, kAnalyzerMaxThreadsCount); diff --git a/test/pc/e2e/peer_connection_e2e_smoke_test.cc b/test/pc/e2e/peer_connection_e2e_smoke_test.cc index a8bddda623..b09b093c25 100644 --- a/test/pc/e2e/peer_connection_e2e_smoke_test.cc +++ b/test/pc/e2e/peer_connection_e2e_smoke_test.cc @@ -74,7 +74,8 @@ class PeerConnectionE2EQualityTestSmokeTest : public ::testing::Test { // Create analyzers. std::unique_ptr video_quality_analyzer = - std::make_unique(); + std::make_unique( + network_emulation_manager->time_controller()->GetClock()); // This is only done for the sake of smoke testing. In general there should // be no need to explicitly pull data from analyzers after the run. auto* video_analyzer_ptr = diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc index aa7e855dda..60eaa1e8b4 100644 --- a/test/pc/e2e/peer_connection_quality_test.cc +++ b/test/pc/e2e/peer_connection_quality_test.cc @@ -22,6 +22,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/time_controller.h" #include "api/test/video_quality_analyzer_interface.h" #include "pc/sdp_utils.h" #include "pc/test/mock_peer_connection_observers.h" @@ -46,7 +47,7 @@ namespace { using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig; using VideoCodecConfig = PeerConnectionE2EQualityTestFixture::VideoCodecConfig; -constexpr int kDefaultTimeoutMs = 10000; +constexpr TimeDelta kDefaultTimeout = TimeDelta::Seconds(10); constexpr char kSignalThreadName[] = "signaling_thread"; // 1 signaling, 2 network, 2 worker and 2 extra for codecs etc. constexpr int kPeerConnectionUsedThreads = 7; @@ -59,7 +60,7 @@ constexpr TimeDelta kStatsUpdateInterval = TimeDelta::Seconds(1); constexpr TimeDelta kAliveMessageLogInterval = TimeDelta::Seconds(30); -constexpr int kQuickTestModeRunDurationMs = 100; +constexpr TimeDelta kQuickTestModeRunDuration = TimeDelta::Millis(100); // Field trials to enable Flex FEC advertising and receiving. constexpr char kFlexFecEnabledFieldTrials[] = @@ -104,17 +105,20 @@ class FixturePeerConnectionObserver : public MockPeerConnectionObserver { PeerConnectionE2EQualityTest::PeerConnectionE2EQualityTest( std::string test_case_name, + TimeController& time_controller, std::unique_ptr audio_quality_analyzer, std::unique_ptr video_quality_analyzer) - : clock_(Clock::GetRealTimeClock()), + : time_controller_(time_controller), task_queue_factory_(CreateDefaultTaskQueueFactory()), test_case_name_(std::move(test_case_name)), - executor_(std::make_unique(clock_)) { + executor_(std::make_unique( + time_controller_.GetClock())) { // Create default video quality analyzer. We will always create an analyzer, // even if there are no video streams, because it will be installed into video // encoder/decoder factories. if (video_quality_analyzer == nullptr) { - video_quality_analyzer = std::make_unique(); + video_quality_analyzer = std::make_unique( + time_controller_.GetClock()); } encoded_image_id_controller_ = std::make_unique(); @@ -189,15 +193,16 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { << "; audio=" << bob_configurer->params()->audio_config.has_value(); - const std::unique_ptr signaling_thread = rtc::Thread::Create(); - signaling_thread->SetName(kSignalThreadName, nullptr); - signaling_thread->Start(); + const std::unique_ptr signaling_thread = + time_controller_.CreateThread(kSignalThreadName); 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"); + task_queue_ = std::make_unique( + time_controller_.GetTaskQueueFactory()->CreateTaskQueue( + "pc_e2e_quality_test", webrtc::TaskQueueFactory::Priority::NORMAL)); // Create call participants: Alice and Bob. // Audio streams are intercepted in AudioDeviceModule, so if it is required to @@ -217,8 +222,8 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { std::string bob_name = bob_configurer->params()->name.value(); TestPeerFactory test_peer_factory( - signaling_thread.get(), video_quality_analyzer_injection_helper_.get(), - task_queue_.get()); + signaling_thread.get(), time_controller_, + video_quality_analyzer_injection_helper_.get(), task_queue_.get()); alice_ = test_peer_factory.CreateTestPeer( std::move(alice_configurer), std::make_unique( @@ -252,7 +257,8 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { std::min(video_analyzer_threads, kMaxVideoAnalyzerThreads); RTC_LOG(INFO) << "video_analyzer_threads=" << video_analyzer_threads; quality_metrics_reporters_.push_back( - std::make_unique(clock_)); + std::make_unique( + time_controller_.GetClock())); quality_metrics_reporters_.push_back( std::make_unique()); @@ -310,15 +316,29 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { RTC_FROM_HERE, rtc::Bind(&PeerConnectionE2EQualityTest::SetupCallOnSignalingThread, this, run_params)); + std::unique_ptr signaling_interceptor = + CreateSignalingInterceptor(run_params); + // Connect peers. + signaling_thread->Invoke( + RTC_FROM_HERE, + rtc::Bind(&PeerConnectionE2EQualityTest::ExchangeOfferAnswer, this, + signaling_interceptor.get())); + WaitUntilIceCandidatesGathered(signaling_thread.get()); + + signaling_thread->Invoke( + RTC_FROM_HERE, + rtc::Bind(&PeerConnectionE2EQualityTest::ExchangeIceCandidates, this, + signaling_interceptor.get())); + WaitUntilPeersAreConnected(signaling_thread.get()); + executor_->Start(task_queue_.get()); Timestamp start_time = Now(); - rtc::Event done; bool is_quick_test_enabled = field_trial::IsEnabled("WebRTC-QuickPerfTest"); if (is_quick_test_enabled) { - done.Wait(kQuickTestModeRunDurationMs); + time_controller_.AdvanceTime(kQuickTestModeRunDuration); } else { - done.Wait(run_params.run_duration.ms()); + time_controller_.AdvanceTime(run_params.run_duration); } RTC_LOG(INFO) << "Test is done, initiating disconnect sequence."; @@ -483,8 +503,6 @@ void PeerConnectionE2EQualityTest::SetupCallOnSignalingThread( SetPeerCodecPreferences(alice_.get(), run_params); SetPeerCodecPreferences(bob_.get(), run_params); - - SetupCall(run_params); } void PeerConnectionE2EQualityTest::TearDownCallOnSignalingThread() { @@ -527,7 +545,9 @@ void PeerConnectionE2EQualityTest::SetPeerCodecPreferences( } } -void PeerConnectionE2EQualityTest::SetupCall(const RunParams& run_params) { +std::unique_ptr +PeerConnectionE2EQualityTest::CreateSignalingInterceptor( + const RunParams& run_params) { std::map stream_label_to_simulcast_streams_count; // We add only Alice here, because simulcast/svc is supported only from the // first peer. @@ -541,21 +561,32 @@ void PeerConnectionE2EQualityTest::SetupCall(const RunParams& run_params) { PatchingParams patching_params(run_params.video_codecs, run_params.use_conference_mode, stream_label_to_simulcast_streams_count); - SignalingInterceptor signaling_interceptor(patching_params); - // Connect peers. - ExchangeOfferAnswer(&signaling_interceptor); - // Do the SDP negotiation, and also exchange ice candidates. - ASSERT_EQ_WAIT(alice_->signaling_state(), PeerConnectionInterface::kStable, - kDefaultTimeoutMs); - ASSERT_TRUE_WAIT(alice_->IsIceGatheringDone(), kDefaultTimeoutMs); - ASSERT_TRUE_WAIT(bob_->IsIceGatheringDone(), kDefaultTimeoutMs); + return std::make_unique(patching_params); +} - ExchangeIceCandidates(&signaling_interceptor); +void PeerConnectionE2EQualityTest::WaitUntilIceCandidatesGathered( + rtc::Thread* signaling_thread) { + ASSERT_TRUE(time_controller_.Wait( + [&]() { + return signaling_thread->Invoke(RTC_FROM_HERE, [&]() { + return alice_->IsIceGatheringDone() && bob_->IsIceGatheringDone(); + }); + }, + 2 * kDefaultTimeout)); +} + +void PeerConnectionE2EQualityTest::WaitUntilPeersAreConnected( + rtc::Thread* signaling_thread) { // This means that ICE and DTLS are connected. - WAIT(bob_->IsIceConnected(), kDefaultTimeoutMs); - bob_connected_ = bob_->IsIceConnected(); - WAIT(alice_->IsIceConnected(), kDefaultTimeoutMs); + time_controller_.Wait( + [&]() { + return signaling_thread->Invoke(RTC_FROM_HERE, [&]() { + return alice_->IsIceConnected() && bob_->IsIceConnected(); + }); + }, + 2 * kDefaultTimeout); alice_connected_ = alice_->IsIceConnected(); + bob_connected_ = bob_->IsIceConnected(); } void PeerConnectionE2EQualityTest::ExchangeOfferAnswer( @@ -663,7 +694,7 @@ void PeerConnectionE2EQualityTest::ReportGeneralTestResults() { } Timestamp PeerConnectionE2EQualityTest::Now() const { - return clock_->CurrentTime(); + return time_controller_.GetClock()->CurrentTime(); } } // namespace webrtc_pc_e2e diff --git a/test/pc/e2e/peer_connection_quality_test.h b/test/pc/e2e/peer_connection_quality_test.h index b302e5c51b..833384d61a 100644 --- a/test/pc/e2e/peer_connection_quality_test.h +++ b/test/pc/e2e/peer_connection_quality_test.h @@ -19,6 +19,7 @@ #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/test/time_controller.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "rtc_base/task_queue_for_test.h" @@ -52,6 +53,7 @@ class PeerConnectionE2EQualityTest PeerConnectionE2EQualityTest( std::string test_case_name, + TimeController& time_controller, std::unique_ptr audio_quality_analyzer, std::unique_ptr video_quality_analyzer); @@ -88,7 +90,10 @@ class PeerConnectionE2EQualityTest void SetupCallOnSignalingThread(const RunParams& run_params); void TearDownCallOnSignalingThread(); void SetPeerCodecPreferences(TestPeer* peer, const RunParams& run_params); - void SetupCall(const RunParams& run_params); + std::unique_ptr CreateSignalingInterceptor( + const RunParams& run_params); + void WaitUntilIceCandidatesGathered(rtc::Thread* signaling_thread); + void WaitUntilPeersAreConnected(rtc::Thread* signaling_thread); void ExchangeOfferAnswer(SignalingInterceptor* signaling_interceptor); void ExchangeIceCandidates(SignalingInterceptor* signaling_interceptor); void StartVideo( @@ -98,7 +103,7 @@ class PeerConnectionE2EQualityTest void ReportGeneralTestResults(); Timestamp Now() const; - Clock* const clock_; + TimeController& time_controller_; const std::unique_ptr task_queue_factory_; std::string test_case_name_; std::unique_ptr diff --git a/test/pc/e2e/test_peer.cc b/test/pc/e2e/test_peer.cc index 8c9c6d9c8f..65d3eb36b8 100644 --- a/test/pc/e2e/test_peer.cc +++ b/test/pc/e2e/test_peer.cc @@ -43,10 +43,12 @@ TestPeer::TestPeer( std::unique_ptr observer, std::unique_ptr params, std::vector video_sources, - rtc::scoped_refptr audio_processing) - : PeerConnectionWrapper::PeerConnectionWrapper(std::move(pc_factory), - std::move(pc), - std::move(observer)), + rtc::scoped_refptr audio_processing, + std::unique_ptr worker_thread) + : worker_thread_(std::move(worker_thread)), + wrapper_(std::make_unique(std::move(pc_factory), + std::move(pc), + std::move(observer))), params_(std::move(params)), video_sources_(std::move(video_sources)), audio_processing_(audio_processing) {} diff --git a/test/pc/e2e/test_peer.h b/test/pc/e2e/test_peer.h index c506127488..4310cbda1c 100644 --- a/test/pc/e2e/test_peer.h +++ b/test/pc/e2e/test_peer.h @@ -26,15 +26,66 @@ namespace webrtc { namespace webrtc_pc_e2e { // Describes a single participant in the call. -class TestPeer final : public PeerConnectionWrapper { +class TestPeer final { public: - using PeerConnectionWrapper::PeerConnectionWrapper; - Params* params() const { return params_.get(); } PeerConfigurerImpl::VideoSource ReleaseVideoSource(size_t i) { return std::move(video_sources_[i]); } + PeerConnectionFactoryInterface* pc_factory() { + return wrapper_->pc_factory(); + } + PeerConnectionInterface* pc() { return wrapper_->pc(); } + MockPeerConnectionObserver* observer() { return wrapper_->observer(); } + + std::unique_ptr CreateOffer() { + return wrapper_->CreateOffer(); + } + + std::unique_ptr CreateAnswer() { + return wrapper_->CreateAnswer(); + } + + bool SetLocalDescription(std::unique_ptr desc, + std::string* error_out = nullptr) { + return wrapper_->SetLocalDescription(std::move(desc), error_out); + } + + bool SetRemoteDescription(std::unique_ptr desc, + std::string* error_out = nullptr) { + return wrapper_->SetRemoteDescription(std::move(desc), error_out); + } + + rtc::scoped_refptr AddTransceiver( + cricket::MediaType media_type, + const RtpTransceiverInit& init) { + return wrapper_->AddTransceiver(media_type, init); + } + + rtc::scoped_refptr AddTrack( + rtc::scoped_refptr track, + const std::vector& stream_ids = {}) { + return wrapper_->AddTrack(track, stream_ids); + } + + rtc::scoped_refptr CreateDataChannel( + const std::string& label) { + return wrapper_->CreateDataChannel(label); + } + + PeerConnectionInterface::SignalingState signaling_state() { + return wrapper_->signaling_state(); + } + + bool IsIceGatheringDone() { return wrapper_->IsIceGatheringDone(); } + + bool IsIceConnected() { return wrapper_->IsIceConnected(); } + + rtc::scoped_refptr GetStats() { + return wrapper_->GetStats(); + } + void DetachAecDump() { if (audio_processing_) { audio_processing_->DetachAecDump(); @@ -52,9 +103,13 @@ class TestPeer final : public PeerConnectionWrapper { std::unique_ptr observer, std::unique_ptr params, std::vector video_sources, - rtc::scoped_refptr audio_processing); + rtc::scoped_refptr audio_processing, + std::unique_ptr worker_thread); private: + // Keeps ownership of worker thread. It has to be destroyed after |wrapper_|. + std::unique_ptr worker_thread_; + std::unique_ptr wrapper_; std::unique_ptr params_; std::vector video_sources_; rtc::scoped_refptr audio_processing_; diff --git a/test/pc/e2e/test_peer_factory.cc b/test/pc/e2e/test_peer_factory.cc index 134e44108f..634a37e95b 100644 --- a/test/pc/e2e/test_peer_factory.cc +++ b/test/pc/e2e/test_peer_factory.cc @@ -14,6 +14,8 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/test/create_time_controller.h" +#include "api/test/time_controller.h" #include "api/video_codecs/builtin_video_decoder_factory.h" #include "api/video_codecs/builtin_video_encoder_factory.h" #include "media/engine/webrtc_media_engine.h" @@ -43,17 +45,19 @@ constexpr int kDefaultSamplingFrequencyInHz = 48000; // and |pc_dependencies| if they are omitted. Also setup required // dependencies, that won't be specially provided by factory and will be just // transferred to peer connection creation code. -void SetMandatoryEntities(InjectableComponents* components) { +void SetMandatoryEntities(InjectableComponents* components, + TimeController& time_controller) { RTC_DCHECK(components->pcf_dependencies); RTC_DCHECK(components->pc_dependencies); // Setup required peer connection factory dependencies. if (components->pcf_dependencies->task_queue_factory == nullptr) { components->pcf_dependencies->task_queue_factory = - CreateDefaultTaskQueueFactory(); + time_controller.CreateTaskQueueFactory(); } if (components->pcf_dependencies->call_factory == nullptr) { - components->pcf_dependencies->call_factory = webrtc::CreateCallFactory(); + components->pcf_dependencies->call_factory = + CreateTimeControllerBasedCallFactory(&time_controller); } if (components->pcf_dependencies->event_log_factory == nullptr) { components->pcf_dependencies->event_log_factory = @@ -211,10 +215,12 @@ PeerConnectionFactoryDependencies CreatePCFDependencies( std::unique_ptr pcf_dependencies, std::unique_ptr media_engine, rtc::Thread* signaling_thread, + rtc::Thread* worker_thread, rtc::Thread* network_thread) { PeerConnectionFactoryDependencies pcf_deps; - pcf_deps.network_thread = network_thread; pcf_deps.signaling_thread = signaling_thread; + pcf_deps.worker_thread = worker_thread; + pcf_deps.network_thread = network_thread; pcf_deps.media_engine = std::move(media_engine); pcf_deps.call_factory = std::move(pcf_dependencies->call_factory); @@ -282,13 +288,10 @@ absl::optional RemotePeerAudioConfig::Create( std::unique_ptr TestPeerFactory::CreateTestPeer( std::unique_ptr configurer, std::unique_ptr observer, - VideoQualityAnalyzerInjectionHelper* video_analyzer_helper, - rtc::Thread* signaling_thread, absl::optional remote_audio_config, double bitrate_multiplier, absl::optional - echo_emulation_config, - rtc::TaskQueue* task_queue) { + echo_emulation_config) { std::unique_ptr components = configurer->ReleaseComponents(); std::unique_ptr params = configurer->ReleaseParams(); @@ -297,7 +300,7 @@ std::unique_ptr TestPeerFactory::CreateTestPeer( RTC_DCHECK(components); RTC_DCHECK(params); RTC_DCHECK_EQ(params->video_configs.size(), video_sources.size()); - SetMandatoryEntities(components.get()); + SetMandatoryEntities(components.get(), time_controller_); params->rtc_configuration.sdp_semantics = SdpSemantics::kUnifiedPlan; // Create peer connection factory. @@ -305,7 +308,7 @@ std::unique_ptr TestPeerFactory::CreateTestPeer( webrtc::AudioProcessingBuilder().Create(); if (params->aec_dump_path && audio_processing) { audio_processing->CreateAndAttachAecDump(*params->aec_dump_path, -1, - task_queue); + task_queue_); } rtc::scoped_refptr audio_device_module = CreateAudioDeviceModule( @@ -314,16 +317,19 @@ std::unique_ptr TestPeerFactory::CreateTestPeer( WrapVideoEncoderFactory( params->name.value(), bitrate_multiplier, CalculateRequiredSpatialIndexPerStream(params->video_configs), - components->pcf_dependencies.get(), video_analyzer_helper); + components->pcf_dependencies.get(), video_analyzer_helper_); WrapVideoDecoderFactory(params->name.value(), components->pcf_dependencies.get(), - video_analyzer_helper); + video_analyzer_helper_); std::unique_ptr media_engine = CreateMediaEngine(components->pcf_dependencies.get(), audio_device_module, audio_processing); + + std::unique_ptr worker_thread = + time_controller_.CreateThread("worker_thread"); PeerConnectionFactoryDependencies pcf_deps = CreatePCFDependencies( std::move(components->pcf_dependencies), std::move(media_engine), - signaling_thread, components->network_thread); + signaling_thread_, worker_thread.get(), components->network_thread); rtc::scoped_refptr peer_connection_factory = CreateModularPeerConnectionFactory(std::move(pcf_deps)); @@ -337,20 +343,8 @@ std::unique_ptr TestPeerFactory::CreateTestPeer( return absl::WrapUnique(new TestPeer( peer_connection_factory, peer_connection, std::move(observer), - std::move(params), std::move(video_sources), audio_processing)); -} - -std::unique_ptr TestPeerFactory::CreateTestPeer( - std::unique_ptr configurer, - std::unique_ptr observer, - absl::optional remote_audio_config, - double bitrate_multiplier, - absl::optional - echo_emulation_config) { - return CreateTestPeer(std::move(configurer), std::move(observer), - video_analyzer_helper_, signaling_thread_, - remote_audio_config, bitrate_multiplier, - echo_emulation_config, task_queue_); + std::move(params), std::move(video_sources), audio_processing, + std::move(worker_thread))); } } // namespace webrtc_pc_e2e diff --git a/test/pc/e2e/test_peer_factory.h b/test/pc/e2e/test_peer_factory.h index edbfe8b990..df33406270 100644 --- a/test/pc/e2e/test_peer_factory.h +++ b/test/pc/e2e/test_peer_factory.h @@ -58,15 +58,7 @@ class TestPeerFactory { VideoQualityAnalyzerInjectionHelper* video_analyzer_helper, rtc::TaskQueue* task_queue) : signaling_thread_(signaling_thread), - video_analyzer_helper_(video_analyzer_helper), - task_queue_(task_queue) {} - - // Same as previous. Created for keeping backward compatibility during - // migration. Will be removed soon. - TestPeerFactory(rtc::Thread* signaling_thread, - VideoQualityAnalyzerInjectionHelper* video_analyzer_helper, - rtc::TaskQueue* task_queue) - : signaling_thread_(signaling_thread), + time_controller_(time_controller), video_analyzer_helper_(video_analyzer_helper), task_queue_(task_queue) {} @@ -74,19 +66,6 @@ class TestPeerFactory { // PeerConnectionFactory and PeerConnection creation methods, // also will setup dependencies, that are required for media analyzers // injection. - // - // |signaling_thread| will be provided by test fixture implementation. - static std::unique_ptr CreateTestPeer( - std::unique_ptr configurer, - std::unique_ptr observer, - VideoQualityAnalyzerInjectionHelper* video_analyzer_helper, - rtc::Thread* signaling_thread, - absl::optional remote_audio_config, - double bitrate_multiplier, - absl::optional - echo_emulation_config, - rtc::TaskQueue* task_queue); - std::unique_ptr CreateTestPeer( std::unique_ptr configurer, std::unique_ptr observer, @@ -97,6 +76,7 @@ class TestPeerFactory { private: rtc::Thread* signaling_thread_; + TimeController& time_controller_; VideoQualityAnalyzerInjectionHelper* video_analyzer_helper_; rtc::TaskQueue* task_queue_; };