diff --git a/media/BUILD.gn b/media/BUILD.gn index 493b883949..8729168da5 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -57,6 +57,7 @@ rtc_library("rtc_media_base") { "../api:rtp_parameters", "../api:scoped_refptr", "../api:sequence_checker", + "../api:webrtc_key_value_config", "../api/audio:audio_frame_processor", "../api/audio_codecs:audio_codecs_api", "../api/crypto:frame_decryptor_interface", @@ -64,7 +65,6 @@ rtc_library("rtc_media_base") { "../api/crypto:options", "../api/transport:datagram_transport_interface", "../api/transport:stun_types", - "../api/transport:webrtc_key_value_config", "../api/transport/rtp:rtp_source", "../api/units:time_delta", "../api/video:video_bitrate_allocation", @@ -453,6 +453,7 @@ rtc_library("rtc_data_sctp_transport_factory") { ] deps = [ ":rtc_data_sctp_transport_internal", + "../api:webrtc_key_value_config", "../api/transport:sctp_transport_factory_interface", "../rtc_base:threading", "../rtc_base/experiments:field_trial_parser", @@ -641,6 +642,7 @@ if (rtc_include_tests) { "../test:fake_video_codecs", "../test:field_trial", "../test:rtp_test_utils", + "../test:scoped_key_value_config", "../test:test_main", "../test:test_support", "../test:video_test_common", diff --git a/media/base/codec.cc b/media/base/codec.cc index 9b09f5e73b..a01914dff5 100644 --- a/media/base/codec.cc +++ b/media/base/codec.cc @@ -18,7 +18,6 @@ #include "rtc_base/logging.h" #include "rtc_base/string_encode.h" #include "rtc_base/strings/string_builder.h" -#include "system_wrappers/include/field_trial.h" namespace cricket { namespace { @@ -129,13 +128,14 @@ bool Codec::operator==(const Codec& c) const { feedback_params == c.feedback_params; } -bool Codec::Matches(const Codec& codec) const { +bool Codec::Matches(const Codec& codec, + const webrtc::WebRtcKeyValueConfig* field_trials) const { // Match the codec id/name based on the typical static/dynamic name rules. // Matching is case-insensitive. // Legacy behaviour with killswitch. - if (webrtc::field_trial::IsDisabled( - "WebRTC-PayloadTypes-Lower-Dynamic-Range")) { + if (field_trials && + field_trials->IsDisabled("WebRTC-PayloadTypes-Lower-Dynamic-Range")) { const int kMaxStaticPayloadId = 95; return (id <= kMaxStaticPayloadId || codec.id <= kMaxStaticPayloadId) ? (id == codec.id) @@ -238,7 +238,9 @@ bool AudioCodec::operator==(const AudioCodec& c) const { return bitrate == c.bitrate && channels == c.channels && Codec::operator==(c); } -bool AudioCodec::Matches(const AudioCodec& codec) const { +bool AudioCodec::Matches( + const AudioCodec& codec, + const webrtc::WebRtcKeyValueConfig* field_trials) const { // If a nonzero clockrate is specified, it must match the actual clockrate. // If a nonzero bitrate is specified, it must match the actual bitrate, // unless the codec is VBR (0), where we just force the supplied value. @@ -248,7 +250,7 @@ bool AudioCodec::Matches(const AudioCodec& codec) const { // omitted if the number of channels is one." // Preference is ignored. // TODO(juberti): Treat a zero clockrate as 8000Hz, the RTP default clockrate. - return Codec::Matches(codec) && + return Codec::Matches(codec, field_trials) && ((codec.clockrate == 0 /*&& clockrate == 8000*/) || clockrate == codec.clockrate) && (codec.bitrate == 0 || bitrate <= 0 || bitrate == codec.bitrate) && @@ -324,8 +326,10 @@ bool VideoCodec::operator==(const VideoCodec& c) const { return Codec::operator==(c) && packetization == c.packetization; } -bool VideoCodec::Matches(const VideoCodec& other) const { - return Codec::Matches(other) && +bool VideoCodec::Matches( + const VideoCodec& other, + const webrtc::WebRtcKeyValueConfig* field_trials) const { + return Codec::Matches(other, field_trials) && IsSameCodecSpecific(name, params, other.name, other.params); } diff --git a/media/base/codec.h b/media/base/codec.h index cfc31aed1f..70ecfd326d 100644 --- a/media/base/codec.h +++ b/media/base/codec.h @@ -19,6 +19,7 @@ #include "absl/types/optional.h" #include "api/rtp_parameters.h" #include "api/video_codecs/sdp_video_format.h" +#include "api/webrtc_key_value_config.h" #include "media/base/media_constants.h" #include "rtc_base/system/rtc_export.h" @@ -75,7 +76,9 @@ struct RTC_EXPORT Codec { virtual ~Codec(); // Indicates if this codec is compatible with the specified codec. - bool Matches(const Codec& codec) const; + bool Matches( + const Codec& codec, + const webrtc::WebRtcKeyValueConfig* field_trials = nullptr) const; bool MatchesCapability(const webrtc::RtpCodecCapability& capability) const; // Find the parameter for `name` and write the value to `out`. @@ -132,7 +135,9 @@ struct AudioCodec : public Codec { ~AudioCodec() override = default; // Indicates if this codec is compatible with the specified codec. - bool Matches(const AudioCodec& codec) const; + bool Matches( + const AudioCodec& codec, + const webrtc::WebRtcKeyValueConfig* field_trials = nullptr) const; std::string ToString() const; @@ -163,7 +168,9 @@ struct RTC_EXPORT VideoCodec : public Codec { // Indicates if this video codec is the same as the other video codec, e.g. if // they are both VP8 or VP9, or if they are both H264 with the same H264 // profile. H264 levels however are not compared. - bool Matches(const VideoCodec& codec) const; + bool Matches( + const VideoCodec& codec, + const webrtc::WebRtcKeyValueConfig* field_trials = nullptr) const; std::string ToString() const; diff --git a/media/base/media_engine.h b/media/base/media_engine.h index 1778104a30..7b4dbe4364 100644 --- a/media/base/media_engine.h +++ b/media/base/media_engine.h @@ -19,8 +19,8 @@ #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 "api/webrtc_key_value_config.h" #include "call/audio_state.h" #include "media/base/codec.h" #include "media/base/media_channel.h" diff --git a/media/base/test_utils.h b/media/base/test_utils.h index 22bda4f12a..fbd9f35184 100644 --- a/media/base/test_utils.h +++ b/media/base/test_utils.h @@ -37,10 +37,12 @@ inline std::vector MakeVector(const T a[], size_t s) { // Checks whether `codecs` contains `codec`; checks using Codec::Matches(). template -bool ContainsMatchingCodec(const std::vector& codecs, const C& codec) { +bool ContainsMatchingCodec(const std::vector& codecs, + const C& codec, + const webrtc::WebRtcKeyValueConfig* field_trials) { typename std::vector::const_iterator it; for (it = codecs.begin(); it != codecs.end(); ++it) { - if (it->Matches(codec)) { + if (it->Matches(codec, field_trials)) { return true; } } diff --git a/media/engine/webrtc_media_engine_unittest.cc b/media/engine/webrtc_media_engine_unittest.cc index 81982fae2b..79efea4e9c 100644 --- a/media/engine/webrtc_media_engine_unittest.cc +++ b/media/engine/webrtc_media_engine_unittest.cc @@ -13,10 +13,9 @@ #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" +#include "test/scoped_key_value_config.h" using webrtc::RtpExtension; @@ -129,7 +128,7 @@ TEST(WebRtcMediaEngineTest, ValidateRtpExtensionsChangeIdForUrl) { TEST(WebRtcMediaEngineTest, FilterRtpExtensionsEmptyList) { std::vector extensions; - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions1, true, trials); EXPECT_EQ(0u, filtered.size()); @@ -137,7 +136,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsEmptyList) { TEST(WebRtcMediaEngineTest, FilterRtpExtensionsIncludeOnlySupported) { std::vector extensions = MakeUniqueExtensions(); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions1, false, trials); EXPECT_EQ(2u, filtered.size()); @@ -147,7 +146,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsIncludeOnlySupported) { TEST(WebRtcMediaEngineTest, FilterRtpExtensionsSortedByName1) { std::vector extensions = MakeUniqueExtensions(); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, false, trials); EXPECT_EQ(12u, filtered.size()); @@ -156,7 +155,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsSortedByName1) { TEST(WebRtcMediaEngineTest, FilterRtpExtensionsSortedByName2) { std::vector extensions = MakeUniqueExtensions(); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(12u, filtered.size()); @@ -165,7 +164,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsSortedByName2) { TEST(WebRtcMediaEngineTest, FilterRtpExtensionsDontRemoveRedundant) { std::vector extensions = MakeRedundantExtensions(); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, false, trials); EXPECT_EQ(12u, filtered.size()); @@ -175,7 +174,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsDontRemoveRedundant) { TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundant) { std::vector extensions = MakeRedundantExtensions(); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(6u, filtered.size()); @@ -189,7 +188,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantEncrypted1) { 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; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(3u, filtered.size()); @@ -206,7 +205,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantEncrypted2) { extensions.push_back(webrtc::RtpExtension("b", 2)); extensions.push_back(webrtc::RtpExtension("c", 3)); extensions.push_back(webrtc::RtpExtension("b", 4)); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(3u, filtered.size()); @@ -218,9 +217,8 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantEncrypted2) { } TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantBwe1) { - webrtc::test::ScopedFieldTrials override_field_trials_( + webrtc::test::ScopedKeyValueConfig trials( "WebRTC-FilterAbsSendTimeExtension/Enabled/"); - webrtc::FieldTrialBasedConfig trials; std::vector extensions; extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 3)); @@ -245,7 +243,7 @@ TEST(WebRtcMediaEngineTest, extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 1)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(2u, filtered.size()); @@ -254,9 +252,8 @@ TEST(WebRtcMediaEngineTest, } TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantBweEncrypted1) { - webrtc::test::ScopedFieldTrials override_field_trials_( + webrtc::test::ScopedKeyValueConfig trials( "WebRTC-FilterAbsSendTimeExtension/Enabled/"); - webrtc::FieldTrialBasedConfig trials; std::vector extensions; extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 3)); @@ -291,7 +288,7 @@ TEST(WebRtcMediaEngineTest, extensions.push_back( RtpExtension(RtpExtension::kTransportSequenceNumberUri, 2, true)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(3u, filtered.size()); @@ -306,7 +303,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantBwe2) { extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 1)); extensions.push_back(RtpExtension(RtpExtension::kAbsSendTimeUri, 14)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 7)); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(1u, filtered.size()); @@ -317,7 +314,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantBwe3) { std::vector extensions; extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 2)); extensions.push_back(RtpExtension(RtpExtension::kTimestampOffsetUri, 14)); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; std::vector filtered = FilterRtpExtensions(extensions, SupportedExtensions2, true, trials); EXPECT_EQ(1u, filtered.size()); @@ -327,7 +324,7 @@ TEST(WebRtcMediaEngineTest, FilterRtpExtensionsRemoveRedundantBwe3) { TEST(WebRtcMediaEngineTest, Create) { MediaEngineDependencies deps; webrtc::SetMediaEngineDefaults(&deps); - webrtc::FieldTrialBasedConfig trials; + webrtc::test::ScopedKeyValueConfig trials; deps.trials = &trials; std::unique_ptr engine = diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index a1aa88de7b..ab9ad1aab6 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -60,11 +60,10 @@ #include "rtc_base/gunit.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/time_utils.h" -#include "system_wrappers/include/field_trial.h" #include "test/fake_decoder.h" -#include "test/field_trial.h" #include "test/frame_forwarder.h" #include "test/gmock.h" +#include "test/scoped_key_value_config.h" #include "test/time_controller/simulated_time_controller.h" using ::testing::_; @@ -244,12 +243,8 @@ class WebRtcVideoEngineTest : public ::testing::Test { public: WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {} explicit WebRtcVideoEngineTest(const std::string& field_trials) - : time_controller_(webrtc::Timestamp::Millis(4711)), - override_field_trials_( - field_trials.empty() - ? nullptr - : std::make_unique( - field_trials)), + : field_trials_(field_trials), + time_controller_(webrtc::Timestamp::Millis(4711)), task_queue_factory_(time_controller_.CreateTaskQueueFactory()), call_(webrtc::Call::Create([&] { webrtc::Call::Config call_config(&event_log_); @@ -286,9 +281,8 @@ class WebRtcVideoEngineTest : public ::testing::Test { void ExpectRtpCapabilitySupport(const char* uri, bool supported) const; + webrtc::test::ScopedKeyValueConfig field_trials_; webrtc::GlobalSimulatedTimeController time_controller_; - std::unique_ptr override_field_trials_; - webrtc::FieldTrialBasedConfig field_trials_; webrtc::RtcEventLogNull event_log_; std::unique_ptr task_queue_factory_; // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly @@ -936,9 +930,8 @@ TEST_F(WebRtcVideoEngineTest, } TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) { - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-H264Simulcast/Enabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-H264Simulcast/Enabled/"); AddSupportedVideoCodecType("H264"); std::unique_ptr channel(engine_.CreateMediaChannel( @@ -978,9 +971,8 @@ TEST_F(WebRtcVideoEngineTest, Flexfec03SendCodecEnablesWithFieldTrial) { EXPECT_THAT(engine_.send_codecs(), Not(Contains(flexfec))); - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-FlexFEC-03-Advertised/Enabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-FlexFEC-03-Advertised/Enabled/"); EXPECT_THAT(engine_.send_codecs(), Contains(flexfec)); } @@ -993,9 +985,8 @@ TEST_F(WebRtcVideoEngineTest, Flexfec03ReceiveCodecDisablesWithFieldTrial) { EXPECT_THAT(engine_.recv_codecs(), Contains(flexfec)); - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-FlexFEC-03-Advertised/Disabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-FlexFEC-03-Advertised/Disabled/"); EXPECT_THAT(engine_.recv_codecs(), Not(Contains(flexfec))); } @@ -1006,9 +997,8 @@ TEST_F(WebRtcVideoEngineTest, Flexfec03LowerPayloadTypeRange) { auto flexfec = Field("name", &VideoCodec::name, "flexfec-03"); // FlexFEC is active with field trial. - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-FlexFEC-03-Advertised/Enabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-FlexFEC-03-Advertised/Enabled/"); auto send_codecs = engine_.send_codecs(); auto it = std::find_if(send_codecs.begin(), send_codecs.end(), [](const cricket::VideoCodec& codec) { @@ -1452,7 +1442,7 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { } static const std::vector kSdpVideoFormats; - webrtc::FieldTrialBasedConfig field_trials_; + webrtc::test::ScopedKeyValueConfig field_trials_; webrtc::RtcEventLogNull event_log_; std::unique_ptr task_queue_factory_; std::unique_ptr call_; @@ -1740,8 +1730,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { } webrtc::RtcEventLogNull event_log_; - webrtc::FieldTrialBasedConfig field_trials_; - std::unique_ptr override_field_trials_; + webrtc::test::ScopedKeyValueConfig field_trials_; std::unique_ptr task_queue_factory_; std::unique_ptr call_; std::unique_ptr @@ -1796,9 +1785,8 @@ TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSize) { // Set field trial to override the default recv buffer size, and then re-run // setup where the interface is created and configured. const int kCustomRecvBufferSize = 123456; - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-IncreasedReceivebuffers/123456/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-IncreasedReceivebuffers/123456/"); ResetTest(); @@ -1814,9 +1802,8 @@ TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSizeWithSuffix) { // Set field trial to override the default recv buffer size, and then re-run // setup where the interface is created and configured. const int kCustomRecvBufferSize = 123456; - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-IncreasedReceivebuffers/123456_Dogfood/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-IncreasedReceivebuffers/123456_Dogfood/"); ResetTest(); EXPECT_TRUE(SetOneCodec(DefaultCodec())); @@ -1832,8 +1819,6 @@ TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) { // then re-run setup where the interface is created and configured. The // default value should still be used. - const char* prev_field_trials = webrtc::field_trial::GetFieldTrialString(); - std::string field_trial_string; for (std::string group : {" ", "NotANumber", "-1", "0"}) { std::string trial_string = "WebRTC-IncreasedReceivebuffers/"; @@ -1858,8 +1843,8 @@ TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) { }); waiting.Wait(rtc::Event::kForever); - field_trial_string = std::move(trial_string); - webrtc::field_trial::InitFieldTrialsFromString(field_trial_string.c_str()); + webrtc::test::ScopedKeyValueConfig field_trial_override(field_trials_, + trial_string); SetUp(); resume.Set(); @@ -1873,8 +1858,6 @@ TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) { EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size()); EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size()); } - - webrtc::field_trial::InitFieldTrialsFromString(prev_field_trials); } // Test that stats work properly for a 1-1 call. @@ -3177,17 +3160,15 @@ TEST_F(WebRtcVideoChannelTest, LossNotificationIsDisabledByDefault) { } TEST_F(WebRtcVideoChannelTest, LossNotificationIsEnabledByFieldTrial) { - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-RtcpLossNotification/Enabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-RtcpLossNotification/Enabled/"); ResetTest(); TestLossNotificationState(true); } TEST_F(WebRtcVideoChannelTest, LossNotificationCanBeEnabledAndDisabled) { - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-RtcpLossNotification/Enabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-RtcpLossNotification/Enabled/"); ResetTest(); AssignDefaultCodec(); @@ -3788,8 +3769,8 @@ TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) { } TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) { - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/"); std::vector streams = AddSendStream()->GetVideoStreams(); ASSERT_EQ(1u, streams.size()); @@ -3798,9 +3779,8 @@ TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) { TEST_F(WebRtcVideoChannelTest, BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) { - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-Video-BalancedDegradation/Disabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-Video-BalancedDegradation/Disabled/"); const bool kResolutionScalingEnabled = true; const bool kFpsScalingEnabled = false; TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled); @@ -3808,9 +3788,8 @@ TEST_F(WebRtcVideoChannelTest, TEST_F(WebRtcVideoChannelTest, BalancedDegradationPreferenceSupportedBehindFieldtrial) { - RTC_DCHECK(!override_field_trials_); - override_field_trials_ = std::make_unique( - "WebRTC-Video-BalancedDegradation/Enabled/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-Video-BalancedDegradation/Enabled/"); const bool kResolutionScalingEnabled = true; const bool kFpsScalingEnabled = true; TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled); @@ -4000,7 +3979,7 @@ TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) { VideoCodec codec; EXPECT_TRUE(channel_->GetSendCodec(&codec)); - EXPECT_TRUE(codec.Matches(engine_.send_codecs()[0])); + EXPECT_TRUE(codec.Matches(engine_.send_codecs()[0], &field_trials_)); // Using a RTX setup to verify that the default RTX payload type is good. const std::vector ssrcs = MAKE_VECTOR(kSsrcs1); @@ -8857,7 +8836,7 @@ class WebRtcVideoChannelSimulcastTest : public ::testing::Test { cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_; std::unique_ptr mock_rate_allocator_factory_; - webrtc::FieldTrialBasedConfig field_trials_; + webrtc::test::ScopedKeyValueConfig 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 7f01b95642..a229658493 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -125,9 +125,10 @@ bool IsCodec(const AudioCodec& codec, const char* ref_name) { bool FindCodec(const std::vector& codecs, const AudioCodec& codec, - AudioCodec* found_codec) { + AudioCodec* found_codec, + const webrtc::WebRtcKeyValueConfig* field_trials) { for (const AudioCodec& c : codecs) { - if (c.Matches(codec)) { + if (c.Matches(codec, field_trials)) { if (found_codec != NULL) { *found_codec = c; } @@ -1557,7 +1558,7 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs( // Log a warning if a codec's payload type is changing. This used to be // treated as an error. It's abnormal, but not really illegal. AudioCodec old_codec; - if (FindCodec(recv_codecs_, codec, &old_codec) && + if (FindCodec(recv_codecs_, codec, &old_codec, &call_->trials()) && old_codec.id != codec.id) { RTC_LOG(LS_WARNING) << codec.name << " mapped to a second payload type (" << codec.id << ", was already mapped to " diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc index a9f4f22cdc..9ff91f4ff6 100644 --- a/media/engine/webrtc_voice_engine_unittest.cc +++ b/media/engine/webrtc_voice_engine_unittest.cc @@ -33,10 +33,10 @@ #include "rtc_base/arraysize.h" #include "rtc_base/byte_order.h" #include "rtc_base/numerics/safe_conversions.h" -#include "test/field_trial.h" #include "test/gtest.h" #include "test/mock_audio_decoder_factory.h" #include "test/mock_audio_encoder_factory.h" +#include "test/scoped_key_value_config.h" using ::testing::_; using ::testing::ContainerEq; @@ -180,9 +180,7 @@ class FakeAudioSource : public cricket::AudioSource { class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { public: - WebRtcVoiceEngineTestFake() : WebRtcVoiceEngineTestFake("") {} - - explicit WebRtcVoiceEngineTestFake(const char* field_trials) + WebRtcVoiceEngineTestFake() : use_null_apm_(GetParam()), task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()), adm_(webrtc::test::MockAudioDeviceModule::CreateStrict()), @@ -190,8 +188,7 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { ? nullptr : rtc::make_ref_counted< StrictMock>()), - call_(), - override_field_trials_(field_trials) { + call_() { // AudioDeviceModule. AdmSetupExpectations(adm_); @@ -212,7 +209,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, trials_config_)); + nullptr, apm_, nullptr, field_trials_)); engine_->Init(); send_parameters_.codecs.push_back(kPcmuCodec); recv_parameters_.codecs.push_back(kPcmuCodec); @@ -800,10 +797,7 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { cricket::AudioRecvParameters recv_parameters_; FakeAudioSource fake_source_; webrtc::AudioProcessing::Config apm_config_; - - private: - webrtc::test::ScopedFieldTrials override_field_trials_; - webrtc::FieldTrialBasedConfig trials_config_; + webrtc::test::ScopedKeyValueConfig field_trials_; }; INSTANTIATE_TEST_SUITE_P(TestBothWithAndWithoutNullApm, @@ -1232,8 +1226,8 @@ TEST_P(WebRtcVoiceEngineTestFake, } TEST_P(WebRtcVoiceEngineTestFake, AdaptivePtimeFieldTrial) { - webrtc::test::ScopedFieldTrials override_field_trials( - "WebRTC-Audio-AdaptivePtime/enabled:true/"); + webrtc::test::ScopedKeyValueConfig override_field_trials( + field_trials_, "WebRTC-Audio-AdaptivePtime/enabled:true/"); EXPECT_TRUE(SetupSendStream()); EXPECT_TRUE(GetAudioNetworkAdaptorConfig(kSsrcX)); } @@ -2503,14 +2497,6 @@ TEST_P(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) { GetAudioNetworkAdaptorConfig(kSsrcX)); } -class WebRtcVoiceEngineWithSendSideBweWithOverheadTest - : public WebRtcVoiceEngineTestFake { - public: - WebRtcVoiceEngineWithSendSideBweWithOverheadTest() - : WebRtcVoiceEngineTestFake( - "WebRTC-Audio-Allocation/min:6000bps,max:32000bps/") {} -}; - // Test that we can set the outgoing SSRC properly. // SSRC is set in SetupSendStream() by calling AddSendStream. TEST_P(WebRtcVoiceEngineTestFake, SetSendSsrc) { diff --git a/media/sctp/sctp_transport_factory.cc b/media/sctp/sctp_transport_factory.cc index 071d7fdb23..21b5b026eb 100644 --- a/media/sctp/sctp_transport_factory.cc +++ b/media/sctp/sctp_transport_factory.cc @@ -10,12 +10,12 @@ #include "media/sctp/sctp_transport_factory.h" +#include "api/webrtc_key_value_config.h" #include "rtc_base/system/unused.h" #ifdef WEBRTC_HAVE_DCSCTP #include "media/sctp/dcsctp_transport.h" // nogncheck #include "system_wrappers/include/clock.h" // nogncheck -#include "system_wrappers/include/field_trial.h" // nogncheck #endif #ifdef WEBRTC_HAVE_USRSCTP @@ -24,12 +24,14 @@ namespace cricket { -SctpTransportFactory::SctpTransportFactory(rtc::Thread* network_thread) +SctpTransportFactory::SctpTransportFactory( + rtc::Thread* network_thread, + const webrtc::WebRtcKeyValueConfig& field_trials) : network_thread_(network_thread), use_usrsctp_("Disabled", false) { RTC_UNUSED(network_thread_); #ifdef WEBRTC_HAVE_DCSCTP - webrtc::ParseFieldTrial({&use_usrsctp_}, webrtc::field_trial::FindFullName( - "WebRTC-DataChannel-Dcsctp")); + webrtc::ParseFieldTrial({&use_usrsctp_}, + field_trials.Lookup("WebRTC-DataChannel-Dcsctp")); #endif } diff --git a/media/sctp/sctp_transport_factory.h b/media/sctp/sctp_transport_factory.h index 9ae246a6a6..4fcec8e0e0 100644 --- a/media/sctp/sctp_transport_factory.h +++ b/media/sctp/sctp_transport_factory.h @@ -14,6 +14,7 @@ #include #include "api/transport/sctp_transport_factory_interface.h" +#include "api/webrtc_key_value_config.h" #include "media/sctp/sctp_transport_internal.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/thread.h" @@ -22,7 +23,9 @@ namespace cricket { class SctpTransportFactory : public webrtc::SctpTransportFactoryInterface { public: - explicit SctpTransportFactory(rtc::Thread* network_thread); + explicit SctpTransportFactory( + rtc::Thread* network_thread, + const webrtc::WebRtcKeyValueConfig& field_trials); std::unique_ptr CreateSctpTransport( rtc::PacketTransportInternal* transport) override; diff --git a/pc/channel_manager_unittest.cc b/pc/channel_manager_unittest.cc index 7d7d3e475f..7b0146c976 100644 --- a/pc/channel_manager_unittest.cc +++ b/pc/channel_manager_unittest.cc @@ -99,25 +99,25 @@ TEST_F(ChannelManagerTest, SetVideoRtxEnabled) { // By default RTX is disabled. cm_->GetSupportedVideoSendCodecs(&send_codecs); - EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec)); + EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec, &field_trials_)); cm_->GetSupportedVideoSendCodecs(&recv_codecs); - EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec)); + EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec, &field_trials_)); // Enable and check. cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(), true, worker_, network_.get()); cm_->GetSupportedVideoSendCodecs(&send_codecs); - EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec)); + EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec, &field_trials_)); cm_->GetSupportedVideoSendCodecs(&recv_codecs); - EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec)); + EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec, &field_trials_)); // Disable and check. cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(), false, worker_, network_.get()); cm_->GetSupportedVideoSendCodecs(&send_codecs); - EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec)); + EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec, &field_trials_)); cm_->GetSupportedVideoSendCodecs(&recv_codecs); - EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec)); + EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec, &field_trials_)); } TEST_F(ChannelManagerTest, CreateDestroyChannels) { diff --git a/pc/channel_unittest.cc b/pc/channel_unittest.cc index 463f60bf35..725ee34918 100644 --- a/pc/channel_unittest.cc +++ b/pc/channel_unittest.cc @@ -2020,9 +2020,11 @@ TEST_F(VideoChannelSingleThreadTest, TestSetLocalOfferWithPacketization) { EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, err)); EXPECT_THAT(media_channel1()->send_codecs(), testing::IsEmpty()); ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2)); - EXPECT_TRUE(media_channel1()->recv_codecs()[0].Matches(kVp8Codec)); + EXPECT_TRUE( + media_channel1()->recv_codecs()[0].Matches(kVp8Codec, &field_trials_)); EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE(media_channel1()->recv_codecs()[1].Matches(vp9_codec)); + EXPECT_TRUE( + media_channel1()->recv_codecs()[1].Matches(vp9_codec, &field_trials_)); EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization, cricket::kPacketizationParamRaw); } @@ -2041,9 +2043,11 @@ TEST_F(VideoChannelSingleThreadTest, TestSetRemoteOfferWithPacketization) { EXPECT_TRUE(err.empty()); EXPECT_THAT(media_channel1()->recv_codecs(), testing::IsEmpty()); ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2)); - EXPECT_TRUE(media_channel1()->send_codecs()[0].Matches(kVp8Codec)); + EXPECT_TRUE( + media_channel1()->send_codecs()[0].Matches(kVp8Codec, &field_trials_)); EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE(media_channel1()->send_codecs()[1].Matches(vp9_codec)); + EXPECT_TRUE( + media_channel1()->send_codecs()[1].Matches(vp9_codec, &field_trials_)); EXPECT_EQ(media_channel1()->send_codecs()[1].packetization, cricket::kPacketizationParamRaw); } @@ -2063,15 +2067,19 @@ TEST_F(VideoChannelSingleThreadTest, TestSetAnswerWithPacketization) { EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kAnswer, err)); EXPECT_TRUE(err.empty()); ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2)); - EXPECT_TRUE(media_channel1()->recv_codecs()[0].Matches(kVp8Codec)); + EXPECT_TRUE( + media_channel1()->recv_codecs()[0].Matches(kVp8Codec, &field_trials_)); EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE(media_channel1()->recv_codecs()[1].Matches(vp9_codec)); + EXPECT_TRUE( + media_channel1()->recv_codecs()[1].Matches(vp9_codec, &field_trials_)); EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization, cricket::kPacketizationParamRaw); EXPECT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2)); - EXPECT_TRUE(media_channel1()->send_codecs()[0].Matches(kVp8Codec)); + EXPECT_TRUE( + media_channel1()->send_codecs()[0].Matches(kVp8Codec, &field_trials_)); EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE(media_channel1()->send_codecs()[1].Matches(vp9_codec)); + EXPECT_TRUE( + media_channel1()->send_codecs()[1].Matches(vp9_codec, &field_trials_)); EXPECT_EQ(media_channel1()->send_codecs()[1].packetization, cricket::kPacketizationParamRaw); } diff --git a/pc/connection_context.cc b/pc/connection_context.cc index 31810bca62..8583e7ba04 100644 --- a/pc/connection_context.cc +++ b/pc/connection_context.cc @@ -79,7 +79,8 @@ std::unique_ptr MaybeCreateSctpFactory( return factory; } #ifdef WEBRTC_HAVE_SCTP - return std::make_unique(network_thread); + return std::make_unique(network_thread, + field_trials); #else return nullptr; #endif diff --git a/pc/media_session.cc b/pc/media_session.cc index 9aeae708d7..2ab661cd69 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -726,13 +726,16 @@ static bool CreateMediaContentOffer( } template -static bool ReferencedCodecsMatch(const std::vector& codecs1, - const int codec1_id, - const std::vector& codecs2, - const int codec2_id) { +static bool ReferencedCodecsMatch( + const std::vector& codecs1, + const int codec1_id, + const std::vector& codecs2, + const int codec2_id, + const webrtc::WebRtcKeyValueConfig* field_trials) { const C* codec1 = FindCodecById(codecs1, codec1_id); const C* codec2 = FindCodecById(codecs2, codec2_id); - return codec1 != nullptr && codec2 != nullptr && codec1->Matches(*codec2); + return codec1 != nullptr && codec2 != nullptr && + codec1->Matches(*codec2, field_trials); } template @@ -752,12 +755,14 @@ template static void NegotiateCodecs(const std::vector& local_codecs, const std::vector& offered_codecs, std::vector* negotiated_codecs, - bool keep_offer_order) { + bool keep_offer_order, + const webrtc::WebRtcKeyValueConfig* field_trials) { for (const C& ours : local_codecs) { C theirs; // Note that we intentionally only find one matching codec for each of our // local codecs, in case the remote offer contains duplicate codecs. - if (FindMatchingCodec(local_codecs, offered_codecs, ours, &theirs)) { + if (FindMatchingCodec(local_codecs, offered_codecs, ours, &theirs, + field_trials)) { C negotiated = ours; NegotiatePacketization(ours, theirs, &negotiated); negotiated.IntersectFeedbackParams(theirs); @@ -810,10 +815,12 @@ static void NegotiateCodecs(const std::vector& local_codecs, // a member of `codecs1`. If `codec_to_match` is an RED or RTX codec, both // the codecs themselves and their associated codecs must match. template -static bool FindMatchingCodec(const std::vector& codecs1, - const std::vector& codecs2, - const C& codec_to_match, - C* found_codec) { +static bool FindMatchingCodec( + const std::vector& codecs1, + const std::vector& codecs2, + const C& codec_to_match, + C* found_codec, + const webrtc::WebRtcKeyValueConfig* field_trials) { // `codec_to_match` should be a member of `codecs1`, in order to look up // RED/RTX codecs' associated codecs correctly. If not, that's a programming // error. @@ -821,7 +828,7 @@ static bool FindMatchingCodec(const std::vector& codecs1, return &codec == &codec_to_match; })); for (const C& potential_match : codecs2) { - if (potential_match.Matches(codec_to_match)) { + if (potential_match.Matches(codec_to_match, field_trials)) { if (IsRtxCodec(codec_to_match)) { int apt_value_1 = 0; int apt_value_2 = 0; @@ -832,8 +839,8 @@ static bool FindMatchingCodec(const std::vector& codecs1, RTC_LOG(LS_WARNING) << "RTX missing associated payload type."; continue; } - if (!ReferencedCodecsMatch(codecs1, apt_value_1, codecs2, - apt_value_2)) { + if (!ReferencedCodecsMatch(codecs1, apt_value_1, codecs2, apt_value_2, + field_trials)) { continue; } } else if (IsRedCodec(codec_to_match)) { @@ -876,7 +883,7 @@ static bool FindMatchingCodec(const std::vector& codecs1, if (rtc::FromString(redundant_payloads_1[0], &red_value_1) && rtc::FromString(redundant_payloads_2[0], &red_value_2)) { if (!ReferencedCodecsMatch(codecs1, red_value_1, codecs2, - red_value_2)) { + red_value_2, field_trials)) { continue; } } @@ -967,14 +974,15 @@ static const C* GetAssociatedCodecForRed(const std::vector& codec_list, template static void MergeCodecs(const std::vector& reference_codecs, std::vector* offered_codecs, - UsedPayloadTypes* used_pltypes) { + UsedPayloadTypes* used_pltypes, + const webrtc::WebRtcKeyValueConfig* field_trials) { // Add all new codecs that are not RTX/RED codecs. // The two-pass splitting of the loops means preferring payload types // of actual codecs with respect to collisions. for (const C& reference_codec : reference_codecs) { if (!IsRtxCodec(reference_codec) && !IsRedCodec(reference_codec) && !FindMatchingCodec(reference_codecs, *offered_codecs, - reference_codec, nullptr)) { + reference_codec, nullptr, field_trials)) { C codec = reference_codec; used_pltypes->FindAndSetIdUsed(&codec); offered_codecs->push_back(codec); @@ -985,7 +993,7 @@ static void MergeCodecs(const std::vector& reference_codecs, for (const C& reference_codec : reference_codecs) { if (IsRtxCodec(reference_codec) && !FindMatchingCodec(reference_codecs, *offered_codecs, - reference_codec, nullptr)) { + reference_codec, nullptr, field_trials)) { C rtx_codec = reference_codec; const C* associated_codec = GetAssociatedCodecForRtx(reference_codecs, rtx_codec); @@ -996,7 +1004,8 @@ static void MergeCodecs(const std::vector& reference_codecs, // Its payload type may be different than the reference codec. C matching_codec; if (!FindMatchingCodec(reference_codecs, *offered_codecs, - *associated_codec, &matching_codec)) { + *associated_codec, &matching_codec, + field_trials)) { RTC_LOG(LS_WARNING) << "Couldn't find matching " << associated_codec->name << " codec."; continue; @@ -1008,14 +1017,15 @@ static void MergeCodecs(const std::vector& reference_codecs, offered_codecs->push_back(rtx_codec); } else if (IsRedCodec(reference_codec) && !FindMatchingCodec(reference_codecs, *offered_codecs, - reference_codec, nullptr)) { + reference_codec, nullptr, field_trials)) { C red_codec = reference_codec; const C* associated_codec = GetAssociatedCodecForRed(reference_codecs, red_codec); if (associated_codec) { C matching_codec; if (!FindMatchingCodec(reference_codecs, *offered_codecs, - *associated_codec, &matching_codec)) { + *associated_codec, &matching_codec, + field_trials)) { RTC_LOG(LS_WARNING) << "Couldn't find matching " << associated_codec->name << " codec."; continue; @@ -1039,7 +1049,8 @@ template static Codecs MatchCodecPreference( const std::vector& codec_preferences, const Codecs& codecs, - const Codecs& supported_codecs) { + const Codecs& supported_codecs, + const webrtc::WebRtcKeyValueConfig* field_trials) { Codecs filtered_codecs; bool want_rtx = false; bool want_red = false; @@ -1068,7 +1079,7 @@ static Codecs MatchCodecPreference( if (found_codec != supported_codecs.end()) { typename Codecs::value_type found_codec_with_correct_pt; if (FindMatchingCodec(supported_codecs, codecs, *found_codec, - &found_codec_with_correct_pt)) { + &found_codec_with_correct_pt, field_trials)) { filtered_codecs.push_back(found_codec_with_correct_pt); std::string id = rtc::ToString(found_codec_with_correct_pt.id); // Search for the matching rtx or red codec. @@ -1111,8 +1122,10 @@ static Codecs MatchCodecPreference( // Compute the union of `codecs1` and `codecs2`. template -std::vector ComputeCodecsUnion(const std::vector& codecs1, - const std::vector& codecs2) { +std::vector ComputeCodecsUnion( + const std::vector& codecs1, + const std::vector& codecs2, + const webrtc::WebRtcKeyValueConfig* field_trials) { std::vector all_codecs; UsedPayloadTypes used_payload_types; for (const C& codec : codecs1) { @@ -1123,7 +1136,7 @@ std::vector ComputeCodecsUnion(const std::vector& codecs1, // Use MergeCodecs to merge the second half of our list as it already checks // and fixes problems with duplicate payload types. - MergeCodecs(codecs2, &all_codecs, &used_payload_types); + MergeCodecs(codecs2, &all_codecs, &used_payload_types, field_trials); return all_codecs; } @@ -1355,7 +1368,8 @@ static bool SetCodecsInAnswer( const webrtc::WebRtcKeyValueConfig& field_trials) { std::vector negotiated_codecs; NegotiateCodecs(local_codecs, offer->codecs(), &negotiated_codecs, - media_description_options.codec_preferences.empty()); + media_description_options.codec_preferences.empty(), + &field_trials); answer->AddCodecs(negotiated_codecs); answer->set_protocol(offer->protocol()); if (!AddStreamParams(media_description_options.sender_options, @@ -2039,16 +2053,19 @@ void MergeCodecsFromDescription( const std::vector& current_active_contents, AudioCodecs* audio_codecs, VideoCodecs* video_codecs, - UsedPayloadTypes* used_pltypes) { + UsedPayloadTypes* used_pltypes, + const webrtc::WebRtcKeyValueConfig* field_trials) { for (const ContentInfo* content : current_active_contents) { if (IsMediaContentOfType(content, MEDIA_TYPE_AUDIO)) { const AudioContentDescription* audio = content->media_description()->as_audio(); - MergeCodecs(audio->codecs(), audio_codecs, used_pltypes); + MergeCodecs(audio->codecs(), audio_codecs, used_pltypes, + field_trials); } else if (IsMediaContentOfType(content, MEDIA_TYPE_VIDEO)) { const VideoContentDescription* video = content->media_description()->as_video(); - MergeCodecs(video->codecs(), video_codecs, used_pltypes); + MergeCodecs(video->codecs(), video_codecs, used_pltypes, + field_trials); } } } @@ -2063,16 +2080,20 @@ void MediaSessionDescriptionFactory::GetCodecsForOffer( const std::vector& current_active_contents, AudioCodecs* audio_codecs, VideoCodecs* video_codecs) const { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); // First - get all codecs from the current description if the media type // is used. Add them to `used_pltypes` so the payload type is not reused if a // new media type is added. UsedPayloadTypes used_pltypes; MergeCodecsFromDescription(current_active_contents, audio_codecs, - video_codecs, &used_pltypes); + video_codecs, &used_pltypes, field_trials); // Add our codecs that are not in the current description. - MergeCodecs(all_audio_codecs_, audio_codecs, &used_pltypes); - MergeCodecs(all_video_codecs_, video_codecs, &used_pltypes); + MergeCodecs(all_audio_codecs_, audio_codecs, &used_pltypes, + field_trials); + MergeCodecs(all_video_codecs_, video_codecs, &used_pltypes, + field_trials); } // Getting codecs for an answer involves these steps: @@ -2087,12 +2108,14 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( const SessionDescription& remote_offer, AudioCodecs* audio_codecs, VideoCodecs* video_codecs) const { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); // First - get all codecs from the current description if the media type // is used. Add them to `used_pltypes` so the payload type is not reused if a // new media type is added. UsedPayloadTypes used_pltypes; MergeCodecsFromDescription(current_active_contents, audio_codecs, - video_codecs, &used_pltypes); + video_codecs, &used_pltypes, field_trials); // Second - filter out codecs that we don't support at all and should ignore. AudioCodecs filtered_offered_audio_codecs; @@ -2102,11 +2125,12 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( const AudioContentDescription* audio = content.media_description()->as_audio(); for (const AudioCodec& offered_audio_codec : audio->codecs()) { - if (!FindMatchingCodec(audio->codecs(), - filtered_offered_audio_codecs, - offered_audio_codec, nullptr) && + if (!FindMatchingCodec( + audio->codecs(), filtered_offered_audio_codecs, + offered_audio_codec, nullptr, field_trials) && FindMatchingCodec(audio->codecs(), all_audio_codecs_, - offered_audio_codec, nullptr)) { + offered_audio_codec, nullptr, + field_trials)) { filtered_offered_audio_codecs.push_back(offered_audio_codec); } } @@ -2114,11 +2138,12 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( const VideoContentDescription* video = content.media_description()->as_video(); for (const VideoCodec& offered_video_codec : video->codecs()) { - if (!FindMatchingCodec(video->codecs(), - filtered_offered_video_codecs, - offered_video_codec, nullptr) && + if (!FindMatchingCodec( + video->codecs(), filtered_offered_video_codecs, + offered_video_codec, nullptr, field_trials) && FindMatchingCodec(video->codecs(), all_video_codecs_, - offered_video_codec, nullptr)) { + offered_video_codec, nullptr, + field_trials)) { filtered_offered_video_codecs.push_back(offered_video_codec); } } @@ -2128,9 +2153,9 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( // Add codecs that are not in the current description but were in // `remote_offer`. MergeCodecs(filtered_offered_audio_codecs, audio_codecs, - &used_pltypes); + &used_pltypes, field_trials); MergeCodecs(filtered_offered_video_codecs, video_codecs, - &used_pltypes); + &used_pltypes, field_trials); } MediaSessionDescriptionFactory::AudioVideoRtpHeaderExtensions @@ -2272,6 +2297,8 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( StreamParamsVec* current_streams, SessionDescription* desc, IceCredentialsIterator* ice_credentials) const { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); // Filter audio_codecs (which includes all codecs, with correctly remapped // payload types) based on transceiver direction. const AudioCodecs& supported_audio_codecs = @@ -2282,9 +2309,9 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( if (!media_description_options.codec_preferences.empty()) { // Add the codecs from the current transceiver's codec preferences. // They override any existing codecs from previous negotiations. - filtered_codecs = - MatchCodecPreference(media_description_options.codec_preferences, - audio_codecs, supported_audio_codecs); + filtered_codecs = MatchCodecPreference( + media_description_options.codec_preferences, audio_codecs, + supported_audio_codecs, field_trials); } else { // Add the codecs from current content if it exists and is not rejected nor // recycled. @@ -2295,7 +2322,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( current_content->media_description()->as_audio(); for (const AudioCodec& codec : acd->codecs()) { if (FindMatchingCodec(acd->codecs(), audio_codecs, codec, - nullptr)) { + nullptr, field_trials)) { filtered_codecs.push_back(codec); } } @@ -2304,9 +2331,10 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( AudioCodec found_codec; for (const AudioCodec& codec : supported_audio_codecs) { if (FindMatchingCodec(supported_audio_codecs, audio_codecs, - codec, &found_codec) && + codec, &found_codec, field_trials) && !FindMatchingCodec(supported_audio_codecs, - filtered_codecs, codec, nullptr)) { + filtered_codecs, codec, nullptr, + field_trials)) { // Use the `found_codec` from `audio_codecs` because it has the // correctly mapped payload type. filtered_codecs.push_back(found_codec); @@ -2362,6 +2390,8 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( StreamParamsVec* current_streams, SessionDescription* desc, IceCredentialsIterator* ice_credentials) const { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); // Filter video_codecs (which includes all codecs, with correctly remapped // payload types) based on transceiver direction. const VideoCodecs& supported_video_codecs = @@ -2372,9 +2402,9 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( if (!media_description_options.codec_preferences.empty()) { // Add the codecs from the current transceiver's codec preferences. // They override any existing codecs from previous negotiations. - filtered_codecs = - MatchCodecPreference(media_description_options.codec_preferences, - video_codecs, supported_video_codecs); + filtered_codecs = MatchCodecPreference( + media_description_options.codec_preferences, video_codecs, + supported_video_codecs, field_trials); } else { // Add the codecs from current content if it exists and is not rejected nor // recycled. @@ -2385,7 +2415,7 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( current_content->media_description()->as_video(); for (const VideoCodec& codec : vcd->codecs()) { if (FindMatchingCodec(vcd->codecs(), video_codecs, codec, - nullptr)) { + nullptr, field_trials)) { filtered_codecs.push_back(codec); } } @@ -2394,9 +2424,10 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( VideoCodec found_codec; for (const VideoCodec& codec : supported_video_codecs) { if (FindMatchingCodec(supported_video_codecs, video_codecs, - codec, &found_codec) && + codec, &found_codec, field_trials) && !FindMatchingCodec(supported_video_codecs, - filtered_codecs, codec, nullptr)) { + filtered_codecs, codec, nullptr, + field_trials)) { // Use the `found_codec` from `video_codecs` because it has the // correctly mapped payload type. if (IsRtxCodec(codec)) { @@ -2408,9 +2439,9 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( // Find the codec we should be referencing and point to it. VideoCodec changed_referenced_codec; - if (FindMatchingCodec(supported_video_codecs, - filtered_codecs, *referenced_codec, - &changed_referenced_codec)) { + if (FindMatchingCodec( + supported_video_codecs, filtered_codecs, *referenced_codec, + &changed_referenced_codec, field_trials)) { found_codec.SetParam(kCodecParamAssociatedPayloadType, changed_referenced_codec.id); } @@ -2556,6 +2587,8 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_AUDIO)); const AudioContentDescription* offer_audio_description = offer_content->media_description()->as_audio(); @@ -2580,9 +2613,9 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( AudioCodecs filtered_codecs; if (!media_description_options.codec_preferences.empty()) { - filtered_codecs = - MatchCodecPreference(media_description_options.codec_preferences, - audio_codecs, supported_audio_codecs); + filtered_codecs = MatchCodecPreference( + media_description_options.codec_preferences, audio_codecs, + supported_audio_codecs, field_trials); } else { // Add the codecs from current content if it exists and is not rejected nor // recycled. @@ -2593,7 +2626,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( current_content->media_description()->as_audio(); for (const AudioCodec& codec : acd->codecs()) { if (FindMatchingCodec(acd->codecs(), audio_codecs, codec, - nullptr)) { + nullptr, field_trials)) { filtered_codecs.push_back(codec); } } @@ -2601,9 +2634,10 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( // Add other supported audio codecs. for (const AudioCodec& codec : supported_audio_codecs) { if (FindMatchingCodec(supported_audio_codecs, audio_codecs, - codec, nullptr) && + codec, nullptr, field_trials) && !FindMatchingCodec(supported_audio_codecs, - filtered_codecs, codec, nullptr)) { + filtered_codecs, codec, nullptr, + field_trials)) { // We should use the local codec with local parameters and the codec id // would be correctly mapped in `NegotiateCodecs`. filtered_codecs.push_back(codec); @@ -2672,6 +2706,8 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_VIDEO)); const VideoContentDescription* offer_video_description = offer_content->media_description()->as_video(); @@ -2696,9 +2732,9 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( VideoCodecs filtered_codecs; if (!media_description_options.codec_preferences.empty()) { - filtered_codecs = - MatchCodecPreference(media_description_options.codec_preferences, - video_codecs, supported_video_codecs); + filtered_codecs = MatchCodecPreference( + media_description_options.codec_preferences, video_codecs, + supported_video_codecs, field_trials); } else { // Add the codecs from current content if it exists and is not rejected nor // recycled. @@ -2709,7 +2745,7 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( current_content->media_description()->as_video(); for (const VideoCodec& codec : vcd->codecs()) { if (FindMatchingCodec(vcd->codecs(), video_codecs, codec, - nullptr)) { + nullptr, field_trials)) { filtered_codecs.push_back(codec); } } @@ -2719,9 +2755,10 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( VideoCodecs other_video_codecs; for (const VideoCodec& codec : supported_video_codecs) { if (FindMatchingCodec(supported_video_codecs, video_codecs, - codec, nullptr) && + codec, nullptr, field_trials) && !FindMatchingCodec(supported_video_codecs, - filtered_codecs, codec, nullptr)) { + filtered_codecs, codec, nullptr, + field_trials)) { // We should use the local codec with local parameters and the codec id // would be correctly mapped in `NegotiateCodecs`. other_video_codecs.push_back(codec); @@ -2729,8 +2766,8 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( } // Use ComputeCodecsUnion to avoid having duplicate payload IDs - filtered_codecs = - ComputeCodecsUnion(filtered_codecs, other_video_codecs); + filtered_codecs = ComputeCodecsUnion( + filtered_codecs, other_video_codecs, field_trials); } if (session_options.raw_packetization_for_video) { @@ -2895,13 +2932,15 @@ bool MediaSessionDescriptionFactory::AddUnsupportedContentForAnswer( } void MediaSessionDescriptionFactory::ComputeAudioCodecsIntersectionAndUnion() { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); audio_sendrecv_codecs_.clear(); all_audio_codecs_.clear(); // Compute the audio codecs union. for (const AudioCodec& send : audio_send_codecs_) { all_audio_codecs_.push_back(send); if (!FindMatchingCodec(audio_send_codecs_, audio_recv_codecs_, - send, nullptr)) { + send, nullptr, field_trials)) { // It doesn't make sense to have an RTX codec we support sending but not // receiving. RTC_DCHECK(!IsRtxCodec(send)); @@ -2909,7 +2948,7 @@ void MediaSessionDescriptionFactory::ComputeAudioCodecsIntersectionAndUnion() { } for (const AudioCodec& recv : audio_recv_codecs_) { if (!FindMatchingCodec(audio_recv_codecs_, audio_send_codecs_, - recv, nullptr)) { + recv, nullptr, field_trials)) { all_audio_codecs_.push_back(recv); } } @@ -2919,15 +2958,17 @@ void MediaSessionDescriptionFactory::ComputeAudioCodecsIntersectionAndUnion() { // expensive than decoding, and prioritizing a codec in the send list probably // means it's a codec we can handle efficiently. NegotiateCodecs(audio_recv_codecs_, audio_send_codecs_, - &audio_sendrecv_codecs_, true); + &audio_sendrecv_codecs_, true, field_trials); } void MediaSessionDescriptionFactory::ComputeVideoCodecsIntersectionAndUnion() { + const webrtc::WebRtcKeyValueConfig* field_trials = + &transport_desc_factory_->trials(); video_sendrecv_codecs_.clear(); // Use ComputeCodecsUnion to avoid having duplicate payload IDs all_video_codecs_ = - ComputeCodecsUnion(video_recv_codecs_, video_send_codecs_); + ComputeCodecsUnion(video_recv_codecs_, video_send_codecs_, field_trials); // Use NegotiateCodecs to merge our codec lists, since the operation is // essentially the same. Put send_codecs as the offered_codecs, which is the @@ -2935,7 +2976,7 @@ void MediaSessionDescriptionFactory::ComputeVideoCodecsIntersectionAndUnion() { // expensive than decoding, and prioritizing a codec in the send list probably // means it's a codec we can handle efficiently. NegotiateCodecs(video_recv_codecs_, video_send_codecs_, - &video_sendrecv_codecs_, true); + &video_sendrecv_codecs_, true, field_trials); } bool IsMediaContent(const ContentInfo* content) { diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc index f06ddc7586..ee71c6ba7d 100644 --- a/pc/media_session_unittest.cc +++ b/pc/media_session_unittest.cc @@ -4454,13 +4454,14 @@ namespace { // Compare the two vectors of codecs ignoring the payload type. template bool CodecsMatch(const std::vector& codecs1, - const std::vector& codecs2) { + const std::vector& codecs2, + const webrtc::WebRtcKeyValueConfig* field_trials) { if (codecs1.size() != codecs2.size()) { return false; } for (size_t i = 0; i < codecs1.size(); ++i) { - if (!codecs1[i].Matches(codecs2[i])) { + if (!codecs1[i].Matches(codecs2[i], field_trials)) { return false; } } @@ -4503,11 +4504,14 @@ void TestAudioCodecsOffer(RtpTransceiverDirection direction) { // might eventually be used anything, but we don't know more at this // moment. if (acd->direction() == RtpTransceiverDirection::kSendOnly) { - EXPECT_TRUE(CodecsMatch(send_codecs, acd->codecs())); + EXPECT_TRUE( + CodecsMatch(send_codecs, acd->codecs(), &field_trials)); } else if (acd->direction() == RtpTransceiverDirection::kRecvOnly) { - EXPECT_TRUE(CodecsMatch(recv_codecs, acd->codecs())); + EXPECT_TRUE( + CodecsMatch(recv_codecs, acd->codecs(), &field_trials)); } else { - EXPECT_TRUE(CodecsMatch(sendrecv_codecs, acd->codecs())); + EXPECT_TRUE(CodecsMatch(sendrecv_codecs, acd->codecs(), + &field_trials)); } } } diff --git a/test/BUILD.gn b/test/BUILD.gn index 82d909d1ae..a791878baa 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -110,6 +110,7 @@ rtc_library("video_test_common") { deps = [ ":fileutils", ":frame_utils", + ":scoped_key_value_config", "../api:array_view", "../api:create_frame_generator", "../api:frame_generator_api", @@ -178,6 +179,7 @@ if (!build_with_chromium) { "vcm_capturer.h", ] deps += [ + ":scoped_key_value_config", "../api:scoped_refptr", "../modules/video_capture:video_capture_module", "../rtc_base:checks", @@ -524,6 +526,7 @@ if (rtc_include_tests && !build_with_chromium) { ":perf_test", ":rtc_expect_death", ":rtp_test_utils", + ":scoped_key_value_config", ":test_common", ":test_main", ":test_support",