diff --git a/api/BUILD.gn b/api/BUILD.gn index c257a7d6e0..5e5172fb6e 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -55,6 +55,7 @@ if (!build_with_chromium) { "audio:audio_mixer_api", "audio_codecs:audio_codecs_api", "task_queue:default_task_queue_factory", + "transport:field_trial_based_config", "video_codecs:video_codecs_api", ] } diff --git a/api/create_peerconnection_factory.cc b/api/create_peerconnection_factory.cc index 6223150079..6eba7d4571 100644 --- a/api/create_peerconnection_factory.cc +++ b/api/create_peerconnection_factory.cc @@ -18,6 +18,7 @@ #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/scoped_refptr.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "media/base/media_engine.h" #include "media/engine/webrtc_media_engine.h" #include "modules/audio_device/include/audio_device.h" @@ -45,6 +46,7 @@ rtc::scoped_refptr CreatePeerConnectionFactory( dependencies.call_factory = CreateCallFactory(); dependencies.event_log_factory = std::make_unique( dependencies.task_queue_factory.get()); + dependencies.trials = std::make_unique(); cricket::MediaEngineDependencies media_dependencies; media_dependencies.task_queue_factory = dependencies.task_queue_factory.get(); @@ -59,6 +61,7 @@ rtc::scoped_refptr CreatePeerConnectionFactory( media_dependencies.audio_mixer = std::move(audio_mixer); media_dependencies.video_encoder_factory = std::move(video_encoder_factory); media_dependencies.video_decoder_factory = std::move(video_decoder_factory); + media_dependencies.trials = dependencies.trials.get(); dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_dependencies)); diff --git a/call/call.cc b/call/call.cc index f53f779737..e814cff5b6 100644 --- a/call/call.cc +++ b/call/call.cc @@ -260,6 +260,8 @@ class Call final : public webrtc::Call, Stats GetStats() const override; + const WebRtcKeyValueConfig& trials() const override; + // Implements PacketReceiver. DeliveryStatus DeliverPacket(MediaType media_type, rtc::CopyOnWriteBuffer packet, @@ -1112,6 +1114,10 @@ Call::Stats Call::GetStats() const { return stats; } +const WebRtcKeyValueConfig& Call::trials() const { + return *config_.trials; +} + void Call::SignalChannelNetworkState(MediaType media, NetworkState state) { RTC_DCHECK_RUN_ON(worker_thread_); switch (media) { diff --git a/call/call.h b/call/call.h index 75272248c4..a2b3b89598 100644 --- a/call/call.h +++ b/call/call.h @@ -156,6 +156,8 @@ class Call { virtual void SetClientBitratePreferences( const BitrateSettings& preferences) = 0; + virtual const WebRtcKeyValueConfig& trials() const = 0; + virtual ~Call() {} }; diff --git a/call/degraded_call.cc b/call/degraded_call.cc index 007e0af360..0cd43018ac 100644 --- a/call/degraded_call.cc +++ b/call/degraded_call.cc @@ -266,6 +266,10 @@ Call::Stats DegradedCall::GetStats() const { return call_->GetStats(); } +const WebRtcKeyValueConfig& DegradedCall::trials() const { + return call_->trials(); +} + void DegradedCall::SignalChannelNetworkState(MediaType media, NetworkState state) { call_->SignalChannelNetworkState(media, state); diff --git a/call/degraded_call.h b/call/degraded_call.h index ac072b7159..d81c65c570 100644 --- a/call/degraded_call.h +++ b/call/degraded_call.h @@ -85,6 +85,8 @@ class DegradedCall : public Call, private PacketReceiver { Stats GetStats() const override; + const WebRtcKeyValueConfig& trials() const override; + void SignalChannelNetworkState(MediaType media, NetworkState state) override; void OnAudioTransportOverheadChanged( int transport_overhead_per_packet) override; diff --git a/media/BUILD.gn b/media/BUILD.gn index 284cd45714..41f3532adb 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -93,6 +93,7 @@ rtc_library("rtc_media_base") { "../api/crypto:frame_encryptor_interface", "../api/crypto:options", "../api/transport:stun_types", + "../api/transport:webrtc_key_value_config", "../api/transport/rtp:rtp_source", "../api/video:video_bitrate_allocation", "../api/video:video_bitrate_allocator_factory", @@ -287,6 +288,8 @@ rtc_library("rtc_audio_video") { "../api/audio_codecs:audio_codecs_api", "../api/task_queue", "../api/transport:bitrate_settings", + "../api/transport:field_trial_based_config", + "../api/transport:webrtc_key_value_config", "../api/transport/rtp:rtp_source", "../api/units:data_rate", "../api/video:video_bitrate_allocation", @@ -324,7 +327,6 @@ rtc_library("rtc_audio_video") { "../rtc_base/system:rtc_export", "../rtc_base/third_party/base64", "../system_wrappers", - "../system_wrappers:field_trial", "../system_wrappers:metrics", ] absl_deps = [ @@ -456,6 +458,7 @@ if (rtc_include_tests) { "../api:call_api", "../api:fec_controller_api", "../api:scoped_refptr", + "../api/transport:field_trial_based_config", "../api/video:encoded_image", "../api/video:video_bitrate_allocation", "../api/video:video_frame", diff --git a/media/base/media_engine.cc b/media/base/media_engine.cc index 8050258728..36a9694cfb 100644 --- a/media/base/media_engine.cc +++ b/media/base/media_engine.cc @@ -161,11 +161,20 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( } CompositeMediaEngine::CompositeMediaEngine( - std::unique_ptr voice_engine, + std::unique_ptr trials, + std::unique_ptr audio_engine, std::unique_ptr video_engine) - : voice_engine_(std::move(voice_engine)), + : trials_(std::move(trials)), + voice_engine_(std::move(audio_engine)), video_engine_(std::move(video_engine)) {} +CompositeMediaEngine::CompositeMediaEngine( + std::unique_ptr audio_engine, + std::unique_ptr video_engine) + : CompositeMediaEngine(nullptr, + std::move(audio_engine), + std::move(video_engine)) {} + CompositeMediaEngine::~CompositeMediaEngine() = default; bool CompositeMediaEngine::Init() { diff --git a/media/base/media_engine.h b/media/base/media_engine.h index 4d9cc56a16..1d8917cfcb 100644 --- a/media/base/media_engine.h +++ b/media/base/media_engine.h @@ -19,6 +19,7 @@ #include "api/audio_codecs/audio_encoder_factory.h" #include "api/crypto/crypto_options.h" #include "api/rtp_parameters.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/video/video_bitrate_allocator_factory.h" #include "call/audio_state.h" #include "media/base/codec.h" @@ -131,8 +132,12 @@ class MediaEngineInterface { // CompositeMediaEngine constructs a MediaEngine from separate // voice and video engine classes. +// Optionally owns a WebRtcKeyValueConfig trials map. class CompositeMediaEngine : public MediaEngineInterface { public: + CompositeMediaEngine(std::unique_ptr trials, + std::unique_ptr audio_engine, + std::unique_ptr video_engine); CompositeMediaEngine(std::unique_ptr audio_engine, std::unique_ptr video_engine); ~CompositeMediaEngine() override; @@ -144,6 +149,7 @@ class CompositeMediaEngine : public MediaEngineInterface { const VideoEngineInterface& video() const override; private: + const std::unique_ptr trials_; std::unique_ptr voice_engine_; std::unique_ptr video_engine_; }; diff --git a/media/engine/fake_webrtc_call.h b/media/engine/fake_webrtc_call.h index d134163dcb..385bbcd76d 100644 --- a/media/engine/fake_webrtc_call.h +++ b/media/engine/fake_webrtc_call.h @@ -24,6 +24,7 @@ #include #include +#include "api/transport/field_trial_based_config.h" #include "api/video/video_frame.h" #include "call/audio_receive_stream.h" #include "call/audio_send_stream.h" @@ -362,6 +363,10 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { webrtc::Call::Stats GetStats() const override; + const webrtc::WebRtcKeyValueConfig& trials() const override { + return trials_; + } + void SignalChannelNetworkState(webrtc::MediaType media, webrtc::NetworkState state) override; void OnAudioTransportOverheadChanged( @@ -385,6 +390,7 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { int num_created_send_streams_; int num_created_receive_streams_; + webrtc::FieldTrialBasedConfig trials_; }; } // namespace cricket diff --git a/media/engine/null_webrtc_video_engine_unittest.cc b/media/engine/null_webrtc_video_engine_unittest.cc index 832bf8ad1a..a11c207baa 100644 --- a/media/engine/null_webrtc_video_engine_unittest.cc +++ b/media/engine/null_webrtc_video_engine_unittest.cc @@ -15,6 +15,7 @@ #include "api/task_queue/default_task_queue_factory.h" #include "api/task_queue/task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "media/engine/webrtc_voice_engine.h" #include "modules/audio_device/include/mock_audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -31,11 +32,12 @@ TEST(NullWebRtcVideoEngineTest, CheckInterface) { webrtc::CreateDefaultTaskQueueFactory(); rtc::scoped_refptr adm = webrtc::test::MockAudioDeviceModule::CreateNice(); + webrtc::FieldTrialBasedConfig trials; auto audio_engine = std::make_unique( task_queue_factory.get(), adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, - webrtc::AudioProcessingBuilder().Create()); + webrtc::AudioProcessingBuilder().Create(), trials); CompositeMediaEngine engine(std::move(audio_engine), std::make_unique()); diff --git a/media/engine/simulcast.cc b/media/engine/simulcast.cc index 6e63ec6f7f..6d64bfa7b8 100644 --- a/media/engine/simulcast.cc +++ b/media/engine/simulcast.cc @@ -16,6 +16,7 @@ #include #include +#include "absl/strings/match.h" #include "absl/types/optional.h" #include "api/video/video_codec_constants.h" #include "media/base/media_constants.h" @@ -26,7 +27,6 @@ #include "rtc_base/experiments/normalize_simulcast_size_experiment.h" #include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/logging.h" -#include "system_wrappers/include/field_trial.h" namespace cricket { @@ -103,7 +103,9 @@ constexpr const SimulcastFormat kSimulcastFormats[] = { const int kMaxScreenshareSimulcastLayers = 2; // Multiway: Number of temporal layers for each simulcast stream. -int DefaultNumberOfTemporalLayers(int simulcast_id, bool screenshare) { +int DefaultNumberOfTemporalLayers(int simulcast_id, + bool screenshare, + const webrtc::WebRtcKeyValueConfig& trials) { RTC_CHECK_GE(simulcast_id, 0); RTC_CHECK_LT(simulcast_id, webrtc::kMaxSimulcastStreams); @@ -114,10 +116,8 @@ int DefaultNumberOfTemporalLayers(int simulcast_id, bool screenshare) { : kDefaultNumTemporalLayers; const std::string group_name = - screenshare ? webrtc::field_trial::FindFullName( - "WebRTC-VP8ScreenshareTemporalLayers") - : webrtc::field_trial::FindFullName( - "WebRTC-VP8ConferenceTemporalLayers"); + screenshare ? trials.Lookup("WebRTC-VP8ScreenshareTemporalLayers") + : trials.Lookup("WebRTC-VP8ConferenceTemporalLayers"); if (group_name.empty()) return default_num_temporal_layers; @@ -231,9 +231,10 @@ webrtc::DataRate GetTotalMaxBitrate( size_t LimitSimulcastLayerCount(int width, int height, size_t need_layers, - size_t layer_count) { - if (!webrtc::field_trial::IsDisabled( - kUseLegacySimulcastLayerLimitFieldTrial)) { + size_t layer_count, + const webrtc::WebRtcKeyValueConfig& trials) { + if (!absl::StartsWith(trials.Lookup(kUseLegacySimulcastLayerLimitFieldTrial), + "Disabled")) { size_t adaptive_layer_count = std::max( need_layers, kSimulcastFormats[FindSimulcastFormatIndex(width, height)].max_layers); @@ -254,27 +255,28 @@ std::vector GetSimulcastConfig( double bitrate_priority, int max_qp, bool is_screenshare_with_conference_mode, - bool temporal_layers_supported) { + bool temporal_layers_supported, + const webrtc::WebRtcKeyValueConfig& trials) { RTC_DCHECK_LE(min_layers, max_layers); RTC_DCHECK(max_layers > 1 || is_screenshare_with_conference_mode); const bool base_heavy_tl3_rate_alloc = - webrtc::RateControlSettings::ParseFromFieldTrials() + webrtc::RateControlSettings::ParseFromKeyValueConfig(&trials) .Vp8BaseHeavyTl3RateAllocation(); if (is_screenshare_with_conference_mode) { return GetScreenshareLayers(max_layers, width, height, bitrate_priority, max_qp, temporal_layers_supported, - base_heavy_tl3_rate_alloc); + base_heavy_tl3_rate_alloc, trials); } else { // Some applications rely on the old behavior limiting the simulcast layer // count based on the resolution automatically, which they can get through // the WebRTC-LegacySimulcastLayerLimit field trial until they update. max_layers = - LimitSimulcastLayerCount(width, height, min_layers, max_layers); + LimitSimulcastLayerCount(width, height, min_layers, max_layers, trials); return GetNormalSimulcastLayers(max_layers, width, height, bitrate_priority, max_qp, temporal_layers_supported, - base_heavy_tl3_rate_alloc); + base_heavy_tl3_rate_alloc, trials); } } @@ -285,7 +287,8 @@ std::vector GetNormalSimulcastLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc) { + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials) { std::vector layers(layer_count); // Format width and height has to be divisible by |2 ^ num_simulcast_layers - @@ -300,11 +303,13 @@ std::vector GetNormalSimulcastLayers( // TODO(pbos): Fill actual temporal-layer bitrate thresholds. layers[s].max_qp = max_qp; layers[s].num_temporal_layers = - temporal_layers_supported ? DefaultNumberOfTemporalLayers(s, false) : 1; + temporal_layers_supported + ? DefaultNumberOfTemporalLayers(s, false, trials) + : 1; layers[s].max_bitrate_bps = FindSimulcastMaxBitrate(width, height).bps(); layers[s].target_bitrate_bps = FindSimulcastTargetBitrate(width, height).bps(); - int num_temporal_layers = DefaultNumberOfTemporalLayers(s, false); + int num_temporal_layers = DefaultNumberOfTemporalLayers(s, false, trials); if (s == 0) { // If alternative temporal rate allocation is selected, adjust the // bitrate of the lowest simulcast stream so that absolute bitrate for @@ -356,7 +361,8 @@ std::vector GetScreenshareLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc) { + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials) { auto max_screenshare_layers = kMaxScreenshareSimulcastLayers; size_t num_simulcast_layers = std::min(max_layers, max_screenshare_layers); @@ -379,7 +385,8 @@ std::vector GetScreenshareLayers( // restrictions. The base simulcast layer will still use legacy setup. if (num_simulcast_layers == kMaxScreenshareSimulcastLayers) { // Add optional upper simulcast layer. - const int num_temporal_layers = DefaultNumberOfTemporalLayers(1, true); + const int num_temporal_layers = + DefaultNumberOfTemporalLayers(1, true, trials); int max_bitrate_bps; bool using_boosted_bitrate = false; if (!temporal_layers_supported) { @@ -389,7 +396,7 @@ std::vector GetScreenshareLayers( kScreenshareHighStreamMaxBitrate.bps() * webrtc::SimulcastRateAllocator::GetTemporalRateAllocation( num_temporal_layers, 0, base_heavy_tl3_rate_alloc)); - } else if (DefaultNumberOfTemporalLayers(1, true) != 3 || + } else if (DefaultNumberOfTemporalLayers(1, true, trials) != 3 || base_heavy_tl3_rate_alloc) { // Experimental temporal layer mode used, use increased max bitrate. max_bitrate_bps = kScreenshareHighStreamMaxBitrate.bps(); @@ -409,7 +416,9 @@ std::vector GetScreenshareLayers( layers[1].max_qp = max_qp; layers[1].max_framerate = kDefaultVideoMaxFramerate; layers[1].num_temporal_layers = - temporal_layers_supported ? DefaultNumberOfTemporalLayers(1, true) : 1; + temporal_layers_supported + ? DefaultNumberOfTemporalLayers(1, true, trials) + : 1; layers[1].min_bitrate_bps = using_boosted_bitrate ? kScreenshareHighStreamMinBitrate.bps() : layers[0].target_bitrate_bps * 2; diff --git a/media/engine/simulcast.h b/media/engine/simulcast.h index 28b08560aa..5defa525dc 100644 --- a/media/engine/simulcast.h +++ b/media/engine/simulcast.h @@ -15,6 +15,7 @@ #include +#include "api/transport/webrtc_key_value_config.h" #include "api/units/data_rate.h" #include "api/video_codecs/video_encoder_config.h" @@ -41,7 +42,8 @@ std::vector GetSimulcastConfig( double bitrate_priority, int max_qp, bool is_screenshare_with_conference_mode, - bool temporal_layers_supported); + bool temporal_layers_supported, + const webrtc::WebRtcKeyValueConfig& trials); // Gets the simulcast config layers for a non-screensharing case. std::vector GetNormalSimulcastLayers( @@ -51,7 +53,8 @@ std::vector GetNormalSimulcastLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc); + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials); // Gets simulcast config layers for screenshare settings. std::vector GetScreenshareLayers( @@ -61,7 +64,8 @@ std::vector GetScreenshareLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc); + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials); } // namespace cricket diff --git a/media/engine/simulcast_unittest.cc b/media/engine/simulcast_unittest.cc index 0ce388a9ee..2c722727dc 100644 --- a/media/engine/simulcast_unittest.cc +++ b/media/engine/simulcast_unittest.cc @@ -10,6 +10,7 @@ #include "media/engine/simulcast.h" +#include "api/transport/field_trial_based_config.h" #include "media/base/media_constants.h" #include "media/engine/constants.h" #include "test/field_trial.h" @@ -80,12 +81,13 @@ TEST(SimulcastTest, BandwidthAboveTotalMaxBitrateGivenToHighestStream) { TEST(SimulcastTest, GetConfig) { const std::vector kExpected = GetSimulcastBitrates720p(); + const FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 3; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 1280, 720, kBitratePriority, kQpMax, - !kScreenshare, true); + !kScreenshare, true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(320u, streams[0].width); @@ -113,6 +115,7 @@ TEST(SimulcastTest, GetConfig) { TEST(SimulcastTest, GetConfigWithBaseHeavyVP8TL3RateAllocation) { test::ScopedFieldTrials field_trials( "WebRTC-UseBaseHeavyVP8TL3RateAllocation/Enabled/"); + FieldTrialBasedConfig trials; const std::vector kExpected = GetSimulcastBitrates720p(); @@ -120,7 +123,7 @@ TEST(SimulcastTest, GetConfigWithBaseHeavyVP8TL3RateAllocation) { const size_t kMaxLayers = 3; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 1280, 720, kBitratePriority, kQpMax, - !kScreenshare, true); + !kScreenshare, true, trials); EXPECT_EQ(kExpected[0].min_bitrate_bps, streams[0].min_bitrate_bps); EXPECT_EQ(static_cast(0.4 * kExpected[0].target_bitrate_bps / 0.6), @@ -137,9 +140,10 @@ TEST(SimulcastTest, GetConfigWithBaseHeavyVP8TL3RateAllocation) { TEST(SimulcastTest, GetConfigWithLimitedMaxLayers) { const size_t kMinLayers = 1; const size_t kMaxLayers = 2; + FieldTrialBasedConfig trials; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 1280, 720, kBitratePriority, kQpMax, - !kScreenshare, true); + !kScreenshare, true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(640u, streams[0].width); @@ -151,11 +155,12 @@ TEST(SimulcastTest, GetConfigWithLimitedMaxLayers) { TEST(SimulcastTest, GetConfigWithLimitedMaxLayersForResolution) { test::ScopedFieldTrials field_trials( "WebRTC-LegacySimulcastLayerLimit/Enabled/"); + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 3; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 800, 600, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(2u, streams.size()); EXPECT_EQ(400u, streams[0].width); @@ -167,11 +172,12 @@ TEST(SimulcastTest, GetConfigWithLimitedMaxLayersForResolution) { TEST(SimulcastTest, GetConfigWithLowResolutionScreenshare) { test::ScopedFieldTrials field_trials( "WebRTC-LegacySimulcastLayerLimit/Enabled/"); + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 3; - std::vector streams = - cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 100, 100, - kBitratePriority, kQpMax, kScreenshare, true); + std::vector streams = cricket::GetSimulcastConfig( + kMinLayers, kMaxLayers, 100, 100, kBitratePriority, kQpMax, kScreenshare, + true, trials); // Simulcast streams number is never decreased for screenshare, // even for very low resolution. @@ -181,11 +187,12 @@ TEST(SimulcastTest, GetConfigWithLowResolutionScreenshare) { TEST(SimulcastTest, GetConfigWithNotLimitedMaxLayersForResolution) { test::ScopedFieldTrials field_trials( "WebRTC-LegacySimulcastLayerLimit/Disabled/"); + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 3; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 800, 600, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(200u, streams[0].width); @@ -197,11 +204,12 @@ TEST(SimulcastTest, GetConfigWithNotLimitedMaxLayersForResolution) { } TEST(SimulcastTest, GetConfigWithNormalizedResolution) { + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 2; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 640 + 1, 360 + 1, kBitratePriority, kQpMax, - !kScreenshare, true); + !kScreenshare, true, trials); // Must be divisible by |2 ^ (num_layers - 1)|. EXPECT_EQ(kMaxLayers, streams.size()); @@ -214,12 +222,13 @@ TEST(SimulcastTest, GetConfigWithNormalizedResolution) { TEST(SimulcastTest, GetConfigWithNormalizedResolutionDivisibleBy4) { test::ScopedFieldTrials field_trials( "WebRTC-NormalizeSimulcastResolution/Enabled-2/"); + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 2; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 709, 501, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); // Must be divisible by |2 ^ 2|. EXPECT_EQ(kMaxLayers, streams.size()); @@ -232,12 +241,13 @@ TEST(SimulcastTest, GetConfigWithNormalizedResolutionDivisibleBy4) { TEST(SimulcastTest, GetConfigWithNormalizedResolutionDivisibleBy8) { test::ScopedFieldTrials field_trials( "WebRTC-NormalizeSimulcastResolution/Enabled-3/"); + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 2; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 709, 501, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); // Must be divisible by |2 ^ 3|. EXPECT_EQ(kMaxLayers, streams.size()); @@ -250,53 +260,56 @@ TEST(SimulcastTest, GetConfigWithNormalizedResolutionDivisibleBy8) { TEST(SimulcastTest, GetConfigForLegacyLayerLimit) { test::ScopedFieldTrials field_trials( "WebRTC-LegacySimulcastLayerLimit/Enabled/"); + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const int kMaxLayers = 3; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 320, 180, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(1u, streams.size()); streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 640, 360, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(2u, streams.size()); streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 1920, 1080, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(3u, streams.size()); } TEST(SimulcastTest, GetConfigForLegacyLayerLimitWithRequiredHD) { test::ScopedFieldTrials field_trials( "WebRTC-LegacySimulcastLayerLimit/Enabled/"); + FieldTrialBasedConfig trials; const size_t kMinLayers = 3; // "HD" layer must be present! const int kMaxLayers = 3; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 320, 180, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(3u, streams.size()); streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 640, 360, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(3u, streams.size()); streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 1920, 1080, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(3u, streams.size()); } TEST(SimulcastTest, GetConfigForScreenshareSimulcast) { + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 3; - std::vector streams = - cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 1400, 800, - kBitratePriority, kQpMax, kScreenshare, true); + std::vector streams = cricket::GetSimulcastConfig( + kMinLayers, kMaxLayers, 1400, 800, kBitratePriority, kQpMax, kScreenshare, + true, trials); EXPECT_GT(streams.size(), 1u); for (size_t i = 0; i < streams.size(); ++i) { @@ -313,11 +326,12 @@ TEST(SimulcastTest, GetConfigForScreenshareSimulcast) { } TEST(SimulcastTest, GetConfigForScreenshareSimulcastWithLimitedMaxLayers) { + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 1; - std::vector streams = - cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 1400, 800, - kBitratePriority, kQpMax, kScreenshare, true); + std::vector streams = cricket::GetSimulcastConfig( + kMinLayers, kMaxLayers, 1400, 800, kBitratePriority, kQpMax, kScreenshare, + true, trials); EXPECT_EQ(kMaxLayers, streams.size()); } @@ -326,22 +340,23 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) { constexpr int kScreenshareHighStreamMinBitrateBps = 600000; constexpr int kScreenshareHighStreamMaxBitrateBps = 1250000; constexpr int kMaxBitrate960_540 = 1200000; + FieldTrialBasedConfig trials; // Normal case, max bitrate not limited by resolution. const size_t kMinLayers = 1; const size_t kMaxLayers = 2; - std::vector streams = - cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 1920, 1080, - kBitratePriority, kQpMax, kScreenshare, true); + std::vector streams = cricket::GetSimulcastConfig( + kMinLayers, kMaxLayers, 1920, 1080, kBitratePriority, kQpMax, + kScreenshare, true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(streams[1].max_bitrate_bps, kScreenshareHighStreamMaxBitrateBps); EXPECT_EQ(streams[1].min_bitrate_bps, kScreenshareHighStreamMinBitrateBps); EXPECT_GE(streams[1].max_bitrate_bps, streams[1].min_bitrate_bps); // At 960x540, the max bitrate is limited to 900kbps. - streams = - cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 540, - kBitratePriority, kQpMax, kScreenshare, true); + streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 540, + kBitratePriority, kQpMax, kScreenshare, + true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(streams[1].max_bitrate_bps, kMaxBitrate960_540); EXPECT_EQ(streams[1].min_bitrate_bps, kScreenshareHighStreamMinBitrateBps); @@ -349,9 +364,9 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) { // At 480x270, the max bitrate is limited to 450kbps. This is lower than // the min bitrate, so use that as a lower bound. - streams = - cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 270, - kBitratePriority, kQpMax, kScreenshare, true); + streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 270, + kBitratePriority, kQpMax, kScreenshare, + true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(streams[1].max_bitrate_bps, kScreenshareHighStreamMinBitrateBps); EXPECT_EQ(streams[1].min_bitrate_bps, kScreenshareHighStreamMinBitrateBps); @@ -359,11 +374,12 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) { } TEST(SimulcastTest, AveragesBitratesForNonStandardResolution) { + FieldTrialBasedConfig trials; const size_t kMinLayers = 1; const size_t kMaxLayers = 3; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, 900, 800, kBitratePriority, kQpMax, !kScreenshare, - true); + true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(900u, streams[2].width); @@ -380,10 +396,11 @@ TEST(SimulcastTest, BitratesForCloseToStandardResolution) { const size_t kWidth = 1280; const size_t kHeight = 716; const std::vector kExpectedNear = GetSimulcastBitrates720p(); + FieldTrialBasedConfig trials; std::vector streams = cricket::GetSimulcastConfig( kMinLayers, kMaxLayers, kWidth, kHeight, kBitratePriority, kQpMax, - !kScreenshare, true); + !kScreenshare, true, trials); EXPECT_EQ(kMaxLayers, streams.size()); EXPECT_EQ(kWidth, streams[2].width); diff --git a/media/engine/webrtc_media_engine.cc b/media/engine/webrtc_media_engine.cc index b026b9d7c7..23353acfbd 100644 --- a/media/engine/webrtc_media_engine.cc +++ b/media/engine/webrtc_media_engine.cc @@ -14,8 +14,8 @@ #include #include "absl/algorithm/container.h" +#include "absl/strings/match.h" #include "media/engine/webrtc_voice_engine.h" -#include "system_wrappers/include/field_trial.h" #ifdef HAVE_WEBRTC_VIDEO #include "media/engine/webrtc_video_engine.h" @@ -27,20 +27,27 @@ namespace cricket { std::unique_ptr CreateMediaEngine( MediaEngineDependencies dependencies) { + // TODO(sprang): Make populating |dependencies.trials| mandatory and remove + // these fallbacks. + std::unique_ptr fallback_trials( + dependencies.trials ? nullptr : new webrtc::FieldTrialBasedConfig()); + const webrtc::WebRtcKeyValueConfig& trials = + dependencies.trials ? *dependencies.trials : *fallback_trials; auto audio_engine = std::make_unique( dependencies.task_queue_factory, std::move(dependencies.adm), std::move(dependencies.audio_encoder_factory), std::move(dependencies.audio_decoder_factory), std::move(dependencies.audio_mixer), - std::move(dependencies.audio_processing)); + std::move(dependencies.audio_processing), trials); #ifdef HAVE_WEBRTC_VIDEO auto video_engine = std::make_unique( std::move(dependencies.video_encoder_factory), - std::move(dependencies.video_decoder_factory)); + std::move(dependencies.video_decoder_factory), trials); #else auto video_engine = std::make_unique(); #endif - return std::make_unique(std::move(audio_engine), + return std::make_unique(std::move(fallback_trials), + std::move(audio_engine), std::move(video_engine)); } @@ -87,7 +94,8 @@ bool ValidateRtpExtensions( std::vector FilterRtpExtensions( const std::vector& extensions, bool (*supported)(absl::string_view), - bool filter_redundant_extensions) { + bool filter_redundant_extensions, + const webrtc::WebRtcKeyValueConfig& trials) { RTC_DCHECK(ValidateRtpExtensions(extensions)); RTC_DCHECK(supported); std::vector result; @@ -121,7 +129,8 @@ std::vector FilterRtpExtensions( result.erase(it, result.end()); // Keep just the highest priority extension of any in the following lists. - if (webrtc::field_trial::IsEnabled("WebRTC-FilterAbsSendTimeExtension")) { + if (absl::StartsWith(trials.Lookup("WebRTC-FilterAbsSendTimeExtension"), + "Enabled")) { static const char* const kBweExtensionPriorities[] = { webrtc::RtpExtension::kTransportSequenceNumberUri, webrtc::RtpExtension::kAbsSendTimeUri, diff --git a/media/engine/webrtc_media_engine.h b/media/engine/webrtc_media_engine.h index dbb2a5fbb0..1511d4b574 100644 --- a/media/engine/webrtc_media_engine.h +++ b/media/engine/webrtc_media_engine.h @@ -21,6 +21,7 @@ #include "api/rtp_parameters.h" #include "api/task_queue/task_queue_factory.h" #include "api/transport/bitrate_settings.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_encoder_factory.h" #include "media/base/codec.h" @@ -48,6 +49,8 @@ struct MediaEngineDependencies { std::unique_ptr video_encoder_factory; std::unique_ptr video_decoder_factory; + + const webrtc::WebRtcKeyValueConfig* trials = nullptr; }; // CreateMediaEngine may be called on any thread, though the engine is @@ -66,7 +69,8 @@ bool ValidateRtpExtensions(const std::vector& extensions); std::vector FilterRtpExtensions( const std::vector& extensions, bool (*supported)(absl::string_view), - bool filter_redundant_extensions); + bool filter_redundant_extensions, + const webrtc::WebRtcKeyValueConfig& trials); webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec); diff --git a/media/engine/webrtc_media_engine_unittest.cc b/media/engine/webrtc_media_engine_unittest.cc index 005a2d46be..78d13fc297 100644 --- a/media/engine/webrtc_media_engine_unittest.cc +++ b/media/engine/webrtc_media_engine_unittest.cc @@ -13,6 +13,7 @@ #include #include +#include "api/transport/field_trial_based_config.h" #include "media/engine/webrtc_media_engine_defaults.h" #include "test/field_trial.h" #include "test/gtest.h" @@ -101,15 +102,17 @@ TEST(WebRtcMediaEngineTest, ValidateRtpExtensions_OverlappingIds_EndOfSet) { TEST(WebRtcMediaEngineTest, FilterRtpExtensions_EmptyList) { std::vector extensions; + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions1, true); + FilterRtpExtensions(extensions, SupportedExtensions1, true, trials); EXPECT_EQ(0u, filtered.size()); } TEST(WebRtcMediaEngineTest, FilterRtpExtensions_IncludeOnlySupported) { std::vector extensions = MakeUniqueExtensions(); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions1, false); + FilterRtpExtensions(extensions, SupportedExtensions1, false, trials); EXPECT_EQ(2u, filtered.size()); EXPECT_EQ("c", filtered[0].uri); EXPECT_EQ("i", filtered[1].uri); @@ -117,24 +120,27 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_IncludeOnlySupported) { TEST(WebRtcMediaEngineTest, FilterRtpExtensions_SortedByName_1) { std::vector extensions = MakeUniqueExtensions(); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, false); + FilterRtpExtensions(extensions, SupportedExtensions2, false, trials); EXPECT_EQ(12u, filtered.size()); EXPECT_TRUE(IsSorted(filtered)); } TEST(WebRtcMediaEngineTest, FilterRtpExtensions_SortedByName_2) { std::vector extensions = MakeUniqueExtensions(); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(12u, filtered.size()); EXPECT_TRUE(IsSorted(filtered)); } TEST(WebRtcMediaEngineTest, FilterRtpExtensions_DontRemoveRedundant) { std::vector extensions = MakeRedundantExtensions(); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, false); + FilterRtpExtensions(extensions, SupportedExtensions2, false, trials); EXPECT_EQ(12u, filtered.size()); EXPECT_TRUE(IsSorted(filtered)); EXPECT_EQ(filtered[0].uri, filtered[1].uri); @@ -142,8 +148,9 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_DontRemoveRedundant) { TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundant) { std::vector extensions = MakeRedundantExtensions(); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(6u, filtered.size()); EXPECT_TRUE(IsSorted(filtered)); EXPECT_NE(filtered[0].uri, filtered[1].uri); @@ -155,8 +162,9 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantEncrypted_1) { extensions.push_back(webrtc::RtpExtension("b", 2, true)); extensions.push_back(webrtc::RtpExtension("c", 3)); extensions.push_back(webrtc::RtpExtension("b", 4)); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(3u, filtered.size()); EXPECT_TRUE(IsSorted(filtered)); EXPECT_EQ(filtered[0].uri, filtered[1].uri); @@ -171,8 +179,9 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantEncrypted_2) { extensions.push_back(webrtc::RtpExtension("b", 2)); extensions.push_back(webrtc::RtpExtension("c", 3)); extensions.push_back(webrtc::RtpExtension("b", 4)); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(3u, filtered.size()); EXPECT_TRUE(IsSorted(filtered)); EXPECT_EQ(filtered[0].uri, filtered[1].uri); @@ -184,6 +193,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantEncrypted_2) { TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_1) { webrtc::test::ScopedFieldTrials override_field_trials_( "WebRTC-FilterAbsSendTimeExtension/Enabled/"); + webrtc::FieldTrialBasedConfig trials; std::vector extensions; extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 3)); @@ -193,7 +203,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_1) { RtpExtension(RtpExtension::kTransportSequenceNumberUri, 1)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(1u, filtered.size()); EXPECT_EQ(RtpExtension::kTransportSequenceNumberUri, filtered[0].uri); } @@ -208,8 +218,9 @@ TEST(WebRtcMediaEngineTest, extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 1)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(2u, filtered.size()); EXPECT_EQ(RtpExtension::kTransportSequenceNumberUri, filtered[0].uri); EXPECT_EQ(RtpExtension::kAbsSendTimeUri, filtered[1].uri); @@ -218,6 +229,7 @@ TEST(WebRtcMediaEngineTest, TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBweEncrypted_1) { webrtc::test::ScopedFieldTrials override_field_trials_( "WebRTC-FilterAbsSendTimeExtension/Enabled/"); + webrtc::FieldTrialBasedConfig trials; std::vector extensions; extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 3)); @@ -231,7 +243,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBweEncrypted_1) { RtpExtension(RtpExtension::kTransportSequenceNumberUri, 2, true)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(2u, filtered.size()); EXPECT_EQ(RtpExtension::kTransportSequenceNumberUri, filtered[0].uri); EXPECT_EQ(RtpExtension::kTransportSequenceNumberUri, filtered[1].uri); @@ -252,8 +264,9 @@ TEST(WebRtcMediaEngineTest, extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 2, true)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(3u, filtered.size()); EXPECT_EQ(RtpExtension::kTransportSequenceNumberUri, filtered[0].uri); EXPECT_EQ(RtpExtension::kTransportSequenceNumberUri, filtered[1].uri); @@ -266,8 +279,9 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_2) { extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 1)); extensions.push_back(RtpExtension(RtpExtension::kAbsSendTimeUri, 14)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 7)); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(1u, filtered.size()); EXPECT_EQ(RtpExtension::kAbsSendTimeUri, filtered[0].uri); } @@ -276,8 +290,9 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_3) { std::vector extensions; extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 2)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); + webrtc::FieldTrialBasedConfig trials; std::vector filtered = - FilterRtpExtensions(extensions, SupportedExtensions2, true); + FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(1u, filtered.size()); EXPECT_EQ(RtpExtension::kTimestampOffsetUri, filtered[0].uri); } @@ -285,6 +300,8 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_3) { TEST(WebRtcMediaEngineTest, Create) { MediaEngineDependencies deps; webrtc::SetMediaEngineDefaults(&deps); + webrtc::FieldTrialBasedConfig trials; + deps.trials = &trials; std::unique_ptr engine = CreateMediaEngine(std::move(deps)); diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index 926b88754d..e56905f0c6 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -42,7 +42,6 @@ #include "rtc_base/thread.h" #include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" -#include "system_wrappers/include/field_trial.h" namespace cricket { @@ -63,20 +62,9 @@ const char* StreamTypeToString( return nullptr; } -// If this field trial is enabled, we will enable sending FlexFEC and disable -// sending ULPFEC whenever the former has been negotiated in the SDPs. -bool IsFlexfecFieldTrialEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03"); -} - -// If this field trial is enabled, the "flexfec-03" codec will be advertised -// as being supported. This means that "flexfec-03" will appear in the default -// SDP offer, and we therefore need to be ready to receive FlexFEC packets from -// the remote. It also means that FlexFEC SSRCs will be generated by -// MediaSession and added as "a=ssrc:" and "a=ssrc-group:" lines in the local -// SDP. -bool IsFlexfecAdvertisedFieldTrialEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised"); +bool IsEnabled(const webrtc::WebRtcKeyValueConfig& trials, + absl::string_view name) { + return absl::StartsWith(trials.Lookup(name), "Enabled"); } bool PowerOfTwo(int value) { @@ -93,7 +81,8 @@ bool IsScaleFactorsPowerOfTwo(const webrtc::VideoEncoderConfig& config) { return true; } -void AddDefaultFeedbackParams(VideoCodec* codec) { +void AddDefaultFeedbackParams(VideoCodec* codec, + const webrtc::WebRtcKeyValueConfig& trials) { // Don't add any feedback params for RED and ULPFEC. if (codec->name == kRedCodecName || codec->name == kUlpfecCodecName) return; @@ -107,7 +96,7 @@ void AddDefaultFeedbackParams(VideoCodec* codec) { codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); if (codec->name == kVp8CodecName && - webrtc::field_trial::IsEnabled("WebRTC-RtcpLossNotification")) { + IsEnabled(trials, "WebRTC-RtcpLossNotification")) { codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamLntf, kParamValueEmpty)); } } @@ -117,7 +106,8 @@ void AddDefaultFeedbackParams(VideoCodec* codec) { // codecs for recognized codecs (VP8, VP9, H264, and RED). It will also add // default feedback params to the codecs. std::vector AssignPayloadTypesAndDefaultCodecs( - std::vector input_formats) { + std::vector input_formats, + const webrtc::WebRtcKeyValueConfig& trials) { if (input_formats.empty()) return std::vector(); static const int kFirstDynamicPayloadType = 96; @@ -127,7 +117,7 @@ std::vector AssignPayloadTypesAndDefaultCodecs( input_formats.push_back(webrtc::SdpVideoFormat(kRedCodecName)); input_formats.push_back(webrtc::SdpVideoFormat(kUlpfecCodecName)); - if (IsFlexfecAdvertisedFieldTrialEnabled()) { + if (IsEnabled(trials, "WebRTC-FlexFEC-03-Advertised")) { webrtc::SdpVideoFormat flexfec_format(kFlexfecCodecName); // This value is currently arbitrarily set to 10 seconds. (The unit // is microseconds.) This parameter MUST be present in the SDP, but @@ -141,7 +131,7 @@ std::vector AssignPayloadTypesAndDefaultCodecs( for (const webrtc::SdpVideoFormat& format : input_formats) { VideoCodec codec(format); codec.id = payload_type; - AddDefaultFeedbackParams(&codec); + AddDefaultFeedbackParams(&codec, trials); output_codecs.push_back(codec); // Increment payload type. @@ -175,7 +165,8 @@ std::vector AssignPayloadTypesAndDefaultCodecs( template std::vector GetPayloadTypesAndDefaultCodecs( const T* factory, - bool is_decoder_factory) { + bool is_decoder_factory, + const webrtc::WebRtcKeyValueConfig& trials) { if (!factory) { return {}; } @@ -186,7 +177,8 @@ std::vector GetPayloadTypesAndDefaultCodecs( AddH264ConstrainedBaselineProfileToSupportedFormats(&supported_formats); } - return AssignPayloadTypesAndDefaultCodecs(std::move(supported_formats)); + return AssignPayloadTypesAndDefaultCodecs(std::move(supported_formats), + trials); } bool IsTemporalLayersSupported(const std::string& codec_name) { @@ -261,8 +253,9 @@ static bool ValidateStreamParams(const StreamParams& sp) { } // Returns true if the given codec is disallowed from doing simulcast. -bool IsCodecDisabledForSimulcast(const std::string& codec_name) { - return !webrtc::field_trial::IsDisabled("WebRTC-H264Simulcast") +bool IsCodecDisabledForSimulcast(const std::string& codec_name, + const webrtc::WebRtcKeyValueConfig& trials) { + return !absl::StartsWith(trials.Lookup("WebRTC-H264Simulcast"), "Disabled") ? absl::EqualsIgnoreCase(codec_name, kVp9CodecName) : absl::EqualsIgnoreCase(codec_name, kH264CodecName) || absl::EqualsIgnoreCase(codec_name, kVp9CodecName); @@ -288,9 +281,11 @@ static int GetMaxDefaultVideoBitrateKbps(int width, return max_bitrate; } -bool GetVp9LayersFromFieldTrialGroup(size_t* num_spatial_layers, - size_t* num_temporal_layers) { - std::string group = webrtc::field_trial::FindFullName("WebRTC-SupportVP9SVC"); +bool GetVp9LayersFromFieldTrialGroup( + size_t* num_spatial_layers, + size_t* num_temporal_layers, + const webrtc::WebRtcKeyValueConfig& trials) { + std::string group = trials.Lookup("WebRTC-SupportVP9SVC"); if (group.empty()) return false; @@ -309,19 +304,21 @@ bool GetVp9LayersFromFieldTrialGroup(size_t* num_spatial_layers, return true; } -absl::optional GetVp9SpatialLayersFromFieldTrial() { +absl::optional GetVp9SpatialLayersFromFieldTrial( + const webrtc::WebRtcKeyValueConfig& trials) { size_t num_sl; size_t num_tl; - if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl)) { + if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl, trials)) { return num_sl; } return absl::nullopt; } -absl::optional GetVp9TemporalLayersFromFieldTrial() { +absl::optional GetVp9TemporalLayersFromFieldTrial( + const webrtc::WebRtcKeyValueConfig& trials) { size_t num_sl; size_t num_tl; - if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl)) { + if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl, trials)) { return num_tl; } return absl::nullopt; @@ -483,14 +480,14 @@ WebRtcVideoChannel::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( const size_t default_num_spatial_layers = parameters_.config.rtp.ssrcs.size(); const size_t num_spatial_layers = - GetVp9SpatialLayersFromFieldTrial().value_or( - default_num_spatial_layers); + GetVp9SpatialLayersFromFieldTrial(call_->trials()) + .value_or(default_num_spatial_layers); const size_t default_num_temporal_layers = num_spatial_layers > 1 ? kConferenceDefaultNumTemporalLayers : 1; const size_t num_temporal_layers = - GetVp9TemporalLayersFromFieldTrial().value_or( - default_num_temporal_layers); + GetVp9TemporalLayersFromFieldTrial(call_->trials()) + .value_or(default_num_temporal_layers); vp9_settings.numberOfSpatialLayers = std::min( num_spatial_layers, kConferenceMaxNumSpatialLayers); @@ -512,7 +509,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( {"onkeypic", webrtc::InterLayerPredMode::kOnKeyPic}}); webrtc::ParseFieldTrial( {&interlayer_pred_experiment_enabled, &inter_layer_pred_mode}, - webrtc::field_trial::FindFullName("WebRTC-Vp9InterLayerPred")); + call_->trials().Lookup("WebRTC-Vp9InterLayerPred")); if (interlayer_pred_experiment_enabled) { vp9_settings.interLayerPred = inter_layer_pred_mode; } else { @@ -583,9 +580,11 @@ void DefaultUnsignalledSsrcHandler::SetDefaultSink( WebRtcVideoEngine::WebRtcVideoEngine( std::unique_ptr video_encoder_factory, - std::unique_ptr video_decoder_factory) + std::unique_ptr video_decoder_factory, + const webrtc::WebRtcKeyValueConfig& trials) : decoder_factory_(std::move(video_decoder_factory)), - encoder_factory_(std::move(video_encoder_factory)) { + encoder_factory_(std::move(video_encoder_factory)), + trials_(trials) { RTC_LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()"; } @@ -606,12 +605,12 @@ VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel( } std::vector WebRtcVideoEngine::send_codecs() const { return GetPayloadTypesAndDefaultCodecs(encoder_factory_.get(), - /*is_decoder_factory=*/false); + /*is_decoder_factory=*/false, trials_); } std::vector WebRtcVideoEngine::recv_codecs() const { return GetPayloadTypesAndDefaultCodecs(decoder_factory_.get(), - /*is_decoder_factory=*/true); + /*is_decoder_factory=*/true, trials_); } std::vector @@ -630,11 +629,10 @@ WebRtcVideoEngine::GetRtpHeaderExtensions() const { webrtc::RtpExtension::kRidUri, webrtc::RtpExtension::kRepairedRidUri}) { result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv); } - result.emplace_back( - webrtc::RtpExtension::kGenericFrameDescriptorUri00, id, - webrtc::field_trial::IsEnabled("WebRTC-GenericDescriptorAdvertised") - ? webrtc::RtpTransceiverDirection::kSendRecv - : webrtc::RtpTransceiverDirection::kStopped); + result.emplace_back(webrtc::RtpExtension::kGenericFrameDescriptorUri00, id, + IsEnabled(trials_, "WebRTC-GenericDescriptorAdvertised") + ? webrtc::RtpTransceiverDirection::kSendRecv + : webrtc::RtpTransceiverDirection::kStopped); return result; } @@ -656,12 +654,13 @@ WebRtcVideoChannel::WebRtcVideoChannel( bitrate_allocator_factory_(bitrate_allocator_factory), default_send_options_(options), last_stats_log_ms_(-1), - discard_unknown_ssrc_packets_(webrtc::field_trial::IsEnabled( - "WebRTC-Video-DiscardPacketsWithUnknownSsrc")), + discard_unknown_ssrc_packets_( + IsEnabled(call_->trials(), + "WebRTC-Video-DiscardPacketsWithUnknownSsrc")), crypto_options_(crypto_options), unknown_ssrc_packet_buffer_( - webrtc::field_trial::IsEnabled( - "WebRTC-Video-BufferPacketsWithUnknownSsrc") + IsEnabled(call_->trials(), + "WebRTC-Video-BufferPacketsWithUnknownSsrc") ? new UnhandledPacketsBuffer() : nullptr) { RTC_DCHECK(thread_checker_.IsCurrent()); @@ -669,7 +668,7 @@ WebRtcVideoChannel::WebRtcVideoChannel( rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; sending_ = false; recv_codecs_ = MapCodecs(GetPayloadTypesAndDefaultCodecs( - decoder_factory_, /*is_decoder_factory=*/true)); + decoder_factory_, /*is_decoder_factory=*/true, call_->trials())); recv_flexfec_payload_type_ = recv_codecs_.empty() ? 0 : recv_codecs_.front().flexfec_payload_type; } @@ -763,7 +762,7 @@ bool WebRtcVideoChannel::GetChangedSendParameters( } // Never enable sending FlexFEC, unless we are in the experiment. - if (!IsFlexfecFieldTrialEnabled()) { + if (!IsEnabled(call_->trials(), "WebRTC-FlexFEC-03")) { RTC_LOG(LS_INFO) << "WebRTC-FlexFEC-03 field trial is not enabled."; for (VideoCodecSettings& codec : negotiated_codecs) codec.flexfec_payload_type = -1; @@ -783,7 +782,8 @@ bool WebRtcVideoChannel::GetChangedSendParameters( changed_params->extmap_allow_mixed = params.extmap_allow_mixed; } std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true); + params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true, + call_->trials()); if (!send_rtp_extensions_ || (*send_rtp_extensions_ != filtered_extensions)) { changed_params->rtp_header_extensions = absl::optional>(filtered_extensions); @@ -1123,7 +1123,8 @@ bool WebRtcVideoChannel::GetChangedRecvParameters( if (params.is_stream_active) { const std::vector local_supported_codecs = GetPayloadTypesAndDefaultCodecs(decoder_factory_, - /*is_decoder_factory=*/true); + /*is_decoder_factory=*/true, + call_->trials()); for (const VideoCodecSettings& mapped_codec : mapped_codecs) { if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) { RTC_LOG(LS_ERROR) @@ -1141,7 +1142,8 @@ bool WebRtcVideoChannel::GetChangedRecvParameters( // Handle RTP header extensions. std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForVideo, false); + params.extensions, webrtc::RtpExtension::IsSupportedForVideo, false, + call_->trials()); if (filtered_extensions != recv_rtp_extensions_) { changed_params->rtp_header_extensions = absl::optional>(filtered_extensions); @@ -1470,7 +1472,7 @@ void WebRtcVideoChannel::ConfigureReceiverRtp( // TODO(brandtr): Generalize when we add support for multistream protection. flexfec_config->payload_type = recv_flexfec_payload_type_; - if (IsFlexfecAdvertisedFieldTrialEnabled() && + if (IsEnabled(call_->trials(), "WebRTC-FlexFEC-03-Advertised") && sp.GetFecFrSsrc(ssrc, &flexfec_config->remote_ssrc)) { flexfec_config->protected_media_ssrcs = {ssrc}; flexfec_config->local_ssrc = config->rtp.local_ssrc; @@ -1703,7 +1705,7 @@ void WebRtcVideoChannel::BackfillBufferedPackets( int delivery_packet_error_cnt = 0; webrtc::PacketReceiver* receiver = this->call_->Receiver(); unknown_ssrc_packet_buffer_->BackfillPackets( - ssrcs, [&](uint32_t ssrc, int64_t packet_time_us, + ssrcs, [&](uint32_t /*ssrc*/, int64_t packet_time_us, rtc::CopyOnWriteBuffer packet) { switch (receiver->DeliverPacket(webrtc::MediaType::VIDEO, packet, packet_time_us)) { @@ -1764,7 +1766,7 @@ void WebRtcVideoChannel::SetInterface(NetworkInterface* iface) { // which case that is used as UDP recevie buffer size. All other values shall // result in the default value being used. const std::string group_name_recv_buf_size = - webrtc::field_trial::FindFullName("WebRTC-IncreasedReceivebuffers"); + call_->trials().Lookup("WebRTC-IncreasedReceivebuffers"); int recv_buffer_size = kVideoRtpRecvBufferSize; if (!group_name_recv_buf_size.empty() && (sscanf(group_name_recv_buf_size.c_str(), "%d", &recv_buffer_size) != 1 || @@ -1782,7 +1784,7 @@ void WebRtcVideoChannel::SetInterface(NetworkInterface* iface) { // due to lack of socket buffer space, although it's not yet clear what the // ideal value should be. const std::string group_name_send_buf_size = - webrtc::field_trial::FindFullName("WebRTC-SendBufferSizeBytes"); + call_->trials().Lookup("WebRTC-SendBufferSizeBytes"); int send_buffer_size = kVideoRtpSendBufferSize; if (!group_name_send_buf_size.empty() && (sscanf(group_name_send_buf_size.c_str(), "%d", &send_buffer_size) != 1 || @@ -1962,8 +1964,8 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( parameters_(std::move(config), options, max_bitrate_bps, codec_settings), rtp_parameters_(CreateRtpParametersWithEncodings(sp)), sending_(false), - disable_automatic_resize_(webrtc::field_trial::IsEnabled( - "WebRTC-Video-DisableAutomaticResize")) { + disable_automatic_resize_( + IsEnabled(call->trials(), "WebRTC-Video-DisableAutomaticResize")) { // Maximum packet size may come in RtpConfig from external transport, for // example from QuicTransportInterface implementation, so do not exceed // given max_packet_size. @@ -1984,7 +1986,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( // FlexFEC SSRCs. // TODO(brandtr): This code needs to be generalized when we add support for // multistream protection. - if (IsFlexfecFieldTrialEnabled()) { + if (IsEnabled(call_->trials(), "WebRTC-FlexFEC-03")) { uint32_t flexfec_ssrc; bool flexfec_enabled = false; for (uint32_t primary_ssrc : parameters_.config.rtp.ssrcs) { @@ -2089,8 +2091,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetDegradationPreference() const { webrtc::VideoTrackInterface::ContentHint::kText) { degradation_preference = webrtc::DegradationPreference::MAINTAIN_RESOLUTION; - } else if (webrtc::field_trial::IsEnabled( - "WebRTC-Video-BalancedDegradation")) { + } else if (IsEnabled(call_->trials(), "WebRTC-Video-BalancedDegradation")) { // Standard wants balanced by default, but it needs to be tuned first. degradation_preference = webrtc::DegradationPreference::BALANCED; } else { @@ -2341,7 +2342,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig( // or a screencast (and not in simulcast screenshare experiment), only // configure a single stream. encoder_config.number_of_streams = parameters_.config.rtp.ssrcs.size(); - if (IsCodecDisabledForSimulcast(codec.name)) { + if (IsCodecDisabledForSimulcast(codec.name, call_->trials())) { encoder_config.number_of_streams = 1; } @@ -2904,8 +2905,7 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateWebRtcVideoStream() { MaybeAssociateFlexfecWithVideo(); stream_->Start(); - if (webrtc::field_trial::IsEnabled( - "WebRTC-Video-BufferPacketsWithUnknownSsrc")) { + if (IsEnabled(call_->trials(), "WebRTC-Video-BufferPacketsWithUnknownSsrc")) { channel_->BackfillBufferedPackets(stream_params_.ssrcs); } } @@ -3356,15 +3356,18 @@ void WebRtcVideoChannel::SetDepacketizerToDecoderFrameTransformer( // TODO(bugs.webrtc.org/8785): Consider removing max_qp as member of // EncoderStreamFactory and instead set this value individually for each stream // in the VideoEncoderConfig.simulcast_layers. -EncoderStreamFactory::EncoderStreamFactory(std::string codec_name, - int max_qp, - bool is_screenshare, - bool conference_mode) +EncoderStreamFactory::EncoderStreamFactory( + std::string codec_name, + int max_qp, + bool is_screenshare, + bool conference_mode, + const webrtc::WebRtcKeyValueConfig* trials) : codec_name_(codec_name), max_qp_(max_qp), is_screenshare_(is_screenshare), - conference_mode_(conference_mode) {} + conference_mode_(conference_mode), + trials_(trials ? *trials : fallback_trials_) {} std::vector EncoderStreamFactory::CreateEncoderStreams( int width, @@ -3486,7 +3489,7 @@ EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams( encoder_config.number_of_streams, width, height, encoder_config.bitrate_priority, max_qp_, is_screenshare_ && conference_mode_, - temporal_layers_supported); + temporal_layers_supported, trials_); // Allow an experiment to override the minimum bitrate for the lowest // spatial layer. The experiment's configuration has the lowest priority. if (experimental_min_bitrate) { diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index 26bde3384a..321a5a8c2e 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -19,6 +19,7 @@ #include "absl/types/optional.h" #include "api/call/transport.h" +#include "api/transport/field_trial_based_config.h" #include "api/video/video_bitrate_allocator_factory.h" #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" @@ -97,7 +98,8 @@ class WebRtcVideoEngine : public VideoEngineInterface { // and external hardware codecs. WebRtcVideoEngine( std::unique_ptr video_encoder_factory, - std::unique_ptr video_decoder_factory); + std::unique_ptr video_decoder_factory, + const webrtc::WebRtcKeyValueConfig& trials); ~WebRtcVideoEngine() override; @@ -119,6 +121,7 @@ class WebRtcVideoEngine : public VideoEngineInterface { const std::unique_ptr encoder_factory_; const std::unique_ptr bitrate_allocator_factory_; + const webrtc::WebRtcKeyValueConfig& trials_; }; class WebRtcVideoChannel : public VideoMediaChannel, @@ -550,7 +553,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, void FillSendAndReceiveCodecStats(VideoMediaInfo* video_media_info) RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); - rtc::Thread* worker_thread_; + rtc::Thread* const worker_thread_; rtc::ThreadChecker thread_checker_; uint32_t rtcp_receiver_report_ssrc_ RTC_GUARDED_BY(thread_checker_); @@ -631,7 +634,18 @@ class EncoderStreamFactory EncoderStreamFactory(std::string codec_name, int max_qp, bool is_screenshare, - bool conference_mode); + bool conference_mode) + : EncoderStreamFactory(codec_name, + max_qp, + is_screenshare, + conference_mode, + nullptr) {} + + EncoderStreamFactory(std::string codec_name, + int max_qp, + bool is_screenshare, + bool conference_mode, + const webrtc::WebRtcKeyValueConfig* trials); private: std::vector CreateEncoderStreams( @@ -658,6 +672,8 @@ class EncoderStreamFactory // Allows a screenshare specific configuration, which enables temporal // layering and various settings. const bool conference_mode_; + const webrtc::FieldTrialBasedConfig fallback_trials_; + const webrtc::WebRtcKeyValueConfig& trials_; }; } // namespace cricket diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index 6d2e971f76..9353f19da6 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -257,7 +257,8 @@ class WebRtcVideoEngineTest : public ::testing::Test { engine_(std::unique_ptr( encoder_factory_), std::unique_ptr( - decoder_factory_)) { + decoder_factory_), + field_trials_) { // Ensure fake clock doesn't return 0, which will cause some initializations // fail inside RTP senders. fake_clock_.AdvanceTime(webrtc::TimeDelta::Micros(1)); @@ -1043,8 +1044,9 @@ TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) { TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) { std::unique_ptr encoder_factory; std::unique_ptr decoder_factory; + webrtc::FieldTrialBasedConfig trials; WebRtcVideoEngine engine(std::move(encoder_factory), - std::move(decoder_factory)); + std::move(decoder_factory), trials); EXPECT_EQ(0u, engine.send_codecs().size()); EXPECT_EQ(0u, engine.recv_codecs().size()); } @@ -1055,9 +1057,10 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) { new webrtc::MockVideoEncoderFactory(); webrtc::MockVideoDecoderFactory* decoder_factory = new webrtc::MockVideoDecoderFactory(); + webrtc::FieldTrialBasedConfig trials; WebRtcVideoEngine engine( (std::unique_ptr(encoder_factory)), - (std::unique_ptr(decoder_factory))); + (std::unique_ptr(decoder_factory)), trials); // TODO(kron): Change to Times(1) once send and receive codecs are changed // to be treated independently. EXPECT_CALL(*encoder_factory, GetSupportedFormats()).Times(1); @@ -1085,9 +1088,10 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) { webrtc::kVideoCodecVP8))) .WillOnce( [] { return std::make_unique(); }); + webrtc::FieldTrialBasedConfig trials; WebRtcVideoEngine engine( (std::unique_ptr(encoder_factory)), - (std::unique_ptr(decoder_factory))); + (std::unique_ptr(decoder_factory)), trials); const webrtc::SdpVideoFormat vp8_format("VP8"); const std::vector supported_formats = {vp8_format}; EXPECT_CALL(*encoder_factory, GetSupportedFormats()) @@ -1204,9 +1208,10 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) { std::unique_ptr rate_allocator_factory = std::make_unique(); + webrtc::FieldTrialBasedConfig trials; WebRtcVideoEngine engine( (std::unique_ptr(encoder_factory)), - (std::unique_ptr(decoder_factory))); + (std::unique_ptr(decoder_factory)), trials); const webrtc::SdpVideoFormat vp8_format("VP8"); const std::vector supported_formats = {vp8_format}; EXPECT_CALL(*encoder_factory, GetSupportedFormats()) @@ -1324,7 +1329,8 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { webrtc::CreateBuiltinVideoEncoderFactory(), std::make_unique( []() { return std::make_unique(); }, - kSdpVideoFormats)), + kSdpVideoFormats), + field_trials_), channel_(absl::WrapUnique(static_cast( engine_.CreateMediaChannel( call_.get(), @@ -1456,7 +1462,8 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { video_bitrate_allocator_factory_( webrtc::CreateBuiltinVideoBitrateAllocatorFactory()), engine_(webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory()) {} + webrtc::CreateBuiltinVideoDecoderFactory(), + field_trials_) {} virtual void SetUp() { // One testcase calls SetUp in a loop, only create call_ once. @@ -8155,7 +8162,8 @@ class WebRtcVideoChannelSimulcastTest : public ::testing::Test { engine_(std::unique_ptr( encoder_factory_), std::unique_ptr( - decoder_factory_)), + decoder_factory_), + field_trials_), last_ssrc_(0) {} void SetUp() override { @@ -8215,7 +8223,7 @@ class WebRtcVideoChannelSimulcastTest : public ::testing::Test { expected_streams = GetSimulcastConfig( /*min_layers=*/1, num_configured_streams, capture_width, capture_height, webrtc::kDefaultBitratePriority, kDefaultQpMax, - screenshare && conference_mode, true); + screenshare && conference_mode, true, field_trials_); if (screenshare && conference_mode) { for (const webrtc::VideoStream& stream : expected_streams) { // Never scale screen content. @@ -8316,6 +8324,7 @@ class WebRtcVideoChannelSimulcastTest : public ::testing::Test { cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_; std::unique_ptr mock_rate_allocator_factory_; + webrtc::FieldTrialBasedConfig field_trials_; WebRtcVideoEngine engine_; std::unique_ptr channel_; uint32_t last_ssrc_; diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 7a0192a4b3..2c9e15df28 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -20,6 +20,7 @@ #include "absl/strings/match.h" #include "api/audio_codecs/audio_codec_pair_id.h" #include "api/call/audio_sink.h" +#include "api/transport/webrtc_key_value_config.h" #include "media/base/audio_source.h" #include "media/base/media_constants.h" #include "media/base/stream_params.h" @@ -45,7 +46,6 @@ #include "rtc_base/strings/string_format.h" #include "rtc_base/third_party/base64/base64.h" #include "rtc_base/trace_event.h" -#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" #if WEBRTC_ENABLE_PROTOBUF @@ -111,12 +111,6 @@ std::string ToString(const AudioCodec& codec) { return ss.Release(); } -// If this field trial is enabled, we will negotiate and use RFC 2198 -// redundancy for opus audio. -bool IsAudioRedForOpusFieldTrialEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-Audio-Red-For-Opus"); -} - bool IsCodec(const AudioCodec& codec, const char* ref_name) { return absl::EqualsIgnoreCase(codec.name, ref_name); } @@ -203,6 +197,11 @@ absl::optional ComputeSendBitrate(int max_send_bitrate_bps, } } +bool IsEnabled(const webrtc::WebRtcKeyValueConfig& config, + absl::string_view trial) { + return absl::StartsWith(config.Lookup(trial), "Enabled"); +} + struct AdaptivePtimeConfig { bool enabled = false; webrtc::DataRate min_payload_bitrate = webrtc::DataRate::KilobitsPerSec(16); @@ -219,9 +218,8 @@ struct AdaptivePtimeConfig { "use_slow_adaptation", &use_slow_adaptation); } - AdaptivePtimeConfig() { - Parser()->Parse( - webrtc::field_trial::FindFullName("WebRTC-Audio-AdaptivePtime")); + explicit AdaptivePtimeConfig(const webrtc::WebRtcKeyValueConfig& trials) { + Parser()->Parse(trials.Lookup("WebRTC-Audio-AdaptivePtime")); #if WEBRTC_ENABLE_PROTOBUF webrtc::audio_network_adaptor::config::ControllerManager config; auto* frame_length_controller = @@ -243,13 +241,18 @@ WebRtcVoiceEngine::WebRtcVoiceEngine( const rtc::scoped_refptr& encoder_factory, const rtc::scoped_refptr& decoder_factory, rtc::scoped_refptr audio_mixer, - rtc::scoped_refptr audio_processing) + rtc::scoped_refptr audio_processing, + const webrtc::WebRtcKeyValueConfig& trials) : task_queue_factory_(task_queue_factory), adm_(adm), encoder_factory_(encoder_factory), decoder_factory_(decoder_factory), audio_mixer_(audio_mixer), - apm_(audio_processing) { + apm_(audio_processing), + audio_red_for_opus_trial_enabled_( + IsEnabled(trials, "WebRTC-Audio-Red-For-Opus")), + minimized_remsampling_on_mobile_trial_enabled_( + IsEnabled(trials, "WebRTC-Audio-MinimizeResamplingOnMobile")) { // This may be called from any thread, so detach thread checkers. worker_thread_checker_.Detach(); signal_thread_checker_.Detach(); @@ -415,8 +418,7 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { // performed inside the audio processing module on mobile platforms by // whenever possible turning off the fixed AGC mode and the high-pass filter. // (https://bugs.chromium.org/p/webrtc/issues/detail?id=6181). - if (webrtc::field_trial::IsEnabled( - "WebRTC-Audio-MinimizeResamplingOnMobile")) { + if (minimized_remsampling_on_mobile_trial_enabled_) { options.auto_gain_control = false; RTC_LOG(LS_INFO) << "Disable AGC according to field trial."; if (!(options.noise_suppression.value_or(false) || @@ -722,8 +724,7 @@ std::vector WebRtcVoiceEngine::CollectCodecs( out.push_back(codec); - if (codec.name == kOpusCodecName && - IsAudioRedForOpusFieldTrialEnabled()) { + if (codec.name == kOpusCodecName && audio_red_for_opus_trial_enabled_) { map_format({kRedCodecName, 48000, 2}, &out); } } @@ -767,7 +768,8 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream const absl::optional codec_pair_id, rtc::scoped_refptr frame_encryptor, const webrtc::CryptoOptions& crypto_options) - : call_(call), + : adaptive_ptime_config_(call->trials()), + call_(call), config_(send_transport), max_send_bitrate_bps_(max_send_bitrate_bps), rtp_parameters_(CreateRtpParametersWithOneEncoding()) { @@ -1368,7 +1370,9 @@ WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel( engine_(engine), call_(call), audio_config_(config.audio), - crypto_options_(crypto_options) { + crypto_options_(crypto_options), + audio_red_for_opus_trial_enabled_( + IsEnabled(call->trials(), "WebRTC-Audio-Red-For-Opus")) { RTC_LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; RTC_DCHECK(call); engine->RegisterChannel(this); @@ -1415,7 +1419,8 @@ bool WebRtcVoiceMediaChannel::SetSendParameters( } std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForAudio, true); + params.extensions, webrtc::RtpExtension::IsSupportedForAudio, true, + call_->trials()); if (send_rtp_extensions_ != filtered_extensions) { send_rtp_extensions_.swap(filtered_extensions); for (auto& it : send_streams_) { @@ -1452,7 +1457,8 @@ bool WebRtcVoiceMediaChannel::SetRecvParameters( return false; } std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForAudio, false); + params.extensions, webrtc::RtpExtension::IsSupportedForAudio, false, + call_->trials()); if (recv_rtp_extensions_ != filtered_extensions) { recv_rtp_extensions_.swap(filtered_extensions); for (auto& it : recv_streams_) { @@ -1628,7 +1634,7 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs( } auto format = AudioCodecToSdpAudioFormat(codec); if (!IsCodec(codec, kCnCodecName) && !IsCodec(codec, kDtmfCodecName) && - (!IsAudioRedForOpusFieldTrialEnabled() || + (!audio_red_for_opus_trial_enabled_ || !IsCodec(codec, kRedCodecName)) && !engine()->decoder_factory_->IsSupportedDecoder(format)) { RTC_LOG(LS_ERROR) << "Unsupported codec: " << rtc::ToString(format); @@ -1782,7 +1788,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( } } - if (IsAudioRedForOpusFieldTrialEnabled()) { + if (audio_red_for_opus_trial_enabled_) { // Loop through the codecs to find the RED codec that matches opus // with respect to clockrate and number of channels. size_t red_codec_position = 0; diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index 9cea31881e..f805d6c916 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -20,6 +20,7 @@ #include "api/scoped_refptr.h" #include "api/task_queue/task_queue_factory.h" #include "api/transport/rtp/rtp_source.h" +#include "api/transport/webrtc_key_value_config.h" #include "call/audio_state.h" #include "call/call.h" #include "media/base/media_engine.h" @@ -49,7 +50,8 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { const rtc::scoped_refptr& encoder_factory, const rtc::scoped_refptr& decoder_factory, rtc::scoped_refptr audio_mixer, - rtc::scoped_refptr audio_processing); + rtc::scoped_refptr audio_processing, + const webrtc::WebRtcKeyValueConfig& trials); ~WebRtcVoiceEngine() override; // Does initialization that needs to occur on the worker thread. @@ -127,6 +129,11 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { int audio_jitter_buffer_min_delay_ms_ = 0; bool audio_jitter_buffer_enable_rtx_handling_ = false; + // If this field trial is enabled, we will negotiate and use RFC 2198 + // redundancy for opus audio. + const bool audio_red_for_opus_trial_enabled_; + const bool minimized_remsampling_on_mobile_trial_enabled_; + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcVoiceEngine); }; @@ -331,6 +338,8 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, rtc::scoped_refptr unsignaled_frame_decryptor_; + const bool audio_red_for_opus_trial_enabled_; + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcVoiceMediaChannel); }; } // namespace cricket diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc index 518badb25f..b051107ec0 100644 --- a/media/engine/webrtc_voice_engine_unittest.cc +++ b/media/engine/webrtc_voice_engine_unittest.cc @@ -158,10 +158,12 @@ TEST(WebRtcVoiceEngineTestStubLibrary, StartupShutdown) { EXPECT_CALL(*apm, DetachAecDump()); } { + webrtc::FieldTrialBasedConfig trials; cricket::WebRtcVoiceEngine engine( task_queue_factory.get(), adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), - webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm); + webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm, + trials); engine.Init(); } } @@ -210,7 +212,7 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory(); engine_.reset(new cricket::WebRtcVoiceEngine( task_queue_factory_.get(), adm_, encoder_factory, decoder_factory, - nullptr, apm_)); + nullptr, apm_, trials_config_)); engine_->Init(); send_parameters_.codecs.push_back(kPcmuCodec); recv_parameters_.codecs.push_back(kPcmuCodec); @@ -801,6 +803,7 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { private: webrtc::test::ScopedFieldTrials override_field_trials_; + webrtc::FieldTrialBasedConfig trials_config_; }; INSTANTIATE_TEST_SUITE_P(TestBothWithAndWithoutNullApm, @@ -3628,14 +3631,15 @@ TEST(WebRtcVoiceEngineTest, StartupShutdown) { webrtc::test::MockAudioDeviceModule::CreateNice(); rtc::scoped_refptr apm = use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create(); + webrtc::FieldTrialBasedConfig field_trials; cricket::WebRtcVoiceEngine engine( task_queue_factory.get(), adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), - webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm); + webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm, + field_trials); engine.Init(); webrtc::RtcEventLogNull event_log; webrtc::Call::Config call_config(&event_log); - webrtc::FieldTrialBasedConfig field_trials; call_config.trials = &field_trials; call_config.task_queue_factory = task_queue_factory.get(); auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); @@ -3659,14 +3663,15 @@ TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) { { rtc::scoped_refptr apm = use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create(); + webrtc::FieldTrialBasedConfig field_trials; cricket::WebRtcVoiceEngine engine( task_queue_factory.get(), adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), - webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm); + webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm, + field_trials); engine.Init(); webrtc::RtcEventLogNull event_log; webrtc::Call::Config call_config(&event_log); - webrtc::FieldTrialBasedConfig field_trials; call_config.trials = &field_trials; call_config.task_queue_factory = task_queue_factory.get(); auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); @@ -3692,10 +3697,12 @@ TEST(WebRtcVoiceEngineTest, HasCorrectPayloadTypeMapping) { webrtc::test::MockAudioDeviceModule::CreateNice(); rtc::scoped_refptr apm = use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create(); + webrtc::FieldTrialBasedConfig field_trials; cricket::WebRtcVoiceEngine engine( task_queue_factory.get(), adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), - webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm); + webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm, + field_trials); engine.Init(); for (const cricket::AudioCodec& codec : engine.send_codecs()) { auto is_codec = [&codec](const char* name, int clockrate = 0) { @@ -3743,14 +3750,15 @@ TEST(WebRtcVoiceEngineTest, Has32Channels) { webrtc::test::MockAudioDeviceModule::CreateNice(); rtc::scoped_refptr apm = use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create(); + webrtc::FieldTrialBasedConfig field_trials; cricket::WebRtcVoiceEngine engine( task_queue_factory.get(), adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), - webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm); + webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm, + field_trials); engine.Init(); webrtc::RtcEventLogNull event_log; webrtc::Call::Config call_config(&event_log); - webrtc::FieldTrialBasedConfig field_trials; call_config.trials = &field_trials; call_config.task_queue_factory = task_queue_factory.get(); auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); @@ -3791,14 +3799,14 @@ TEST(WebRtcVoiceEngineTest, SetRecvCodecs) { webrtc::test::MockAudioDeviceModule::CreateNice(); rtc::scoped_refptr apm = use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create(); + webrtc::FieldTrialBasedConfig field_trials; cricket::WebRtcVoiceEngine engine( task_queue_factory.get(), adm, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), - webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm); + webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm, field_trials); engine.Init(); webrtc::RtcEventLogNull event_log; webrtc::Call::Config call_config(&event_log); - webrtc::FieldTrialBasedConfig field_trials; call_config.trials = &field_trials; call_config.task_queue_factory = task_queue_factory.get(); auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); @@ -3843,9 +3851,10 @@ TEST(WebRtcVoiceEngineTest, CollectRecvCodecs) { rtc::scoped_refptr apm = use_null_apm ? nullptr : webrtc::AudioProcessingBuilder().Create(); - cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), adm, - unused_encoder_factory, - mock_decoder_factory, nullptr, apm); + webrtc::FieldTrialBasedConfig field_trials; + cricket::WebRtcVoiceEngine engine( + task_queue_factory.get(), adm, unused_encoder_factory, + mock_decoder_factory, nullptr, apm, field_trials); engine.Init(); auto codecs = engine.recv_codecs(); EXPECT_EQ(11u, codecs.size()); diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index a4c2f089d6..6f95c062fc 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -759,6 +759,7 @@ if (rtc_include_tests) { "../../api:array_view", "../../api:videocodec_test_fixture_api", "../../api/test/video:function_video_factory", + "../../api/transport:field_trial_based_config", "../../api/video:video_bitrate_allocation", "../../api/video_codecs:video_codecs_api", "../../call:video_stream_api", diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc index ee6301b739..aa3ffede52 100644 --- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc +++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc @@ -22,6 +22,7 @@ #include "absl/types/optional.h" #include "api/array_view.h" +#include "api/transport/field_trial_based_config.h" #include "api/video/video_bitrate_allocation.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_codec.h" @@ -61,10 +62,11 @@ const int kMaxFramerateFps = 30; const int kMaxQp = 56; void ConfigureSimulcast(VideoCodec* codec_settings) { + FieldTrialBasedConfig trials; const std::vector streams = cricket::GetSimulcastConfig( /*min_layer=*/1, codec_settings->numberOfSimulcastStreams, codec_settings->width, codec_settings->height, kBitratePriority, kMaxQp, - /* is_screenshare = */ false, true); + /* is_screenshare = */ false, true, trials); for (size_t i = 0; i < streams.size(); ++i) { SpatialLayer* ss = &codec_settings->simulcastStream[i]; diff --git a/pc/BUILD.gn b/pc/BUILD.gn index d182b43df9..5383362686 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -585,6 +585,7 @@ if (rtc_include_tests) { "../api/rtc_event_log", "../api/rtc_event_log:rtc_event_log_factory", "../api/task_queue:default_task_queue_factory", + "../api/transport:field_trial_based_config", "../api/transport/rtp:rtp_source", "../api/units:time_delta", "../api/video:builtin_video_bitrate_allocator_factory", diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 22ef75c96b..3b5c333a98 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -58,7 +58,6 @@ #include "rtc_base/strings/string_builder.h" #include "rtc_base/trace_event.h" #include "system_wrappers/include/clock.h" -#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" using cricket::ContentInfo; @@ -4355,7 +4354,8 @@ bool PeerConnection::StartRtcEventLog(std::unique_ptr output, bool PeerConnection::StartRtcEventLog( std::unique_ptr output) { int64_t output_period_ms = webrtc::RtcEventLog::kImmediateOutput; - if (field_trial::IsEnabled("WebRTC-RtcEventLogNewFormat")) { + if (absl::StartsWith(factory_->trials().Lookup("WebRTC-RtcEventLogNewFormat"), + "Enabled")) { output_period_ms = 5000; } return StartRtcEventLog(std::move(output), output_period_ms); @@ -5798,9 +5798,8 @@ PeerConnection::InitializePortAllocator_n( // by experiment. if (configuration.disable_ipv6) { port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); - } else if (absl::StartsWith( - webrtc::field_trial::FindFullName("WebRTC-IPv6Default"), - "Disabled")) { + } else if (absl::StartsWith(factory_->trials().Lookup("WebRTC-IPv6Default"), + "Disabled")) { port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); } diff --git a/pc/peer_connection_factory.h b/pc/peer_connection_factory.h index 8e7a2e27ee..552d5ab311 100644 --- a/pc/peer_connection_factory.h +++ b/pc/peer_connection_factory.h @@ -87,6 +87,8 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface { const Options& options() const { return options_; } + const WebRtcKeyValueConfig& trials() const { return *trials_.get(); } + protected: // This structure allows simple management of all new dependencies being added // to the PeerConnectionFactory. diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc index f38ad237b4..4b098e1d5f 100644 --- a/pc/peer_connection_integrationtest.cc +++ b/pc/peer_connection_integrationtest.cc @@ -28,6 +28,7 @@ #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/rtp_receiver_interface.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "api/uma_metrics.h" #include "api/video_codecs/sdp_video_format.h" #include "call/call.h" @@ -633,6 +634,7 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, pc_factory_dependencies.signaling_thread = signaling_thread; pc_factory_dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory(); + pc_factory_dependencies.trials = std::make_unique(); cricket::MediaEngineDependencies media_deps; media_deps.task_queue_factory = pc_factory_dependencies.task_queue_factory.get(); @@ -652,6 +654,8 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, media_deps.audio_processing = AudioProcessingBuilderForTesting().Create(); } + media_deps.trials = pc_factory_dependencies.trials.get(); + pc_factory_dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); pc_factory_dependencies.call_factory = webrtc::CreateCallFactory(); diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc index 3f2371c832..a0e3845fd6 100644 --- a/pc/peer_connection_interface_unittest.cc +++ b/pc/peer_connection_interface_unittest.cc @@ -43,6 +43,7 @@ #include "api/rtp_transceiver_interface.h" #include "api/scoped_refptr.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "api/video_codecs/builtin_video_decoder_factory.h" #include "api/video_codecs/builtin_video_encoder_factory.h" #include "api/video_codecs/video_decoder_factory.h" @@ -646,12 +647,14 @@ class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory { dependencies.network_thread = rtc::Thread::Current(); dependencies.signaling_thread = rtc::Thread::Current(); dependencies.task_queue_factory = CreateDefaultTaskQueueFactory(); + dependencies.trials = std::make_unique(); cricket::MediaEngineDependencies media_deps; media_deps.task_queue_factory = dependencies.task_queue_factory.get(); // Use fake audio device module since we're only testing the interface // level, and using a real one could make tests flaky when run in parallel. media_deps.adm = FakeAudioCaptureModule::Create(); SetMediaEngineDefaults(&media_deps); + media_deps.trials = dependencies.trials.get(); dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); dependencies.call_factory = webrtc::CreateCallFactory(); diff --git a/pc/peer_connection_jsep_unittest.cc b/pc/peer_connection_jsep_unittest.cc index ae151f0a3b..c3e093617b 100644 --- a/pc/peer_connection_jsep_unittest.cc +++ b/pc/peer_connection_jsep_unittest.cc @@ -11,6 +11,7 @@ #include #include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "media/engine/webrtc_media_engine.h" #include "media/engine/webrtc_media_engine_defaults.h" #include "pc/media_session.h" @@ -47,9 +48,11 @@ PeerConnectionFactoryDependencies CreatePeerConnectionFactoryDependencies() { dependencies.network_thread = rtc::Thread::Current(); dependencies.signaling_thread = rtc::Thread::Current(); dependencies.task_queue_factory = CreateDefaultTaskQueueFactory(); + dependencies.trials = std::make_unique(); cricket::MediaEngineDependencies media_deps; media_deps.task_queue_factory = dependencies.task_queue_factory.get(); media_deps.adm = FakeAudioCaptureModule::Create(); + media_deps.trials = dependencies.trials.get(); SetMediaEngineDefaults(&media_deps); dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); dependencies.call_factory = CreateCallFactory(); diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 289536e732..d2ee7b5824 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -973,6 +973,7 @@ if (is_ios || is_mac) { "../api/crypto:frame_encryptor_interface", "../api/rtc_event_log:rtc_event_log_factory", "../api/task_queue:default_task_queue_factory", + "../api/transport:field_trial_based_config", "../api/video:video_frame", "../api/video:video_rtp_headers", "../api/video_codecs:video_codecs_api", diff --git a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm index 3fa5159ec3..e466f99b99 100644 --- a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm +++ b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm @@ -37,6 +37,7 @@ #include "api/audio_codecs/builtin_audio_encoder_factory.h" // nogncheck #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "modules/audio_device/include/audio_device.h" // nogncheck #include "modules/audio_processing/include/audio_processing.h" // nogncheck @@ -190,6 +191,7 @@ } #ifndef HAVE_NO_MEDIA dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory(); + dependencies.trials = std::make_unique(); cricket::MediaEngineDependencies media_deps; media_deps.adm = std::move(audioDeviceModule); media_deps.task_queue_factory = dependencies.task_queue_factory.get(); @@ -202,6 +204,7 @@ } else { media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); } + media_deps.trials = dependencies.trials.get(); dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); dependencies.call_factory = webrtc::CreateCallFactory(); dependencies.event_log_factory = diff --git a/test/network/BUILD.gn b/test/network/BUILD.gn index 058f473d1b..71d0533546 100644 --- a/test/network/BUILD.gn +++ b/test/network/BUILD.gn @@ -93,6 +93,7 @@ rtc_library("network_emulation_pc_unittest") { "../../api:simulated_network_api", "../../api/rtc_event_log:rtc_event_log_factory", "../../api/task_queue:default_task_queue_factory", + "../../api/transport:field_trial_based_config", "../../call:simulated_network", "../../media:rtc_audio_video", "../../media:rtc_media_engine_defaults", diff --git a/test/network/network_emulation_pc_unittest.cc b/test/network/network_emulation_pc_unittest.cc index e04da34076..3d0140f5a2 100644 --- a/test/network/network_emulation_pc_unittest.cc +++ b/test/network/network_emulation_pc_unittest.cc @@ -16,6 +16,7 @@ #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/scoped_refptr.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "call/simulated_network.h" #include "media/engine/webrtc_media_engine.h" #include "media/engine/webrtc_media_engine_defaults.h" @@ -59,6 +60,7 @@ rtc::scoped_refptr CreatePeerConnectionFactory( std::make_unique(pcf_deps.task_queue_factory.get()); pcf_deps.network_thread = network_thread; pcf_deps.signaling_thread = signaling_thread; + pcf_deps.trials = std::make_unique(); cricket::MediaEngineDependencies media_deps; media_deps.task_queue_factory = pcf_deps.task_queue_factory.get(); media_deps.adm = TestAudioDeviceModule::Create( @@ -67,6 +69,7 @@ rtc::scoped_refptr CreatePeerConnectionFactory( kSamplingFrequency), TestAudioDeviceModule::CreateDiscardRenderer(kSamplingFrequency), /*speed=*/1.f); + media_deps.trials = pcf_deps.trials.get(); SetMediaEngineDefaults(&media_deps); pcf_deps.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); return CreateModularPeerConnectionFactory(std::move(pcf_deps)); diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn index 83f7ac6193..e00ab36796 100644 --- a/test/pc/e2e/BUILD.gn +++ b/test/pc/e2e/BUILD.gn @@ -58,6 +58,7 @@ if (!build_with_chromium) { "../../../api/rtc_event_log", "../../../api/task_queue", "../../../api/transport:network_control", + "../../../api/transport:webrtc_key_value_config", "../../../api/video_codecs:video_codecs_api", "../../../rtc_base", ] @@ -269,6 +270,7 @@ if (!build_with_chromium) { "../../../api:time_controller", "../../../api/rtc_event_log:rtc_event_log_factory", "../../../api/task_queue:default_task_queue_factory", + "../../../api/transport:field_trial_based_config", "../../../api/video_codecs:builtin_video_decoder_factory", "../../../api/video_codecs:builtin_video_encoder_factory", "../../../media:rtc_audio_video", diff --git a/test/pc/e2e/peer_connection_quality_test_params.h b/test/pc/e2e/peer_connection_quality_test_params.h index edefc7a008..e1c0232cb2 100644 --- a/test/pc/e2e/peer_connection_quality_test_params.h +++ b/test/pc/e2e/peer_connection_quality_test_params.h @@ -21,6 +21,7 @@ #include "api/task_queue/task_queue_factory.h" #include "api/test/peerconnection_quality_test_fixture.h" #include "api/transport/network_control.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_encoder_factory.h" #include "rtc_base/network.h" @@ -52,6 +53,8 @@ struct PeerConnectionFactoryComponents { // PeerConnectionFactory. std::unique_ptr video_encoder_factory; std::unique_ptr video_decoder_factory; + + std::unique_ptr trials; }; // Contains most parts from PeerConnectionDependencies. Also all fields are diff --git a/test/pc/e2e/test_peer_factory.cc b/test/pc/e2e/test_peer_factory.cc index 634a37e95b..eceec778df 100644 --- a/test/pc/e2e/test_peer_factory.cc +++ b/test/pc/e2e/test_peer_factory.cc @@ -16,6 +16,7 @@ #include "api/task_queue/default_task_queue_factory.h" #include "api/test/create_time_controller.h" #include "api/test/time_controller.h" +#include "api/transport/field_trial_based_config.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" @@ -64,6 +65,10 @@ void SetMandatoryEntities(InjectableComponents* components, std::make_unique( components->pcf_dependencies->task_queue_factory.get()); } + if (!components->pcf_dependencies->trials) { + components->pcf_dependencies->trials = + std::make_unique(); + } } // Returns mapping from stream label to optional spatial index. @@ -173,6 +178,9 @@ std::unique_ptr CreateMediaEngine( media_deps.video_decoder_factory = std::move(pcf_dependencies->video_decoder_factory); webrtc::SetMediaEngineDefaults(&media_deps); + RTC_DCHECK(pcf_dependencies->trials); + media_deps.trials = pcf_dependencies->trials.get(); + return cricket::CreateMediaEngine(std::move(media_deps)); } @@ -238,6 +246,9 @@ PeerConnectionFactoryDependencies CreatePCFDependencies( if (pcf_dependencies->neteq_factory != nullptr) { pcf_deps.neteq_factory = std::move(pcf_dependencies->neteq_factory); } + if (pcf_dependencies->trials != nullptr) { + pcf_deps.trials = std::move(pcf_dependencies->trials); + } return pcf_deps; } diff --git a/test/peer_scenario/BUILD.gn b/test/peer_scenario/BUILD.gn index bdc77b70c8..70a7471591 100644 --- a/test/peer_scenario/BUILD.gn +++ b/test/peer_scenario/BUILD.gn @@ -37,6 +37,7 @@ if (rtc_include_tests) { "../../api/audio_codecs:builtin_audio_encoder_factory", "../../api/rtc_event_log:rtc_event_log_factory", "../../api/task_queue:default_task_queue_factory", + "../../api/transport:field_trial_based_config", "../../api/video_codecs:builtin_video_decoder_factory", "../../api/video_codecs:builtin_video_encoder_factory", "../../media:rtc_audio_video", diff --git a/test/peer_scenario/peer_scenario_client.cc b/test/peer_scenario/peer_scenario_client.cc index 1ced030f34..681a90704f 100644 --- a/test/peer_scenario/peer_scenario_client.cc +++ b/test/peer_scenario/peer_scenario_client.cc @@ -18,6 +18,7 @@ #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/task_queue/default_task_queue_factory.h" #include "api/test/create_time_controller.h" +#include "api/transport/field_trial_based_config.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" @@ -197,6 +198,7 @@ PeerScenarioClient::PeerScenarioClient( net->time_controller()->CreateTaskQueueFactory(); pcf_deps.event_log_factory = std::make_unique(task_queue_factory_); + pcf_deps.trials = std::make_unique(); cricket::MediaEngineDependencies media_deps; media_deps.task_queue_factory = task_queue_factory_; @@ -221,6 +223,7 @@ PeerScenarioClient::PeerScenarioClient( } media_deps.audio_encoder_factory = CreateBuiltinAudioEncoderFactory(); media_deps.audio_decoder_factory = CreateBuiltinAudioDecoderFactory(); + media_deps.trials = pcf_deps.trials.get(); pcf_deps.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); pcf_deps.fec_controller_factory = nullptr;