Add SmokeSendAndReceivePacketsOnOneThread

Only use the network thread for sending and receiving packets.
The one and only network thread is used as a worker thread in all
PeerConnections. Pacing when sending packets is done on the worker thread.

Bug: webrtc:14502
Change-Id: Ib373315688ae4d810ae1e4421101a859fca93b31
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/278621
Reviewed-by: Evan Shrubsole <eshr@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38354}
This commit is contained in:
Per Kjellander
2022-10-11 13:05:33 +02:00
committed by WebRTC LUCI CQ
parent ac7577854f
commit 78d80f9be7
7 changed files with 99 additions and 7 deletions

View File

@ -532,6 +532,10 @@ class PeerConnectionE2EQualityTestFixture {
virtual PeerConfigurer* SetAudioMixer(
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) = 0;
// Forces the Peerconnection to use the network thread as the worker thread.
// Ie, worker thread and the network thread is the same thread.
virtual PeerConfigurer* SetUseNetworkThreadAsWorkerThread() = 0;
// The parameters of the following 4 methods will be passed to the
// PeerConnectionInterface implementation that will be created for this
// peer.

View File

@ -335,6 +335,7 @@ if (!build_with_chromium) {
"../../../modules/audio_processing/aec_dump",
"../../../p2p:rtc_p2p",
"../../../rtc_base:rtc_task_queue",
"../../../rtc_base:threading",
]
absl_deps = [
"//third_party/abseil-cpp/absl/memory",

View File

@ -184,6 +184,12 @@ class PeerConfigurerImpl final
components_->pcf_dependencies->audio_mixer = audio_mixer;
return this;
}
virtual PeerConfigurer* SetUseNetworkThreadAsWorkerThread() override {
components_->worker_thread = components_->network_thread;
return this;
}
PeerConfigurer* SetRtcEventLogPath(std::string path) override {
params_->rtc_event_log_path = std::move(path);
return this;

View File

@ -10,6 +10,7 @@
#include <cstdint>
#include <memory>
#include <string>
#include "api/media_stream_interface.h"
#include "api/test/create_network_emulation_manager.h"
@ -191,6 +192,73 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Smoke) {
RunAndCheckEachVideoStreamReceivedFrames(run_params);
}
// IOS debug builds can be quite slow, disabling to avoid issues with timeouts.
#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM64) && !defined(NDEBUG)
#define MAYBE_Smoke DISABLED_Smoke
#else
#define MAYBE_SendAndReceivePacketsOnOneThread \
SmokeSendAndReceivePacketsOnOneThread
#endif
// Only use the network thread for sending and receiving packets.
// The one and only network thread is used as a worker thread in all
// PeerConnections. Pacing when sending packets is done on the worker thread.
// See bugs.webrtc.org/14502.
TEST_F(PeerConnectionE2EQualityTestSmokeTest,
MAYBE_SendAndReceivePacketsOnOneThread) {
test::ScopedFieldTrials trials(
std::string(field_trial::GetFieldTrialString()) +
"WebRTC-SendPacketsOnWorkerThread/Enabled/");
std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>
network_links = CreateNetwork();
AddPeer(network_links.first, [](PeerConfigurer* alice) {
// Peerconnection use the network thread as the worker thread.
alice->SetUseNetworkThreadAsWorkerThread();
VideoConfig video(160, 120, 15);
video.stream_label = "alice-video";
video.sync_group = "alice-media";
alice->AddVideoConfig(std::move(video));
AudioConfig audio;
audio.stream_label = "alice-audio";
audio.mode = AudioConfig::Mode::kFile;
audio.input_file_name =
test::ResourcePath("pc_quality_smoke_test_alice_source", "wav");
audio.sampling_frequency_in_hz = 48000;
audio.sync_group = "alice-media";
alice->SetAudioConfig(std::move(audio));
alice->SetVideoCodecs(
{VideoCodecConfig(cricket::kVp9CodecName, {{"profile-id", "0"}})});
});
AddPeer(network_links.second, [](PeerConfigurer* charlie) {
// Peerconnection use the network thread as the worker thread.
charlie->SetUseNetworkThreadAsWorkerThread();
charlie->SetName("charlie");
VideoConfig video(160, 120, 15);
video.stream_label = "charlie-video";
video.temporal_layers_count = 2;
charlie->AddVideoConfig(std::move(video));
AudioConfig audio;
audio.stream_label = "charlie-audio";
audio.mode = AudioConfig::Mode::kFile;
audio.input_file_name =
test::ResourcePath("pc_quality_smoke_test_bob_source", "wav");
charlie->SetAudioConfig(std::move(audio));
charlie->SetVideoCodecs(
{VideoCodecConfig(cricket::kVp9CodecName, {{"profile-id", "0"}})});
charlie->SetVideoEncoderBitrateMultiplier(1.1);
});
fixture()->AddQualityMetricsReporter(
std::make_unique<StatsBasedNetworkQualityMetricsReporter>(
std::map<std::string, std::vector<EmulatedEndpoint*>>(
{{"alice", network_links.first->endpoints()},
{"charlie", network_links.second->endpoints()}}),
network_emulation(), test::GetGlobalMetricsLogger()));
RunParams run_params(TimeDelta::Seconds(2));
RunAndCheckEachVideoStreamReceivedFrames(run_params);
}
#if defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
TEST_F(PeerConnectionE2EQualityTestSmokeTest, SmokeH264) {
std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>

View File

@ -10,6 +10,7 @@
#ifndef TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_PARAMS_H_
#define TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_PARAMS_H_
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
@ -95,6 +96,7 @@ struct InjectableComponents {
rtc::NetworkManager* network_manager,
rtc::PacketSocketFactory* packet_socket_factory)
: network_thread(network_thread),
worker_thread(nullptr),
pcf_dependencies(std::make_unique<PeerConnectionFactoryComponents>()),
pc_dependencies(
std::make_unique<PeerConnectionComponents>(network_manager,
@ -103,6 +105,7 @@ struct InjectableComponents {
}
rtc::Thread* const network_thread;
rtc::Thread* worker_thread;
std::unique_ptr<PeerConnectionFactoryComponents> pcf_dependencies;
std::unique_ptr<PeerConnectionComponents> pc_dependencies;

View File

@ -173,6 +173,8 @@ class TestPeer final : public StatsProvider {
nullptr;
// Keeps ownership of worker thread. It has to be destroyed after `wrapper_`.
// `worker_thread_`can be null if the Peer use only one thread as both the
// worker thread and network thread.
std::unique_ptr<rtc::Thread> worker_thread_;
std::unique_ptr<PeerConnectionWrapper> wrapper_;
std::vector<PeerConfigurerImpl::VideoSource> video_sources_;

View File

@ -23,6 +23,7 @@
#include "media/engine/webrtc_media_engine_defaults.h"
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
#include "p2p/client/basic_port_allocator.h"
#include "rtc_base/thread.h"
#include "test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h"
#include "test/pc/e2e/echo/echo_emulation.h"
#include "test/pc/e2e/peer_configurer.h"
@ -339,15 +340,21 @@ std::unique_ptr<TestPeer> TestPeerFactory::CreateTestPeer(
CreateMediaEngine(components->pcf_dependencies.get(),
audio_device_module);
std::unique_ptr<rtc::Thread> worker_thread =
time_controller_.CreateThread("worker_thread");
std::unique_ptr<rtc::Thread> owned_worker_thread =
components->worker_thread != nullptr
? nullptr
: time_controller_.CreateThread("worker_thread");
if (components->worker_thread == nullptr) {
components->worker_thread = owned_worker_thread.get();
}
// Store `webrtc::AudioProcessing` into local variable before move of
// `components->pcf_dependencies`
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing =
components->pcf_dependencies->audio_processing;
PeerConnectionFactoryDependencies pcf_deps = CreatePCFDependencies(
std::move(components->pcf_dependencies), std::move(media_engine),
signaling_thread_, worker_thread.get(), components->network_thread);
signaling_thread_, components->worker_thread, components->network_thread);
rtc::scoped_refptr<PeerConnectionFactoryInterface> peer_connection_factory =
CreateModularPeerConnectionFactory(std::move(pcf_deps));
@ -362,10 +369,11 @@ std::unique_ptr<TestPeer> TestPeerFactory::CreateTestPeer(
.MoveValue();
peer_connection->SetBitrate(params->bitrate_settings);
return absl::WrapUnique(new TestPeer(
peer_connection_factory, peer_connection, std::move(observer),
std::move(*params), std::move(*configurable_params),
std::move(video_sources), audio_processing, std::move(worker_thread)));
return absl::WrapUnique(
new TestPeer(peer_connection_factory, peer_connection,
std::move(observer), std::move(*params),
std::move(*configurable_params), std::move(video_sources),
audio_processing, std::move(owned_worker_thread)));
}
} // namespace webrtc_pc_e2e