| // Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. | |
| // | |
| // Use of this source code is governed by a BSD-style license | |
| // that can be found in the LICENSE file in the root of the source | |
| // tree. An additional intellectual property rights grant can be found | |
| // in the file PATENTS. All contributing project authors may | |
| // be found in the AUTHORS file in the root of the source tree. | |
| #include "rtc_base/experiments/encoder_speed_experiment.h" | |
| #include <string> | |
| #include "api/field_trials.h" | |
| #include "api/video/video_codec_type.h" | |
| #include "api/video_codecs/video_codec.h" | |
| #include "test/create_test_field_trials.h" | |
| #include "test/gtest.h" | |
| namespace webrtc { | |
| namespace { | |
| TEST(EncoderSpeedExperimentTest, EnabledByDefault) { | |
| FieldTrials field_trials = CreateTestFieldTrials(""); | |
| EncoderSpeedExperiment config(field_trials); | |
| EXPECT_TRUE(config.IsDynamicSpeedEnabled()); | |
| } | |
| TEST(EncoderSpeedExperimentTest, DynamicSpeedEnabled) { | |
| FieldTrials field_trials = | |
| CreateTestFieldTrials("WebRTC-EncoderSpeed/dynamic_speed:true/"); | |
| EncoderSpeedExperiment config(field_trials); | |
| EXPECT_TRUE(config.IsDynamicSpeedEnabled()); | |
| } | |
| TEST(EncoderSpeedExperimentTest, DynamicSpeedExplicitlyDisabled) { | |
| FieldTrials field_trials = | |
| CreateTestFieldTrials("WebRTC-EncoderSpeed/dynamic_speed:false/"); | |
| EncoderSpeedExperiment config(field_trials); | |
| EXPECT_FALSE(config.IsDynamicSpeedEnabled()); | |
| } | |
| TEST(EncoderSpeedExperimentTest, DefaultComplexity) { | |
| FieldTrials field_trials = CreateTestFieldTrials(""); | |
| EncoderSpeedExperiment config(field_trials); | |
| // New defaults for AV1. | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecAV1, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityHigh); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecAV1, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityLow); | |
| // All others default to normal for now, pending future experimentation. | |
| for (VideoCodecType codec : | |
| {kVideoCodecVP8, kVideoCodecVP9, kVideoCodecH264, kVideoCodecH265}) { | |
| EXPECT_EQ(config.GetComplexity(codec, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityNormal); | |
| EXPECT_EQ(config.GetComplexity(codec, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityNormal); | |
| } | |
| } | |
| TEST(EncoderSpeedExperimentTest, PerCodecComplexity) { | |
| FieldTrials field_trials = CreateTestFieldTrials( | |
| "WebRTC-EncoderSpeed/" | |
| "dynamic_speed:true,av1_camera:high,av1_screenshare:low,vp8_camera:max/"); | |
| EncoderSpeedExperiment config(field_trials); | |
| EXPECT_TRUE(config.IsDynamicSpeedEnabled()); | |
| // AV1 | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecAV1, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityHigh); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecAV1, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityLow); | |
| // VP8 | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP8, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityMax); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP8, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityNormal); // Default | |
| // VP9 (Not specified) | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityNormal); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityNormal); | |
| } | |
| TEST(EncoderSpeedExperimentTest, PerCodecComplexityDynamicSpeedDisabled) { | |
| FieldTrials field_trials = CreateTestFieldTrials( | |
| "WebRTC-EncoderSpeed/" | |
| "dynamic_speed:false,av1_camera:high,av1_screenshare:low/"); | |
| EncoderSpeedExperiment config(field_trials); | |
| EXPECT_FALSE(config.IsDynamicSpeedEnabled()); | |
| // AV1 | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecAV1, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityHigh); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecAV1, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityLow); | |
| } | |
| TEST(EncoderSpeedExperimentTest, InvalidCodecComplexityValue) { | |
| FieldTrials field_trials = CreateTestFieldTrials( | |
| "WebRTC-EncoderSpeed/" | |
| "dynamic_speed:true,vp8_camera:invalid,vp8_screenshare:max/"); | |
| EncoderSpeedExperiment config(field_trials); | |
| EXPECT_TRUE(config.IsDynamicSpeedEnabled()); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP8, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityNormal); // Invalid value | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP8, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityMax); | |
| } | |
| TEST(EncoderSpeedExperimentTest, InvalidDynamicSpeedValue) { | |
| FieldTrials field_trials = | |
| CreateTestFieldTrials("WebRTC-EncoderSpeed/dynamic_speed:invalid/"); | |
| EncoderSpeedExperiment config(field_trials); | |
| EXPECT_TRUE(config.IsDynamicSpeedEnabled()); // Should default to true | |
| } | |
| TEST(EncoderSpeedExperimentTest, Vp9LowComplexityFallbackEnabled) { | |
| for (std::string trial : {"WebRTC-EncoderSpeed/dynamic_speed:true/", | |
| "WebRTC-EncoderSpeed/dynamic_speed:false/"}) { | |
| FieldTrials field_trials = CreateTestFieldTrials(trial); | |
| EncoderSpeedExperiment config(field_trials, | |
| /*use_low_complexity_for_vp9=*/true); | |
| // VP9 should fallback to low complexity. | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityLow); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityLow); | |
| // Other codecs should still be normal complexity. | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP8, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityNormal); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecH264, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityNormal); | |
| } | |
| } | |
| TEST(EncoderSpeedExperimentTest, | |
| FieldTrialsTakePrecedenceOverVP9LowComplexityFlag) { | |
| for (std::string trial : | |
| {"WebRTC-EncoderSpeed/" | |
| "dynamic_speed:false,vp9_camera:high,vp9_screenshare:max/", | |
| "WebRTC-EncoderSpeed/" | |
| "dynamic_speed:true,vp9_camera:high,vp9_screenshare:max/"}) { | |
| FieldTrials field_trials = CreateTestFieldTrials(trial); | |
| EncoderSpeedExperiment config(field_trials, | |
| /*use_low_complexity_for_vp9=*/true); | |
| // VP9 should use the configured complexity instead of falling back. | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityHigh); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityMax); | |
| } | |
| } | |
| TEST(EncoderSpeedExperimentTest, Vp9LowComplexityFallbackDisabled) { | |
| FieldTrials field_trials = | |
| CreateTestFieldTrials("WebRTC-EncoderSpeed/dynamic_speed:true/"); | |
| EncoderSpeedExperiment config(field_trials, | |
| /*use_low_complexity_for_vp9=*/false); | |
| // VP9 should be normal complexity. | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/false), | |
| VideoCodecComplexity::kComplexityNormal); | |
| EXPECT_EQ(config.GetComplexity(kVideoCodecVP9, /*is_screenshare=*/true), | |
| VideoCodecComplexity::kComplexityNormal); | |
| } | |
| } // namespace | |
| } // namespace webrtc |