blob: 4fa74b80d9634287be348051b1aa538301376e62 [file] [log] [blame]
// 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 <optional>
#include <string>
#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<VideoCodecComplexity> 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<std::string> camera_complexity(
std::string(codec_name) + "_camera", "");
FieldTrialParameter<std::string> 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<bool> 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