blob: 373e9df925e33dff42bc5cfccf8275a58cae4fad [file]
// 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