Allow supplying a custom NetworkControllerInterfaceFactory per-Call in PeerConnectionDependencies

This requires making CallConfig move-only so it can hold a unique_ptr to
the factory, but as discussed with Danil, that seems fine.

Bug: chromium:355610792
Change-Id: Ie52e33faaa4a2af748daeb25f5327b7a532936e2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/357862
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tony Herre <herre@google.com>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42679}
This commit is contained in:
Tony Herre 2024-07-29 07:54:20 +02:00 committed by WebRTC LUCI CQ
parent d74d085dc5
commit 5079e8a30a
24 changed files with 85 additions and 59 deletions

View File

@ -39,8 +39,8 @@ class MediaFactoryImpl : public MediaFactory {
MediaFactoryImpl& operator=(const MediaFactoryImpl&) = delete;
~MediaFactoryImpl() override = default;
std::unique_ptr<Call> CreateCall(const CallConfig& config) override {
return webrtc::CreateCall(config);
std::unique_ptr<Call> CreateCall(CallConfig config) override {
return webrtc::CreateCall(std::move(config));
}
std::unique_ptr<MediaEngineInterface> CreateMediaEngine(

View File

@ -1392,6 +1392,10 @@ struct RTC_EXPORT PeerConnectionDependencies final {
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier;
std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
video_bitrate_allocator_factory;
// Optional network controller factory to use.
// Overrides that set in PeerConnectionFactoryDependencies.
std::unique_ptr<NetworkControllerFactoryInterface> network_controller_factory;
// Optional field trials to use.
// Overrides those from PeerConnectionFactoryDependencies.
std::unique_ptr<FieldTrialsView> trials;

View File

@ -48,13 +48,12 @@ void EnableMediaWithDefaultsAndTimeController(
absl::Nonnull<std::unique_ptr<MediaFactory>> media_factory)
: clock_(clock), media_factory_(std::move(media_factory)) {}
std::unique_ptr<Call> CreateCall(const CallConfig& config) override {
std::unique_ptr<Call> CreateCall(CallConfig config) override {
EnvironmentFactory env_factory(config.env);
env_factory.Set(clock_);
CallConfig config_with_custom_clock = config;
config_with_custom_clock.env = env_factory.Create();
return media_factory_->CreateCall(config_with_custom_clock);
config.env = env_factory.Create();
return media_factory_->CreateCall(std::move(config));
}
std::unique_ptr<cricket::MediaEngineInterface> CreateMediaEngine(

View File

@ -183,7 +183,7 @@ class Call final : public webrtc::Call,
public TargetTransferRateObserver,
public BitrateAllocator::LimitObserver {
public:
Call(const CallConfig& config,
Call(CallConfig config,
std::unique_ptr<RtpTransportControllerSendInterface> transport_send);
~Call() override;
@ -467,7 +467,7 @@ std::string Call::Stats::ToString(int64_t time_ms) const {
return ss.str();
}
std::unique_ptr<Call> Call::Create(const CallConfig& config) {
std::unique_ptr<Call> Call::Create(CallConfig config) {
std::unique_ptr<RtpTransportControllerSendInterface> transport_send;
if (config.rtp_transport_controller_send_factory != nullptr) {
transport_send = config.rtp_transport_controller_send_factory->Create(
@ -477,7 +477,8 @@ std::unique_ptr<Call> Call::Create(const CallConfig& config) {
config.ExtractTransportConfig());
}
return std::make_unique<internal::Call>(config, std::move(transport_send));
return std::make_unique<internal::Call>(std::move(config),
std::move(transport_send));
}
// This method here to avoid subclasses has to implement this method.
@ -643,7 +644,7 @@ void Call::SendStats::SetMinAllocatableRate(BitrateAllocationLimits limits) {
min_allocated_send_bitrate_bps_ = limits.min_allocatable_rate.bps();
}
Call::Call(const CallConfig& config,
Call::Call(CallConfig config,
std::unique_ptr<RtpTransportControllerSendInterface> transport_send)
: env_(config.env),
worker_thread_(GetCurrentTaskQueueOrThread()),
@ -660,7 +661,7 @@ Call::Call(const CallConfig& config,
num_cpu_cores_(CpuInfo::DetectNumberOfCores()),
call_stats_(new CallStats(&env_.clock(), worker_thread_)),
bitrate_allocator_(new BitrateAllocator(this)),
config_(config),
config_(std::move(config)),
audio_network_state_(kNetworkDown),
video_network_state_(kNetworkDown),
aggregate_network_up_(false),

View File

@ -55,7 +55,7 @@ class Call {
int64_t rtt_ms = -1;
};
static std::unique_ptr<Call> Create(const CallConfig& config);
static std::unique_ptr<Call> Create(CallConfig config);
virtual AudioSendStream* CreateAudioSendStream(
const AudioSendStream::Config& config) = 0;

View File

@ -20,12 +20,13 @@ CallConfig::CallConfig(const Environment& env,
: env(env),
network_task_queue_(network_task_queue) {}
CallConfig::CallConfig(const CallConfig& config) = default;
RtpTransportConfig CallConfig::ExtractTransportConfig() const {
RtpTransportConfig transport_config = {.env = env};
transport_config.bitrate_config = bitrate_config;
transport_config.network_controller_factory = network_controller_factory;
transport_config.network_controller_factory =
per_call_network_controller_factory
? per_call_network_controller_factory.get()
: network_controller_factory;
transport_config.network_state_predictor_factory =
network_state_predictor_factory;
transport_config.pacer_burst_interval = pacer_burst_interval;

View File

@ -10,6 +10,8 @@
#ifndef CALL_CALL_CONFIG_H_
#define CALL_CALL_CONFIG_H_
#include <memory>
#include "api/environment/environment.h"
#include "api/fec_controller.h"
#include "api/metronome/metronome.h"
@ -32,7 +34,9 @@ struct CallConfig {
explicit CallConfig(const Environment& env,
TaskQueueBase* network_task_queue = nullptr);
CallConfig(const CallConfig&);
// Move-only.
CallConfig(CallConfig&&) = default;
CallConfig& operator=(CallConfig&& other) = default;
~CallConfig();
@ -57,13 +61,18 @@ struct CallConfig {
NetworkStatePredictorFactoryInterface* network_state_predictor_factory =
nullptr;
// Network controller factory to use for this call.
// Call-specific Network controller factory to use. If this is set, it
// takes precedence over network_controller_factory.
std::unique_ptr<NetworkControllerFactoryInterface>
per_call_network_controller_factory;
// Network controller factory to use for this call if
// per_call_network_controller_factory is null.
NetworkControllerFactoryInterface* network_controller_factory = nullptr;
// NetEq factory to use for this call.
NetEqFactory* neteq_factory = nullptr;
TaskQueueBase* const network_task_queue_ = nullptr;
TaskQueueBase* network_task_queue_ = nullptr;
// RtpTransportControllerSend to use for this call.
RtpTransportControllerSendFactoryInterface*
rtp_transport_controller_send_factory = nullptr;

View File

@ -231,7 +231,7 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec,
sender_config.audio_state = audio_state;
CallConfig receiver_config = RecvCallConfig();
receiver_config.audio_state = audio_state;
CreateCalls(sender_config, receiver_config);
CreateCalls(std::move(sender_config), std::move(receiver_config));
std::copy_if(std::begin(payload_type_map_), std::end(payload_type_map_),
std::inserter(audio_pt_map, audio_pt_map.end()),

View File

@ -65,7 +65,7 @@ struct CallHelper {
rtc::make_ref_counted<MockAudioDeviceModule>();
CallConfig config(CreateEnvironment());
config.audio_state = AudioState::Create(audio_state_config);
call_ = Call::Create(config);
call_ = Call::Create(std::move(config));
}
Call* operator->() { return call_.get(); }

View File

@ -77,14 +77,14 @@ std::vector<TimeScopedNetworkConfig> GetNetworkConfigs(
} // namespace
std::unique_ptr<Call> CreateCall(const CallConfig& config) {
std::unique_ptr<Call> CreateCall(CallConfig config) {
std::vector<DegradedCall::TimeScopedNetworkConfig> send_degradation_configs =
GetNetworkConfigs(config.env.field_trials(), /*send=*/true);
std::vector<DegradedCall::TimeScopedNetworkConfig>
receive_degradation_configs =
GetNetworkConfigs(config.env.field_trials(), /*send=*/false);
std::unique_ptr<Call> call = Call::Create(config);
std::unique_ptr<Call> call = Call::Create(std::move(config));
if (!send_degradation_configs.empty() ||
!receive_degradation_configs.empty()) {

View File

@ -18,7 +18,7 @@
namespace webrtc {
std::unique_ptr<Call> CreateCall(const CallConfig& config);
std::unique_ptr<Call> CreateCall(CallConfig config);
} // namespace webrtc

View File

@ -1429,7 +1429,7 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
webrtc::Timestamp::Millis(4711));
CallConfig call_config(CreateEnvironment(
time_controller.CreateTaskQueueFactory(), time_controller.GetClock()));
const std::unique_ptr<Call> call = Call::Create(call_config);
const std::unique_ptr<Call> call = Call::Create(std::move(call_config));
// Create send channel.
const int send_ssrc = 123;

View File

@ -3883,7 +3883,7 @@ TEST(WebRtcVoiceEngineTest, SetRtpSendParametersMaxBitrate) {
webrtc::test::MockAudioDeviceModule::CreateNice();
call_config.audio_state = webrtc::AudioState::Create(config);
}
std::unique_ptr<Call> call = Call::Create(call_config);
std::unique_ptr<Call> call = Call::Create(std::move(call_config));
cricket::WebRtcVoiceSendChannel channel(
&engine, cricket::MediaConfig(), cricket::AudioOptions(),
webrtc::CryptoOptions(), call.get(), webrtc::AudioCodecPairId::Create());

View File

@ -34,7 +34,7 @@ class MediaFactory {
public:
virtual ~MediaFactory() = default;
virtual std::unique_ptr<Call> CreateCall(const CallConfig& config) = 0;
virtual std::unique_ptr<Call> CreateCall(CallConfig config) = 0;
virtual std::unique_ptr<cricket::MediaEngineInterface> CreateMediaEngine(
const Environment& env,
PeerConnectionFactoryDependencies& dependencies) = 0;

View File

@ -256,9 +256,13 @@ PeerConnectionFactory::CreatePeerConnectionOrError(
dependencies.allocator->SetNetworkIgnoreMask(options().network_ignore_mask);
dependencies.allocator->SetVpnList(configuration.vpn_list);
std::unique_ptr<Call> call =
worker_thread()->BlockingCall([this, &env, &configuration] {
return CreateCall_w(env, configuration);
std::unique_ptr<NetworkControllerFactoryInterface>
network_controller_factory =
std::move(dependencies.network_controller_factory);
std::unique_ptr<Call> call = worker_thread()->BlockingCall(
[this, &env, &configuration, &network_controller_factory] {
return CreateCall_w(env, std::move(configuration),
std::move(network_controller_factory));
});
auto result = PeerConnection::Create(env, context_, options_, std::move(call),
@ -305,7 +309,9 @@ rtc::scoped_refptr<AudioTrackInterface> PeerConnectionFactory::CreateAudioTrack(
std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
const Environment& env,
const PeerConnectionInterface::RTCConfiguration& configuration) {
const PeerConnectionInterface::RTCConfiguration& configuration,
std::unique_ptr<NetworkControllerFactoryInterface>
per_call_network_controller_factory) {
RTC_DCHECK_RUN_ON(worker_thread());
CallConfig call_config(env, network_thread());
@ -335,8 +341,12 @@ std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
network_state_predictor_factory_.get();
call_config.neteq_factory = neteq_factory_.get();
if (IsTrialEnabled("WebRTC-Bwe-InjectedCongestionController")) {
RTC_LOG(LS_INFO) << "Using injected network controller factory";
if (per_call_network_controller_factory != nullptr) {
RTC_LOG(LS_INFO) << "Using pc injected network controller factory";
call_config.per_call_network_controller_factory =
std::move(per_call_network_controller_factory);
} else if (IsTrialEnabled("WebRTC-Bwe-InjectedCongestionController")) {
RTC_LOG(LS_INFO) << "Using pcf injected network controller factory";
call_config.network_controller_factory =
injected_network_controller_factory_.get();
} else {
@ -348,7 +358,7 @@ std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
call_config.decode_metronome = decode_metronome_.get();
call_config.encode_metronome = encode_metronome_.get();
call_config.pacer_burst_interval = configuration.pacer_burst_interval;
return context_->call_factory()->CreateCall(call_config);
return context_->call_factory()->CreateCall(std::move(call_config));
}
bool PeerConnectionFactory::IsTrialEnabled(absl::string_view key) const {

View File

@ -133,7 +133,9 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface {
std::unique_ptr<Call> CreateCall_w(
const Environment& env,
const PeerConnectionInterface::RTCConfiguration& configuration);
const PeerConnectionInterface::RTCConfiguration& configuration,
std::unique_ptr<NetworkControllerFactoryInterface>
network_controller_factory);
rtc::scoped_refptr<ConnectionContext> context_;
PeerConnectionFactoryInterface::Options options_

View File

@ -36,8 +36,8 @@ void EnableFakeMedia(
absl::Nonnull<std::unique_ptr<FakeMediaEngine>> fake)
: fake_(std::move(fake)) {}
std::unique_ptr<Call> CreateCall(const CallConfig& config) override {
return Call::Create(config);
std::unique_ptr<Call> CreateCall(CallConfig config) override {
return Call::Create(std::move(config));
}
std::unique_ptr<MediaEngineInterface> CreateMediaEngine(

View File

@ -128,7 +128,7 @@ void CallTest::RunBaseTest(BaseTest* test) {
fake_send_audio_device_->RegisterAudioCallback(
send_config.audio_state->audio_transport());
}
CreateSenderCall(send_config);
CreateSenderCall(std::move(send_config));
if (test->ShouldCreateReceivers()) {
CallConfig recv_config = RecvCallConfig();
test->ModifyReceiverBitrateConfig(&recv_config.bitrate_config);
@ -141,7 +141,7 @@ void CallTest::RunBaseTest(BaseTest* test) {
fake_recv_audio_device_->RegisterAudioCallback(
recv_config.audio_state->audio_transport());
}
CreateReceiverCall(recv_config);
CreateReceiverCall(std::move(recv_config));
}
test->OnCallsCreated(sender_call_.get(), receiver_call_.get());
CreateReceiveTransport(test->GetReceiveTransportConfig(), test);
@ -235,22 +235,22 @@ void CallTest::CreateCalls() {
CreateCalls(SendCallConfig(), RecvCallConfig());
}
void CallTest::CreateCalls(const CallConfig& sender_config,
const CallConfig& receiver_config) {
CreateSenderCall(sender_config);
CreateReceiverCall(receiver_config);
void CallTest::CreateCalls(CallConfig sender_config,
CallConfig receiver_config) {
CreateSenderCall(std::move(sender_config));
CreateReceiverCall(std::move(receiver_config));
}
void CallTest::CreateSenderCall() {
CreateSenderCall(SendCallConfig());
}
void CallTest::CreateSenderCall(const CallConfig& config) {
sender_call_ = Call::Create(config);
void CallTest::CreateSenderCall(CallConfig config) {
sender_call_ = Call::Create(std::move(config));
}
void CallTest::CreateReceiverCall(const CallConfig& config) {
receiver_call_ = Call::Create(config);
void CallTest::CreateReceiverCall(CallConfig config) {
receiver_call_ = Call::Create(std::move(config));
}
void CallTest::DestroyCalls() {

View File

@ -72,11 +72,10 @@ class CallTest : public ::testing::Test, public RtpPacketSinkInterface {
CallConfig RecvCallConfig() const;
void CreateCalls();
void CreateCalls(const CallConfig& sender_config,
const CallConfig& receiver_config);
void CreateCalls(CallConfig sender_config, CallConfig receiver_config);
void CreateSenderCall();
void CreateSenderCall(const CallConfig& config);
void CreateReceiverCall(const CallConfig& config);
void CreateSenderCall(CallConfig config);
void CreateReceiverCall(CallConfig config);
void DestroyCalls();
void CreateVideoSendConfig(VideoSendStream::Config* video_config,

View File

@ -73,7 +73,7 @@ void RtpReplayer::Replay(
// Setup the video streams based on the configuration.
CallConfig call_config(CreateEnvironment());
std::unique_ptr<Call> call(Call::Create(call_config));
std::unique_ptr<Call> call(Call::Create(std::move(call_config)));
SetupVideoStreams(&receive_stream_configs, stream_state.get(), call.get());
// Start replaying the provided stream now that it has been configured.

View File

@ -75,7 +75,7 @@ std::unique_ptr<Call> CreateCall(
config.transport.rates.start_rate.bps();
call_config.network_controller_factory = network_controller_factory;
call_config.audio_state = audio_state;
return Call::Create(call_config);
return Call::Create(std::move(call_config));
}
std::unique_ptr<RtcEventLog> CreateEventLog(

View File

@ -48,7 +48,8 @@ void MultiStreamTester::RunTest() {
// to make test more stable.
auto task_queue = env.task_queue_factory().CreateTaskQueue(
"TaskQueue", TaskQueueFactory::Priority::HIGH);
CallConfig config(env);
CallConfig sender_config(env);
CallConfig receiver_config(env);
std::unique_ptr<Call> sender_call;
std::unique_ptr<Call> receiver_call;
std::unique_ptr<test::DirectTransport> sender_transport;
@ -66,8 +67,8 @@ void MultiStreamTester::RunTest() {
InternalDecoderFactory decoder_factory;
SendTask(task_queue.get(), [&]() {
sender_call = Call::Create(config);
receiver_call = Call::Create(config);
sender_call = Call::Create(std::move(sender_config));
receiver_call = Call::Create(std::move(receiver_config));
sender_transport = CreateSendTransport(task_queue.get(), sender_call.get());
receiver_transport =
CreateReceiveTransport(task_queue.get(), receiver_call.get());

View File

@ -527,8 +527,8 @@ TEST_F(StatsEndToEndTest, MAYBE_ContentTypeSwitches) {
SendTask(task_queue(), [this, &test, &send_config, &recv_config,
&encoder_config_with_screenshare]() {
CreateSenderCall(send_config);
CreateReceiverCall(recv_config);
CreateSenderCall(std::move(send_config));
CreateReceiverCall(std::move(recv_config));
CreateReceiveTransport(test.GetReceiveTransportConfig(), &test);
CreateSendTransport(test.GetReceiveTransportConfig(), &test);

View File

@ -1241,7 +1241,7 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
InitializeAudioDevice(&send_call_config, &recv_call_config,
params_.audio.use_real_adm);
CreateCalls(send_call_config, recv_call_config);
CreateCalls(std::move(send_call_config), std::move(recv_call_config));
send_transport = CreateSendTransport();
recv_transport = CreateReceiveTransport();
});
@ -1468,7 +1468,7 @@ void VideoQualityTest::RunWithRenderers(const Params& params) {
InitializeAudioDevice(&send_call_config, &recv_call_config,
params_.audio.use_real_adm);
CreateCalls(send_call_config, recv_call_config);
CreateCalls(std::move(send_call_config), std::move(recv_call_config));
// TODO(minyue): consider if this is a good transport even for audio only
// calls.