mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Add support for creation of AEC dump during the test with PC framework.
Also add conversational speech into PC smoke test (with resource files). Bug: webrtc:10138 Change-Id: I415a5565bc9146821476ffc60f57f47ed51f89c4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132323 Reviewed-by: Ivo Creusen <ivoc@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27592}
This commit is contained in:
parent
753741fe53
commit
70f80e5962
10 changed files with 284 additions and 196 deletions
|
@ -167,6 +167,9 @@ class PeerConnectionE2EQualityTestFixture {
|
||||||
// If is set, an RTCEventLog will be saved in that location and it will be
|
// If is set, an RTCEventLog will be saved in that location and it will be
|
||||||
// available for further analysis.
|
// available for further analysis.
|
||||||
virtual PeerConfigurer* SetRtcEventLogPath(std::string path) = 0;
|
virtual PeerConfigurer* SetRtcEventLogPath(std::string path) = 0;
|
||||||
|
// If is set, an AEC dump will be saved in that location and it will be
|
||||||
|
// available for further analysis.
|
||||||
|
virtual PeerConfigurer* SetAecDumpPath(std::string path) = 0;
|
||||||
virtual PeerConfigurer* SetRTCConfiguration(
|
virtual PeerConfigurer* SetRTCConfiguration(
|
||||||
PeerConnectionInterface::RTCConfiguration configuration) = 0;
|
PeerConnectionInterface::RTCConfiguration configuration) = 0;
|
||||||
};
|
};
|
||||||
|
|
1
resources/pc_quality_smoke_test_alice_source.wav.sha1
Normal file
1
resources/pc_quality_smoke_test_alice_source.wav.sha1
Normal file
|
@ -0,0 +1 @@
|
||||||
|
28738955a60b9559b58b232e4d2d9cb7a1dd9b2a
|
1
resources/pc_quality_smoke_test_bob_source.wav.sha1
Normal file
1
resources/pc_quality_smoke_test_bob_source.wav.sha1
Normal file
|
@ -0,0 +1 @@
|
||||||
|
b18e0d654b84e6150dc79140f40dac3f8e675e7d
|
|
@ -208,11 +208,13 @@ if (rtc_include_tests) {
|
||||||
"../../../modules/audio_device:audio_device_api",
|
"../../../modules/audio_device:audio_device_api",
|
||||||
"../../../modules/audio_device:audio_device_impl",
|
"../../../modules/audio_device:audio_device_impl",
|
||||||
"../../../modules/audio_processing:api",
|
"../../../modules/audio_processing:api",
|
||||||
|
"../../../modules/audio_processing/aec_dump:aec_dump",
|
||||||
"../../../p2p:rtc_p2p",
|
"../../../p2p:rtc_p2p",
|
||||||
"../../../pc:pc_test_utils",
|
"../../../pc:pc_test_utils",
|
||||||
"../../../pc:peerconnection_wrapper",
|
"../../../pc:peerconnection_wrapper",
|
||||||
"../../../rtc_base",
|
"../../../rtc_base",
|
||||||
"../../../rtc_base:rtc_base_approved",
|
"../../../rtc_base:rtc_base_approved",
|
||||||
|
"../../../rtc_base:rtc_task_queue",
|
||||||
"../../../test:copy_to_file_audio_capturer",
|
"../../../test:copy_to_file_audio_capturer",
|
||||||
"../../../test:video_test_common",
|
"../../../test:video_test_common",
|
||||||
"//third_party/abseil-cpp/absl/memory",
|
"//third_party/abseil-cpp/absl/memory",
|
||||||
|
@ -286,6 +288,20 @@ if (rtc_include_tests) {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer_connection_e2e_smoke_test_resources = [
|
||||||
|
"../../../resources/pc_quality_smoke_test_alice_source.wav",
|
||||||
|
"../../../resources/pc_quality_smoke_test_bob_source.wav",
|
||||||
|
]
|
||||||
|
if (is_ios) {
|
||||||
|
bundle_data("peer_connection_e2e_smoke_test_resources_bundle_data") {
|
||||||
|
testonly = true
|
||||||
|
sources = peer_connection_e2e_smoke_test_resources
|
||||||
|
outputs = [
|
||||||
|
"{{bundle_resources_dir}}/{{source_file_part}}",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rtc_source_set("peer_connection_e2e_smoke_test") {
|
rtc_source_set("peer_connection_e2e_smoke_test") {
|
||||||
testonly = true
|
testonly = true
|
||||||
sources = [
|
sources = [
|
||||||
|
@ -321,6 +337,10 @@ if (rtc_include_tests) {
|
||||||
"../../../test:test_support",
|
"../../../test:test_support",
|
||||||
"//third_party/abseil-cpp/absl/memory",
|
"//third_party/abseil-cpp/absl/memory",
|
||||||
]
|
]
|
||||||
|
data = peer_connection_e2e_smoke_test_resources
|
||||||
|
if (is_ios) {
|
||||||
|
deps += [ ":peer_connection_e2e_smoke_test_resources_bundle_data" ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_source_set("stats_poller") {
|
rtc_source_set("stats_poller") {
|
||||||
|
|
|
@ -85,6 +85,9 @@ TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
|
||||||
alice->AddVideoConfig(std::move(video_config));
|
alice->AddVideoConfig(std::move(video_config));
|
||||||
AudioConfig audio_config;
|
AudioConfig audio_config;
|
||||||
audio_config.stream_label = "alice-audio";
|
audio_config.stream_label = "alice-audio";
|
||||||
|
audio_config.mode = AudioConfig::Mode::kFile;
|
||||||
|
audio_config.input_file_name = test::ResourcePath(
|
||||||
|
"pc_quality_smoke_test_alice_source", "wav");
|
||||||
alice->SetAudioConfig(std::move(audio_config));
|
alice->SetAudioConfig(std::move(audio_config));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -98,10 +101,13 @@ TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
|
||||||
bob->AddVideoConfig(std::move(video_config));
|
bob->AddVideoConfig(std::move(video_config));
|
||||||
AudioConfig audio_config;
|
AudioConfig audio_config;
|
||||||
audio_config.stream_label = "bob-audio";
|
audio_config.stream_label = "bob-audio";
|
||||||
|
audio_config.mode = AudioConfig::Mode::kFile;
|
||||||
|
audio_config.input_file_name = test::ResourcePath(
|
||||||
|
"pc_quality_smoke_test_bob_source", "wav");
|
||||||
bob->SetAudioConfig(std::move(audio_config));
|
bob->SetAudioConfig(std::move(audio_config));
|
||||||
});
|
});
|
||||||
|
|
||||||
RunParams run_params(TimeDelta::seconds(5));
|
RunParams run_params(TimeDelta::seconds(7));
|
||||||
run_params.video_encoder_bitrate_multiplier = 1.1;
|
run_params.video_encoder_bitrate_multiplier = 1.1;
|
||||||
fixture->Run(run_params);
|
fixture->Run(run_params);
|
||||||
|
|
||||||
|
|
|
@ -234,6 +234,9 @@ void PeerConnectionE2EQualityTest::Run(
|
||||||
signaling_thread->SetName(kSignalThreadName, nullptr);
|
signaling_thread->SetName(kSignalThreadName, nullptr);
|
||||||
signaling_thread->Start();
|
signaling_thread->Start();
|
||||||
|
|
||||||
|
// Create a |task_queue_|.
|
||||||
|
task_queue_ = absl::make_unique<TaskQueueForTest>("pc_e2e_quality_test");
|
||||||
|
|
||||||
// Create call participants: Alice and Bob.
|
// Create call participants: Alice and Bob.
|
||||||
// Audio streams are intercepted in AudioDeviceModule, so if it is required to
|
// Audio streams are intercepted in AudioDeviceModule, so if it is required to
|
||||||
// catch output of Alice's stream, Alice's output_dump_file_name should be
|
// catch output of Alice's stream, Alice's output_dump_file_name should be
|
||||||
|
@ -259,7 +262,7 @@ void PeerConnectionE2EQualityTest::Run(
|
||||||
[this]() { StartVideo(alice_video_sources_); }),
|
[this]() { StartVideo(alice_video_sources_); }),
|
||||||
video_quality_analyzer_injection_helper_.get(), signaling_thread.get(),
|
video_quality_analyzer_injection_helper_.get(), signaling_thread.get(),
|
||||||
alice_audio_output_dump_file_name,
|
alice_audio_output_dump_file_name,
|
||||||
run_params.video_encoder_bitrate_multiplier);
|
run_params.video_encoder_bitrate_multiplier, task_queue_.get());
|
||||||
bob_ = TestPeer::CreateTestPeer(
|
bob_ = TestPeer::CreateTestPeer(
|
||||||
std::move(bob_components), std::move(bob_params),
|
std::move(bob_components), std::move(bob_params),
|
||||||
absl::make_unique<FixturePeerConnectionObserver>(
|
absl::make_unique<FixturePeerConnectionObserver>(
|
||||||
|
@ -270,7 +273,7 @@ void PeerConnectionE2EQualityTest::Run(
|
||||||
[this]() { StartVideo(bob_video_sources_); }),
|
[this]() { StartVideo(bob_video_sources_); }),
|
||||||
video_quality_analyzer_injection_helper_.get(), signaling_thread.get(),
|
video_quality_analyzer_injection_helper_.get(), signaling_thread.get(),
|
||||||
bob_audio_output_dump_file_name,
|
bob_audio_output_dump_file_name,
|
||||||
run_params.video_encoder_bitrate_multiplier);
|
run_params.video_encoder_bitrate_multiplier, task_queue_.get());
|
||||||
|
|
||||||
int num_cores = CpuInfo::DetectNumberOfCores();
|
int num_cores = CpuInfo::DetectNumberOfCores();
|
||||||
RTC_DCHECK_GE(num_cores, 1);
|
RTC_DCHECK_GE(num_cores, 1);
|
||||||
|
@ -302,8 +305,6 @@ void PeerConnectionE2EQualityTest::Run(
|
||||||
webrtc::RtcEventLog::kImmediateOutput);
|
webrtc::RtcEventLog::kImmediateOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a |task_queue_|.
|
|
||||||
task_queue_ = absl::make_unique<TaskQueueForTest>("pc_e2e_quality_test");
|
|
||||||
// Setup call.
|
// Setup call.
|
||||||
signaling_thread->Invoke<void>(
|
signaling_thread->Invoke<void>(
|
||||||
RTC_FROM_HERE,
|
RTC_FROM_HERE,
|
||||||
|
@ -345,6 +346,10 @@ void PeerConnectionE2EQualityTest::Run(
|
||||||
RTC_CHECK(no_timeout) << "Failed to stop Stats polling after "
|
RTC_CHECK(no_timeout) << "Failed to stop Stats polling after "
|
||||||
<< kStatsPollingStopTimeout.seconds() << " seconds.";
|
<< kStatsPollingStopTimeout.seconds() << " seconds.";
|
||||||
|
|
||||||
|
// We need to detach AEC dumping from peers, because dump uses |task_queue_|
|
||||||
|
// inside.
|
||||||
|
alice_->DetachAecDump();
|
||||||
|
bob_->DetachAecDump();
|
||||||
// Destroy |task_queue_|. It is done to stop all running tasks and prevent
|
// Destroy |task_queue_|. It is done to stop all running tasks and prevent
|
||||||
// their access to any call related objects after these objects will be
|
// their access to any call related objects after these objects will be
|
||||||
// destroyed during call tear down.
|
// destroyed during call tear down.
|
||||||
|
@ -449,7 +454,9 @@ void PeerConnectionE2EQualityTest::ValidateParams(const RunParams& run_params,
|
||||||
if (p->audio_config.value().mode == AudioConfig::Mode::kFile) {
|
if (p->audio_config.value().mode == AudioConfig::Mode::kFile) {
|
||||||
RTC_CHECK(p->audio_config.value().input_file_name);
|
RTC_CHECK(p->audio_config.value().input_file_name);
|
||||||
RTC_CHECK(
|
RTC_CHECK(
|
||||||
test::FileExists(p->audio_config.value().input_file_name.value()));
|
test::FileExists(p->audio_config.value().input_file_name.value()))
|
||||||
|
<< p->audio_config.value().input_file_name.value()
|
||||||
|
<< " doesn't exist";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,10 @@ class PeerConfigurerImpl final
|
||||||
params_->rtc_event_log_path = std::move(path);
|
params_->rtc_event_log_path = std::move(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
PeerConfigurer* SetAecDumpPath(std::string path) override {
|
||||||
|
params_->aec_dump_path = std::move(path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
PeerConfigurer* SetRTCConfiguration(
|
PeerConfigurer* SetRTCConfiguration(
|
||||||
PeerConnectionInterface::RTCConfiguration configuration) override {
|
PeerConnectionInterface::RTCConfiguration configuration) override {
|
||||||
params_->rtc_configuration = std::move(configuration);
|
params_->rtc_configuration = std::move(configuration);
|
||||||
|
|
|
@ -104,6 +104,9 @@ struct Params {
|
||||||
// If |rtc_event_log_path| is set, an RTCEventLog will be saved in that
|
// If |rtc_event_log_path| is set, an RTCEventLog will be saved in that
|
||||||
// location and it will be available for further analysis.
|
// location and it will be available for further analysis.
|
||||||
absl::optional<std::string> rtc_event_log_path;
|
absl::optional<std::string> rtc_event_log_path;
|
||||||
|
// If |aec_dump_path| is set, an AEC dump will be saved in that location and
|
||||||
|
// it will be available for further analysis.
|
||||||
|
absl::optional<std::string> aec_dump_path;
|
||||||
|
|
||||||
PeerConnectionInterface::RTCConfiguration rtc_configuration;
|
PeerConnectionInterface::RTCConfiguration rtc_configuration;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "logging/rtc_event_log/rtc_event_log_factory.h"
|
#include "logging/rtc_event_log/rtc_event_log_factory.h"
|
||||||
#include "media/engine/webrtc_media_engine.h"
|
#include "media/engine/webrtc_media_engine.h"
|
||||||
#include "modules/audio_device/include/audio_device.h"
|
#include "modules/audio_device/include/audio_device.h"
|
||||||
|
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
|
||||||
#include "modules/audio_processing/include/audio_processing.h"
|
#include "modules/audio_processing/include/audio_processing.h"
|
||||||
#include "p2p/client/basic_port_allocator.h"
|
#include "p2p/client/basic_port_allocator.h"
|
||||||
#include "rtc_base/location.h"
|
#include "rtc_base/location.h"
|
||||||
|
@ -33,8 +34,6 @@ namespace {
|
||||||
constexpr int16_t kGeneratedAudioMaxAmplitude = 32000;
|
constexpr int16_t kGeneratedAudioMaxAmplitude = 32000;
|
||||||
constexpr int kSamplingFrequencyInHz = 48000;
|
constexpr int kSamplingFrequencyInHz = 48000;
|
||||||
|
|
||||||
using AudioConfig = PeerConnectionE2EQualityTestFixture::AudioConfig;
|
|
||||||
|
|
||||||
// Sets mandatory entities in injectable components like |pcf_dependencies|
|
// Sets mandatory entities in injectable components like |pcf_dependencies|
|
||||||
// and |pc_dependencies| if they are omitted. Also setup required
|
// and |pc_dependencies| if they are omitted. Also setup required
|
||||||
// dependencies, that won't be specially provided by factory and will be just
|
// dependencies, that won't be specially provided by factory and will be just
|
||||||
|
@ -53,175 +52,232 @@ void SetMandatoryEntities(InjectableComponents* components) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<TestAudioDeviceModule::Capturer> CreateAudioCapturer(
|
struct TestPeerComponents {
|
||||||
AudioConfig audio_config) {
|
using AudioConfig = PeerConnectionE2EQualityTestFixture::AudioConfig;
|
||||||
if (audio_config.mode == AudioConfig::Mode::kGenerated) {
|
|
||||||
return TestAudioDeviceModule::CreatePulsedNoiseCapturer(
|
|
||||||
kGeneratedAudioMaxAmplitude, kSamplingFrequencyInHz);
|
|
||||||
}
|
|
||||||
if (audio_config.mode == AudioConfig::Mode::kFile) {
|
|
||||||
RTC_DCHECK(audio_config.input_file_name);
|
|
||||||
return TestAudioDeviceModule::CreateWavFileReader(
|
|
||||||
audio_config.input_file_name.value());
|
|
||||||
}
|
|
||||||
RTC_NOTREACHED() << "Unknown audio_config->mode";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModule(
|
rtc::scoped_refptr<PeerConnectionFactoryInterface> peer_connection_factory;
|
||||||
absl::optional<AudioConfig> audio_config,
|
rtc::scoped_refptr<PeerConnectionInterface> peer_connection;
|
||||||
absl::optional<std::string> audio_output_file_name) {
|
rtc::scoped_refptr<AudioProcessing> audio_processing;
|
||||||
std::unique_ptr<TestAudioDeviceModule::Capturer> capturer;
|
|
||||||
if (audio_config) {
|
|
||||||
capturer = CreateAudioCapturer(audio_config.value());
|
|
||||||
} else {
|
|
||||||
// If we have no audio config we still need to provide some audio device.
|
|
||||||
// In such case use generated capturer. Despite of we provided audio here,
|
|
||||||
// in test media setup audio stream won't be added into peer connection.
|
|
||||||
capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(
|
|
||||||
kGeneratedAudioMaxAmplitude, kSamplingFrequencyInHz);
|
|
||||||
}
|
|
||||||
RTC_DCHECK(capturer);
|
|
||||||
|
|
||||||
if (audio_config && audio_config->input_dump_file_name) {
|
TestPeerComponents(std::unique_ptr<InjectableComponents> components,
|
||||||
capturer = absl::make_unique<test::CopyToFileAudioCapturer>(
|
const Params& params,
|
||||||
std::move(capturer), audio_config->input_dump_file_name.value());
|
MockPeerConnectionObserver* observer,
|
||||||
|
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
||||||
|
rtc::Thread* signaling_thread,
|
||||||
|
absl::optional<std::string> audio_output_file_name,
|
||||||
|
double bitrate_multiplier,
|
||||||
|
rtc::TaskQueue* task_queue) {
|
||||||
|
std::map<std::string, absl::optional<int>> stream_required_spatial_index;
|
||||||
|
for (auto& video_config : params.video_configs) {
|
||||||
|
// Stream label should be set by fixture implementation here.
|
||||||
|
RTC_DCHECK(video_config.stream_label);
|
||||||
|
bool res = stream_required_spatial_index
|
||||||
|
.insert({*video_config.stream_label,
|
||||||
|
video_config.target_spatial_index})
|
||||||
|
.second;
|
||||||
|
RTC_DCHECK(res) << "Duplicate video_config.stream_label="
|
||||||
|
<< *video_config.stream_label;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create audio processing, that will be used to create media engine that
|
||||||
|
// then will be added into peer connection. See CreateMediaEngine(...).
|
||||||
|
audio_processing = webrtc::AudioProcessingBuilder().Create();
|
||||||
|
if (params.aec_dump_path) {
|
||||||
|
audio_processing->AttachAecDump(
|
||||||
|
AecDumpFactory::Create(*params.aec_dump_path, -1, task_queue));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create peer connection factory.
|
||||||
|
PeerConnectionFactoryDependencies pcf_deps = CreatePCFDependencies(
|
||||||
|
std::move(components->pcf_dependencies), params.audio_config,
|
||||||
|
bitrate_multiplier, std::move(stream_required_spatial_index),
|
||||||
|
video_analyzer_helper, components->network_thread, signaling_thread,
|
||||||
|
std::move(audio_output_file_name), task_queue);
|
||||||
|
peer_connection_factory =
|
||||||
|
CreateModularPeerConnectionFactory(std::move(pcf_deps));
|
||||||
|
|
||||||
|
// Create peer connection.
|
||||||
|
PeerConnectionDependencies pc_deps =
|
||||||
|
CreatePCDependencies(std::move(components->pc_dependencies), observer);
|
||||||
|
peer_connection = peer_connection_factory->CreatePeerConnection(
|
||||||
|
params.rtc_configuration, std::move(pc_deps));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<TestAudioDeviceModule::Renderer> renderer;
|
std::unique_ptr<TestAudioDeviceModule::Capturer> CreateAudioCapturer(
|
||||||
if (audio_output_file_name) {
|
AudioConfig audio_config) {
|
||||||
renderer = TestAudioDeviceModule::CreateBoundedWavFileWriter(
|
if (audio_config.mode == AudioConfig::Mode::kGenerated) {
|
||||||
audio_output_file_name.value(), kSamplingFrequencyInHz);
|
return TestAudioDeviceModule::CreatePulsedNoiseCapturer(
|
||||||
} else {
|
kGeneratedAudioMaxAmplitude, kSamplingFrequencyInHz);
|
||||||
renderer =
|
}
|
||||||
TestAudioDeviceModule::CreateDiscardRenderer(kSamplingFrequencyInHz);
|
if (audio_config.mode == AudioConfig::Mode::kFile) {
|
||||||
|
RTC_DCHECK(audio_config.input_file_name);
|
||||||
|
return TestAudioDeviceModule::CreateWavFileReader(
|
||||||
|
audio_config.input_file_name.value());
|
||||||
|
}
|
||||||
|
RTC_NOTREACHED() << "Unknown audio_config->mode";
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TestAudioDeviceModule::CreateTestAudioDeviceModule(
|
rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModule(
|
||||||
std::move(capturer), std::move(renderer), /*speed=*/1.f);
|
absl::optional<AudioConfig> audio_config,
|
||||||
}
|
absl::optional<std::string> audio_output_file_name) {
|
||||||
|
std::unique_ptr<TestAudioDeviceModule::Capturer> capturer;
|
||||||
|
if (audio_config) {
|
||||||
|
capturer = CreateAudioCapturer(audio_config.value());
|
||||||
|
} else {
|
||||||
|
// If we have no audio config we still need to provide some audio device.
|
||||||
|
// In such case use generated capturer. Despite of we provided audio here,
|
||||||
|
// in test media setup audio stream won't be added into peer connection.
|
||||||
|
capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(
|
||||||
|
kGeneratedAudioMaxAmplitude, kSamplingFrequencyInHz);
|
||||||
|
}
|
||||||
|
RTC_DCHECK(capturer);
|
||||||
|
|
||||||
std::unique_ptr<VideoEncoderFactory> CreateVideoEncoderFactory(
|
if (audio_config && audio_config->input_dump_file_name) {
|
||||||
PeerConnectionFactoryComponents* pcf_dependencies,
|
capturer = absl::make_unique<test::CopyToFileAudioCapturer>(
|
||||||
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
std::move(capturer), audio_config->input_dump_file_name.value());
|
||||||
double bitrate_multiplier,
|
}
|
||||||
std::map<std::string, absl::optional<int>> stream_required_spatial_index) {
|
|
||||||
std::unique_ptr<VideoEncoderFactory> video_encoder_factory;
|
|
||||||
if (pcf_dependencies->video_encoder_factory != nullptr) {
|
|
||||||
video_encoder_factory = std::move(pcf_dependencies->video_encoder_factory);
|
|
||||||
} else {
|
|
||||||
video_encoder_factory = CreateBuiltinVideoEncoderFactory();
|
|
||||||
}
|
|
||||||
return video_analyzer_helper->WrapVideoEncoderFactory(
|
|
||||||
std::move(video_encoder_factory), bitrate_multiplier,
|
|
||||||
std::move(stream_required_spatial_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<VideoDecoderFactory> CreateVideoDecoderFactory(
|
std::unique_ptr<TestAudioDeviceModule::Renderer> renderer;
|
||||||
PeerConnectionFactoryComponents* pcf_dependencies,
|
if (audio_output_file_name) {
|
||||||
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper) {
|
renderer = TestAudioDeviceModule::CreateBoundedWavFileWriter(
|
||||||
std::unique_ptr<VideoDecoderFactory> video_decoder_factory;
|
audio_output_file_name.value(), kSamplingFrequencyInHz);
|
||||||
if (pcf_dependencies->video_decoder_factory != nullptr) {
|
} else {
|
||||||
video_decoder_factory = std::move(pcf_dependencies->video_decoder_factory);
|
renderer =
|
||||||
} else {
|
TestAudioDeviceModule::CreateDiscardRenderer(kSamplingFrequencyInHz);
|
||||||
video_decoder_factory = CreateBuiltinVideoDecoderFactory();
|
}
|
||||||
}
|
|
||||||
return video_analyzer_helper->WrapVideoDecoderFactory(
|
|
||||||
std::move(video_decoder_factory));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<cricket::MediaEngineInterface> CreateMediaEngine(
|
return TestAudioDeviceModule::CreateTestAudioDeviceModule(
|
||||||
PeerConnectionFactoryComponents* pcf_dependencies,
|
std::move(capturer), std::move(renderer), /*speed=*/1.f);
|
||||||
absl::optional<AudioConfig> audio_config,
|
|
||||||
double bitrate_multiplier,
|
|
||||||
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
|
|
||||||
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
|
||||||
absl::optional<std::string> audio_output_file_name) {
|
|
||||||
rtc::scoped_refptr<AudioDeviceModule> adm = CreateAudioDeviceModule(
|
|
||||||
std::move(audio_config), std::move(audio_output_file_name));
|
|
||||||
|
|
||||||
std::unique_ptr<VideoEncoderFactory> video_encoder_factory =
|
|
||||||
CreateVideoEncoderFactory(pcf_dependencies, video_analyzer_helper,
|
|
||||||
bitrate_multiplier,
|
|
||||||
std::move(stream_required_spatial_index));
|
|
||||||
std::unique_ptr<VideoDecoderFactory> video_decoder_factory =
|
|
||||||
CreateVideoDecoderFactory(pcf_dependencies, video_analyzer_helper);
|
|
||||||
|
|
||||||
return cricket::WebRtcMediaEngineFactory::Create(
|
|
||||||
adm, webrtc::CreateBuiltinAudioEncoderFactory(),
|
|
||||||
webrtc::CreateBuiltinAudioDecoderFactory(),
|
|
||||||
std::move(video_encoder_factory), std::move(video_decoder_factory),
|
|
||||||
/*audio_mixer=*/nullptr, webrtc::AudioProcessingBuilder().Create());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates PeerConnectionFactoryDependencies objects, providing entities
|
|
||||||
// from InjectableComponents::PeerConnectionFactoryComponents and also
|
|
||||||
// creating entities, that are required for correct injection of media quality
|
|
||||||
// analyzers.
|
|
||||||
PeerConnectionFactoryDependencies CreatePCFDependencies(
|
|
||||||
std::unique_ptr<PeerConnectionFactoryComponents> pcf_dependencies,
|
|
||||||
absl::optional<AudioConfig> audio_config,
|
|
||||||
double bitrate_multiplier,
|
|
||||||
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
|
|
||||||
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
|
||||||
rtc::Thread* network_thread,
|
|
||||||
rtc::Thread* signaling_thread,
|
|
||||||
absl::optional<std::string> audio_output_file_name) {
|
|
||||||
PeerConnectionFactoryDependencies pcf_deps;
|
|
||||||
pcf_deps.network_thread = network_thread;
|
|
||||||
pcf_deps.signaling_thread = signaling_thread;
|
|
||||||
pcf_deps.media_engine = CreateMediaEngine(
|
|
||||||
pcf_dependencies.get(), std::move(audio_config), bitrate_multiplier,
|
|
||||||
std::move(stream_required_spatial_index), video_analyzer_helper,
|
|
||||||
std::move(audio_output_file_name));
|
|
||||||
|
|
||||||
pcf_deps.call_factory = std::move(pcf_dependencies->call_factory);
|
|
||||||
pcf_deps.event_log_factory = std::move(pcf_dependencies->event_log_factory);
|
|
||||||
|
|
||||||
if (pcf_dependencies->fec_controller_factory != nullptr) {
|
|
||||||
pcf_deps.fec_controller_factory =
|
|
||||||
std::move(pcf_dependencies->fec_controller_factory);
|
|
||||||
}
|
|
||||||
if (pcf_dependencies->network_controller_factory != nullptr) {
|
|
||||||
pcf_deps.network_controller_factory =
|
|
||||||
std::move(pcf_dependencies->network_controller_factory);
|
|
||||||
}
|
|
||||||
if (pcf_dependencies->media_transport_factory != nullptr) {
|
|
||||||
pcf_deps.media_transport_factory =
|
|
||||||
std::move(pcf_dependencies->media_transport_factory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pcf_deps;
|
std::unique_ptr<VideoEncoderFactory> CreateVideoEncoderFactory(
|
||||||
}
|
PeerConnectionFactoryComponents* pcf_dependencies,
|
||||||
|
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
||||||
// Creates PeerConnectionDependencies objects, providing entities
|
double bitrate_multiplier,
|
||||||
// from InjectableComponents::PeerConnectionComponents.
|
std::map<std::string, absl::optional<int>>
|
||||||
PeerConnectionDependencies CreatePCDependencies(
|
stream_required_spatial_index) {
|
||||||
std::unique_ptr<PeerConnectionComponents> pc_dependencies,
|
std::unique_ptr<VideoEncoderFactory> video_encoder_factory;
|
||||||
PeerConnectionObserver* observer) {
|
if (pcf_dependencies->video_encoder_factory != nullptr) {
|
||||||
PeerConnectionDependencies pc_deps(observer);
|
video_encoder_factory =
|
||||||
|
std::move(pcf_dependencies->video_encoder_factory);
|
||||||
auto port_allocator = absl::make_unique<cricket::BasicPortAllocator>(
|
} else {
|
||||||
pc_dependencies->network_manager);
|
video_encoder_factory = CreateBuiltinVideoEncoderFactory();
|
||||||
|
}
|
||||||
// This test does not support TCP
|
return video_analyzer_helper->WrapVideoEncoderFactory(
|
||||||
int flags = cricket::PORTALLOCATOR_DISABLE_TCP;
|
std::move(video_encoder_factory), bitrate_multiplier,
|
||||||
port_allocator->set_flags(port_allocator->flags() | flags);
|
std::move(stream_required_spatial_index));
|
||||||
|
|
||||||
pc_deps.allocator = std::move(port_allocator);
|
|
||||||
|
|
||||||
if (pc_dependencies->async_resolver_factory != nullptr) {
|
|
||||||
pc_deps.async_resolver_factory =
|
|
||||||
std::move(pc_dependencies->async_resolver_factory);
|
|
||||||
}
|
}
|
||||||
if (pc_dependencies->cert_generator != nullptr) {
|
|
||||||
pc_deps.cert_generator = std::move(pc_dependencies->cert_generator);
|
std::unique_ptr<VideoDecoderFactory> CreateVideoDecoderFactory(
|
||||||
|
PeerConnectionFactoryComponents* pcf_dependencies,
|
||||||
|
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper) {
|
||||||
|
std::unique_ptr<VideoDecoderFactory> video_decoder_factory;
|
||||||
|
if (pcf_dependencies->video_decoder_factory != nullptr) {
|
||||||
|
video_decoder_factory =
|
||||||
|
std::move(pcf_dependencies->video_decoder_factory);
|
||||||
|
} else {
|
||||||
|
video_decoder_factory = CreateBuiltinVideoDecoderFactory();
|
||||||
|
}
|
||||||
|
return video_analyzer_helper->WrapVideoDecoderFactory(
|
||||||
|
std::move(video_decoder_factory));
|
||||||
}
|
}
|
||||||
if (pc_dependencies->tls_cert_verifier != nullptr) {
|
|
||||||
pc_deps.tls_cert_verifier = std::move(pc_dependencies->tls_cert_verifier);
|
std::unique_ptr<cricket::MediaEngineInterface> CreateMediaEngine(
|
||||||
|
PeerConnectionFactoryComponents* pcf_dependencies,
|
||||||
|
absl::optional<AudioConfig> audio_config,
|
||||||
|
double bitrate_multiplier,
|
||||||
|
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
|
||||||
|
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
||||||
|
absl::optional<std::string> audio_output_file_name,
|
||||||
|
rtc::TaskQueue* task_queue) {
|
||||||
|
rtc::scoped_refptr<AudioDeviceModule> adm = CreateAudioDeviceModule(
|
||||||
|
std::move(audio_config), std::move(audio_output_file_name));
|
||||||
|
|
||||||
|
std::unique_ptr<VideoEncoderFactory> video_encoder_factory =
|
||||||
|
CreateVideoEncoderFactory(pcf_dependencies, video_analyzer_helper,
|
||||||
|
bitrate_multiplier,
|
||||||
|
std::move(stream_required_spatial_index));
|
||||||
|
std::unique_ptr<VideoDecoderFactory> video_decoder_factory =
|
||||||
|
CreateVideoDecoderFactory(pcf_dependencies, video_analyzer_helper);
|
||||||
|
|
||||||
|
return cricket::WebRtcMediaEngineFactory::Create(
|
||||||
|
adm, webrtc::CreateBuiltinAudioEncoderFactory(),
|
||||||
|
webrtc::CreateBuiltinAudioDecoderFactory(),
|
||||||
|
std::move(video_encoder_factory), std::move(video_decoder_factory),
|
||||||
|
/*audio_mixer=*/nullptr, audio_processing);
|
||||||
}
|
}
|
||||||
return pc_deps;
|
|
||||||
}
|
// Creates PeerConnectionFactoryDependencies objects, providing entities
|
||||||
|
// from InjectableComponents::PeerConnectionFactoryComponents and also
|
||||||
|
// creating entities, that are required for correct injection of media quality
|
||||||
|
// analyzers.
|
||||||
|
PeerConnectionFactoryDependencies CreatePCFDependencies(
|
||||||
|
std::unique_ptr<PeerConnectionFactoryComponents> pcf_dependencies,
|
||||||
|
absl::optional<AudioConfig> audio_config,
|
||||||
|
double bitrate_multiplier,
|
||||||
|
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
|
||||||
|
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
||||||
|
rtc::Thread* network_thread,
|
||||||
|
rtc::Thread* signaling_thread,
|
||||||
|
absl::optional<std::string> audio_output_file_name,
|
||||||
|
rtc::TaskQueue* task_queue) {
|
||||||
|
PeerConnectionFactoryDependencies pcf_deps;
|
||||||
|
pcf_deps.network_thread = network_thread;
|
||||||
|
pcf_deps.signaling_thread = signaling_thread;
|
||||||
|
pcf_deps.media_engine = CreateMediaEngine(
|
||||||
|
pcf_dependencies.get(), std::move(audio_config), bitrate_multiplier,
|
||||||
|
std::move(stream_required_spatial_index), video_analyzer_helper,
|
||||||
|
std::move(audio_output_file_name), task_queue);
|
||||||
|
|
||||||
|
pcf_deps.call_factory = std::move(pcf_dependencies->call_factory);
|
||||||
|
pcf_deps.event_log_factory = std::move(pcf_dependencies->event_log_factory);
|
||||||
|
|
||||||
|
if (pcf_dependencies->fec_controller_factory != nullptr) {
|
||||||
|
pcf_deps.fec_controller_factory =
|
||||||
|
std::move(pcf_dependencies->fec_controller_factory);
|
||||||
|
}
|
||||||
|
if (pcf_dependencies->network_controller_factory != nullptr) {
|
||||||
|
pcf_deps.network_controller_factory =
|
||||||
|
std::move(pcf_dependencies->network_controller_factory);
|
||||||
|
}
|
||||||
|
if (pcf_dependencies->media_transport_factory != nullptr) {
|
||||||
|
pcf_deps.media_transport_factory =
|
||||||
|
std::move(pcf_dependencies->media_transport_factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pcf_deps;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates PeerConnectionDependencies objects, providing entities
|
||||||
|
// from InjectableComponents::PeerConnectionComponents.
|
||||||
|
PeerConnectionDependencies CreatePCDependencies(
|
||||||
|
std::unique_ptr<PeerConnectionComponents> pc_dependencies,
|
||||||
|
PeerConnectionObserver* observer) {
|
||||||
|
PeerConnectionDependencies pc_deps(observer);
|
||||||
|
|
||||||
|
auto port_allocator = absl::make_unique<cricket::BasicPortAllocator>(
|
||||||
|
pc_dependencies->network_manager);
|
||||||
|
|
||||||
|
// This test does not support TCP
|
||||||
|
int flags = cricket::PORTALLOCATOR_DISABLE_TCP;
|
||||||
|
port_allocator->set_flags(port_allocator->flags() | flags);
|
||||||
|
|
||||||
|
pc_deps.allocator = std::move(port_allocator);
|
||||||
|
|
||||||
|
if (pc_dependencies->async_resolver_factory != nullptr) {
|
||||||
|
pc_deps.async_resolver_factory =
|
||||||
|
std::move(pc_dependencies->async_resolver_factory);
|
||||||
|
}
|
||||||
|
if (pc_dependencies->cert_generator != nullptr) {
|
||||||
|
pc_deps.cert_generator = std::move(pc_dependencies->cert_generator);
|
||||||
|
}
|
||||||
|
if (pc_dependencies->tls_cert_verifier != nullptr) {
|
||||||
|
pc_deps.tls_cert_verifier = std::move(pc_dependencies->tls_cert_verifier);
|
||||||
|
}
|
||||||
|
return pc_deps;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -232,41 +288,21 @@ std::unique_ptr<TestPeer> TestPeer::CreateTestPeer(
|
||||||
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
||||||
rtc::Thread* signaling_thread,
|
rtc::Thread* signaling_thread,
|
||||||
absl::optional<std::string> audio_output_file_name,
|
absl::optional<std::string> audio_output_file_name,
|
||||||
double bitrate_multiplier) {
|
double bitrate_multiplier,
|
||||||
|
rtc::TaskQueue* task_queue) {
|
||||||
RTC_DCHECK(components);
|
RTC_DCHECK(components);
|
||||||
RTC_DCHECK(params);
|
RTC_DCHECK(params);
|
||||||
SetMandatoryEntities(components.get());
|
SetMandatoryEntities(components.get());
|
||||||
params->rtc_configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
|
params->rtc_configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
|
||||||
|
|
||||||
std::map<std::string, absl::optional<int>> stream_required_spatial_index;
|
TestPeerComponents tpc(std::move(components), *params, observer.get(),
|
||||||
for (auto& video_config : params->video_configs) {
|
video_analyzer_helper, signaling_thread,
|
||||||
// Stream label should be set by fixture implementation here.
|
std::move(audio_output_file_name), bitrate_multiplier,
|
||||||
RTC_DCHECK(video_config.stream_label);
|
task_queue);
|
||||||
bool res = stream_required_spatial_index
|
|
||||||
.insert({*video_config.stream_label,
|
|
||||||
video_config.target_spatial_index})
|
|
||||||
.second;
|
|
||||||
RTC_DCHECK(res) << "Duplicate video_config.stream_label="
|
|
||||||
<< *video_config.stream_label;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create peer connection factory.
|
return absl::WrapUnique(new TestPeer(
|
||||||
PeerConnectionFactoryDependencies pcf_deps = CreatePCFDependencies(
|
tpc.peer_connection_factory, tpc.peer_connection, std::move(observer),
|
||||||
std::move(components->pcf_dependencies), params->audio_config,
|
std::move(params), tpc.audio_processing));
|
||||||
bitrate_multiplier, std::move(stream_required_spatial_index),
|
|
||||||
video_analyzer_helper, components->network_thread, signaling_thread,
|
|
||||||
std::move(audio_output_file_name));
|
|
||||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> pcf =
|
|
||||||
CreateModularPeerConnectionFactory(std::move(pcf_deps));
|
|
||||||
|
|
||||||
// Create peer connection.
|
|
||||||
PeerConnectionDependencies pc_deps = CreatePCDependencies(
|
|
||||||
std::move(components->pc_dependencies), observer.get());
|
|
||||||
rtc::scoped_refptr<PeerConnectionInterface> pc =
|
|
||||||
pcf->CreatePeerConnection(params->rtc_configuration, std::move(pc_deps));
|
|
||||||
|
|
||||||
return absl::WrapUnique(
|
|
||||||
new TestPeer(pcf, pc, std::move(observer), std::move(params)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestPeer::AddIceCandidates(
|
bool TestPeer::AddIceCandidates(
|
||||||
|
@ -289,11 +325,13 @@ TestPeer::TestPeer(
|
||||||
rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
|
rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
|
||||||
rtc::scoped_refptr<PeerConnectionInterface> pc,
|
rtc::scoped_refptr<PeerConnectionInterface> pc,
|
||||||
std::unique_ptr<MockPeerConnectionObserver> observer,
|
std::unique_ptr<MockPeerConnectionObserver> observer,
|
||||||
std::unique_ptr<Params> params)
|
std::unique_ptr<Params> params,
|
||||||
|
rtc::scoped_refptr<AudioProcessing> audio_processing)
|
||||||
: PeerConnectionWrapper::PeerConnectionWrapper(std::move(pc_factory),
|
: PeerConnectionWrapper::PeerConnectionWrapper(std::move(pc_factory),
|
||||||
std::move(pc),
|
std::move(pc),
|
||||||
std::move(observer)),
|
std::move(observer)),
|
||||||
params_(std::move(params)) {}
|
params_(std::move(params)),
|
||||||
|
audio_processing_(audio_processing) {}
|
||||||
|
|
||||||
} // namespace webrtc_pc_e2e
|
} // namespace webrtc_pc_e2e
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "pc/peer_connection_wrapper.h"
|
#include "pc/peer_connection_wrapper.h"
|
||||||
#include "pc/test/mock_peer_connection_observers.h"
|
#include "pc/test/mock_peer_connection_observers.h"
|
||||||
#include "rtc_base/network.h"
|
#include "rtc_base/network.h"
|
||||||
|
#include "rtc_base/task_queue.h"
|
||||||
#include "rtc_base/thread.h"
|
#include "rtc_base/thread.h"
|
||||||
#include "test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h"
|
#include "test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h"
|
||||||
#include "test/pc/e2e/peer_connection_quality_test_params.h"
|
#include "test/pc/e2e/peer_connection_quality_test_params.h"
|
||||||
|
@ -54,9 +55,11 @@ class TestPeer final : public PeerConnectionWrapper {
|
||||||
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper,
|
||||||
rtc::Thread* signaling_thread,
|
rtc::Thread* signaling_thread,
|
||||||
absl::optional<std::string> audio_output_file_name,
|
absl::optional<std::string> audio_output_file_name,
|
||||||
double bitrate_multiplier);
|
double bitrate_multiplier,
|
||||||
|
rtc::TaskQueue* task_queue);
|
||||||
|
|
||||||
Params* params() const { return params_.get(); }
|
Params* params() const { return params_.get(); }
|
||||||
|
void DetachAecDump() { audio_processing_->DetachAecDump(); }
|
||||||
|
|
||||||
// Adds provided |candidates| to the owned peer connection.
|
// Adds provided |candidates| to the owned peer connection.
|
||||||
bool AddIceCandidates(
|
bool AddIceCandidates(
|
||||||
|
@ -66,9 +69,11 @@ class TestPeer final : public PeerConnectionWrapper {
|
||||||
TestPeer(rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
|
TestPeer(rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
|
||||||
rtc::scoped_refptr<PeerConnectionInterface> pc,
|
rtc::scoped_refptr<PeerConnectionInterface> pc,
|
||||||
std::unique_ptr<MockPeerConnectionObserver> observer,
|
std::unique_ptr<MockPeerConnectionObserver> observer,
|
||||||
std::unique_ptr<Params> params);
|
std::unique_ptr<Params> params,
|
||||||
|
rtc::scoped_refptr<AudioProcessing> audio_processing);
|
||||||
|
|
||||||
std::unique_ptr<Params> params_;
|
std::unique_ptr<Params> params_;
|
||||||
|
rtc::scoped_refptr<AudioProcessing> audio_processing_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc_pc_e2e
|
} // namespace webrtc_pc_e2e
|
||||||
|
|
Loading…
Reference in a new issue