// 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 #include #include "absl/strings/string_view.h" #include "api/field_trials_view.h" #include "api/video/video_codec_type.h" #include "api/video_codecs/video_codec.h" #include "rtc_base/experiments/field_trial_parser.h" namespace webrtc { namespace { constexpr absl::string_view kFieldTrialName = "WebRTC-EncoderSpeed"; // Helper function to parse complexity string. std::optional ParseComplexity(absl::string_view s) { if (s.empty()) { return std::nullopt; } else if (s == "low") { return VideoCodecComplexity::kComplexityLow; } else if (s == "normal") { return VideoCodecComplexity::kComplexityNormal; } else if (s == "high") { return VideoCodecComplexity::kComplexityHigh; } else if (s == "higher") { return VideoCodecComplexity::kComplexityHigher; } else if (s == "max") { return VideoCodecComplexity::kComplexityMax; } return std::nullopt; // Invalid value. } } // namespace void EncoderSpeedExperiment::ParseCodecSettings(absl::string_view codec_name, absl::string_view trial_string, ComplexitySettings& settings) { FieldTrialParameter camera_complexity( std::string(codec_name) + "_camera", ""); FieldTrialParameter screenshare_complexity( std::string(codec_name) + "_screenshare", ""); ParseFieldTrial({&camera_complexity, &screenshare_complexity}, trial_string); if (auto complexity = ParseComplexity(camera_complexity.Get())) { settings.camera = *complexity; } if (auto complexity = ParseComplexity(screenshare_complexity.Get())) { settings.screenshare = *complexity; } } EncoderSpeedExperiment::EncoderSpeedExperiment( const FieldTrialsView& field_trials) { std::string trial_string = field_trials.Lookup(kFieldTrialName); if (trial_string.empty()) { return; } FieldTrialParameter dynamic_speed_enabled("dynamic_speed", false); ParseFieldTrial({&dynamic_speed_enabled}, trial_string); dynamic_speed_enabled_ = dynamic_speed_enabled.Get(); ParseCodecSettings("av1", trial_string, av1_complexity_); ParseCodecSettings("vp8", trial_string, vp8_complexity_); ParseCodecSettings("vp9", trial_string, vp9_complexity_); ParseCodecSettings("h264", trial_string, h264_complexity_); ParseCodecSettings("h265", trial_string, h265_complexity_); } bool EncoderSpeedExperiment::IsDynamicSpeedEnabled() const { return dynamic_speed_enabled_; } VideoCodecComplexity EncoderSpeedExperiment::GetComplexity( VideoCodecType codec_type, bool is_screenshare) const { const ComplexitySettings* settings = nullptr; switch (codec_type) { case kVideoCodecAV1: settings = &av1_complexity_; break; case kVideoCodecVP8: settings = &vp8_complexity_; break; case kVideoCodecVP9: settings = &vp9_complexity_; break; case kVideoCodecH264: settings = &h264_complexity_; break; case kVideoCodecH265: settings = &h265_complexity_; break; case kVideoCodecGeneric: // Not supported, just use the normal default value. return VideoCodecComplexity::kComplexityNormal; } return is_screenshare ? settings->screenshare : settings->camera; } } // namespace webrtc