Add simulated time support for PC level test.

Bug: webrtc:11743
Change-Id: If69ab07618a30ec1a66dd5f36b3198486bee55fa
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/178608
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Andrey Logvin <landrey@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Commit-Queue: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31639}
This commit is contained in:
Artem Titov 2020-07-06 10:57:28 +02:00 committed by Commit Bot
parent a166a353fb
commit 0ef4a2488a
13 changed files with 217 additions and 116 deletions

View File

@ -22,12 +22,12 @@ namespace webrtc_pc_e2e {
std::unique_ptr<PeerConnectionE2EQualityTestFixture>
CreatePeerConnectionE2EQualityTestFixture(
std::string test_case_name,
TimeController& /*time_controller*/,
TimeController& time_controller,
std::unique_ptr<AudioQualityAnalyzerInterface> audio_quality_analyzer,
std::unique_ptr<VideoQualityAnalyzerInterface> video_quality_analyzer) {
return std::make_unique<PeerConnectionE2EQualityTest>(
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

View File

@ -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<rtc::Thread> CreateThread(
const std::string& name,
std::unique_ptr<rtc::SocketServer> socket_server = nullptr) = 0;

View File

@ -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",

View File

@ -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);

View File

@ -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<uint16_t> next_frame_id_{0};

View File

@ -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<std::string>{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<std::string>{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<std::string>{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<std::string>{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<std::string>{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<std::string>{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<std::string>{kAlice, kBob, kCharlie},
kAnalyzerMaxThreadsCount);

View File

@ -74,7 +74,8 @@ class PeerConnectionE2EQualityTestSmokeTest : public ::testing::Test {
// Create analyzers.
std::unique_ptr<VideoQualityAnalyzerInterface> video_quality_analyzer =
std::make_unique<DefaultVideoQualityAnalyzer>();
std::make_unique<DefaultVideoQualityAnalyzer>(
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 =

View File

@ -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<AudioQualityAnalyzerInterface> audio_quality_analyzer,
std::unique_ptr<VideoQualityAnalyzerInterface> 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<TestActivitiesExecutor>(clock_)) {
executor_(std::make_unique<TestActivitiesExecutor>(
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<DefaultVideoQualityAnalyzer>();
video_quality_analyzer = std::make_unique<DefaultVideoQualityAnalyzer>(
time_controller_.GetClock());
}
encoded_image_id_controller_ =
std::make_unique<SingleProcessEncodedImageDataInjector>();
@ -189,15 +193,16 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
<< "; audio="
<< bob_configurer->params()->audio_config.has_value();
const std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
signaling_thread->SetName(kSignalThreadName, nullptr);
signaling_thread->Start();
const std::unique_ptr<rtc::Thread> signaling_thread =
time_controller_.CreateThread(kSignalThreadName);
media_helper_ = std::make_unique<MediaHelper>(
video_quality_analyzer_injection_helper_.get(),
task_queue_factory_.get());
// Create a |task_queue_|.
task_queue_ = std::make_unique<TaskQueueForTest>("pc_e2e_quality_test");
task_queue_ = std::make_unique<webrtc::TaskQueueForTest>(
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<FixturePeerConnectionObserver>(
@ -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<VideoQualityMetricsReporter>(clock_));
std::make_unique<VideoQualityMetricsReporter>(
time_controller_.GetClock()));
quality_metrics_reporters_.push_back(
std::make_unique<CrossMediaMetricsReporter>());
@ -310,15 +316,29 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
RTC_FROM_HERE,
rtc::Bind(&PeerConnectionE2EQualityTest::SetupCallOnSignalingThread, this,
run_params));
std::unique_ptr<SignalingInterceptor> signaling_interceptor =
CreateSignalingInterceptor(run_params);
// Connect peers.
signaling_thread->Invoke<void>(
RTC_FROM_HERE,
rtc::Bind(&PeerConnectionE2EQualityTest::ExchangeOfferAnswer, this,
signaling_interceptor.get()));
WaitUntilIceCandidatesGathered(signaling_thread.get());
signaling_thread->Invoke<void>(
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<SignalingInterceptor>
PeerConnectionE2EQualityTest::CreateSignalingInterceptor(
const RunParams& run_params) {
std::map<std::string, int> 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<SignalingInterceptor>(patching_params);
}
ExchangeIceCandidates(&signaling_interceptor);
void PeerConnectionE2EQualityTest::WaitUntilIceCandidatesGathered(
rtc::Thread* signaling_thread) {
ASSERT_TRUE(time_controller_.Wait(
[&]() {
return signaling_thread->Invoke<bool>(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<bool>(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

View File

@ -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<AudioQualityAnalyzerInterface> audio_quality_analyzer,
std::unique_ptr<VideoQualityAnalyzerInterface> 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<SignalingInterceptor> 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<TaskQueueFactory> task_queue_factory_;
std::string test_case_name_;
std::unique_ptr<VideoQualityAnalyzerInjectionHelper>

View File

@ -43,10 +43,12 @@ TestPeer::TestPeer(
std::unique_ptr<MockPeerConnectionObserver> observer,
std::unique_ptr<Params> params,
std::vector<PeerConfigurerImpl::VideoSource> video_sources,
rtc::scoped_refptr<AudioProcessing> audio_processing)
: PeerConnectionWrapper::PeerConnectionWrapper(std::move(pc_factory),
std::move(pc),
std::move(observer)),
rtc::scoped_refptr<AudioProcessing> audio_processing,
std::unique_ptr<rtc::Thread> worker_thread)
: worker_thread_(std::move(worker_thread)),
wrapper_(std::make_unique<PeerConnectionWrapper>(std::move(pc_factory),
std::move(pc),
std::move(observer))),
params_(std::move(params)),
video_sources_(std::move(video_sources)),
audio_processing_(audio_processing) {}

View File

@ -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<SessionDescriptionInterface> CreateOffer() {
return wrapper_->CreateOffer();
}
std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
return wrapper_->CreateAnswer();
}
bool SetLocalDescription(std::unique_ptr<SessionDescriptionInterface> desc,
std::string* error_out = nullptr) {
return wrapper_->SetLocalDescription(std::move(desc), error_out);
}
bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,
std::string* error_out = nullptr) {
return wrapper_->SetRemoteDescription(std::move(desc), error_out);
}
rtc::scoped_refptr<RtpTransceiverInterface> AddTransceiver(
cricket::MediaType media_type,
const RtpTransceiverInit& init) {
return wrapper_->AddTransceiver(media_type, init);
}
rtc::scoped_refptr<RtpSenderInterface> AddTrack(
rtc::scoped_refptr<MediaStreamTrackInterface> track,
const std::vector<std::string>& stream_ids = {}) {
return wrapper_->AddTrack(track, stream_ids);
}
rtc::scoped_refptr<DataChannelInterface> 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<const RTCStatsReport> GetStats() {
return wrapper_->GetStats();
}
void DetachAecDump() {
if (audio_processing_) {
audio_processing_->DetachAecDump();
@ -52,9 +103,13 @@ class TestPeer final : public PeerConnectionWrapper {
std::unique_ptr<MockPeerConnectionObserver> observer,
std::unique_ptr<Params> params,
std::vector<PeerConfigurerImpl::VideoSource> video_sources,
rtc::scoped_refptr<AudioProcessing> audio_processing);
rtc::scoped_refptr<AudioProcessing> audio_processing,
std::unique_ptr<rtc::Thread> worker_thread);
private:
// Keeps ownership of worker thread. It has to be destroyed after |wrapper_|.
std::unique_ptr<rtc::Thread> worker_thread_;
std::unique_ptr<PeerConnectionWrapper> wrapper_;
std::unique_ptr<Params> params_;
std::vector<PeerConfigurerImpl::VideoSource> video_sources_;
rtc::scoped_refptr<AudioProcessing> audio_processing_;

View File

@ -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<PeerConnectionFactoryComponents> pcf_dependencies,
std::unique_ptr<cricket::MediaEngineInterface> 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> RemotePeerAudioConfig::Create(
std::unique_ptr<TestPeer> TestPeerFactory::CreateTestPeer(
std::unique_ptr<PeerConfigurerImpl> configurer,
std::unique_ptr<MockPeerConnectionObserver> observer,
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
rtc::Thread* signaling_thread,
absl::optional<RemotePeerAudioConfig> remote_audio_config,
double bitrate_multiplier,
absl::optional<PeerConnectionE2EQualityTestFixture::EchoEmulationConfig>
echo_emulation_config,
rtc::TaskQueue* task_queue) {
echo_emulation_config) {
std::unique_ptr<InjectableComponents> components =
configurer->ReleaseComponents();
std::unique_ptr<Params> params = configurer->ReleaseParams();
@ -297,7 +300,7 @@ std::unique_ptr<TestPeer> 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<TestPeer> 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<AudioDeviceModule> audio_device_module =
CreateAudioDeviceModule(
@ -314,16 +317,19 @@ std::unique_ptr<TestPeer> 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<cricket::MediaEngineInterface> media_engine =
CreateMediaEngine(components->pcf_dependencies.get(), audio_device_module,
audio_processing);
std::unique_ptr<rtc::Thread> 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<PeerConnectionFactoryInterface> peer_connection_factory =
CreateModularPeerConnectionFactory(std::move(pcf_deps));
@ -337,20 +343,8 @@ std::unique_ptr<TestPeer> 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<TestPeer> TestPeerFactory::CreateTestPeer(
std::unique_ptr<PeerConfigurerImpl> configurer,
std::unique_ptr<MockPeerConnectionObserver> observer,
absl::optional<RemotePeerAudioConfig> remote_audio_config,
double bitrate_multiplier,
absl::optional<PeerConnectionE2EQualityTestFixture::EchoEmulationConfig>
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

View File

@ -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<TestPeer> CreateTestPeer(
std::unique_ptr<PeerConfigurerImpl> configurer,
std::unique_ptr<MockPeerConnectionObserver> observer,
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
rtc::Thread* signaling_thread,
absl::optional<RemotePeerAudioConfig> remote_audio_config,
double bitrate_multiplier,
absl::optional<PeerConnectionE2EQualityTestFixture::EchoEmulationConfig>
echo_emulation_config,
rtc::TaskQueue* task_queue);
std::unique_ptr<TestPeer> CreateTestPeer(
std::unique_ptr<PeerConfigurerImpl> configurer,
std::unique_ptr<MockPeerConnectionObserver> observer,
@ -97,6 +76,7 @@ class TestPeerFactory {
private:
rtc::Thread* signaling_thread_;
TimeController& time_controller_;
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper_;
rtc::TaskQueue* task_queue_;
};