Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | #include "rtc_base/experiments/rate_control_settings.h" |
| 12 | |
| 13 | #include <inttypes.h> |
| 14 | #include <stdio.h> |
| 15 | |
| 16 | #include <string> |
| 17 | |
| 18 | #include "api/transport/field_trial_based_config.h" |
Evan Shrubsole | dd33d8e | 2019-04-09 09:59:00 +0200 | [diff] [blame^] | 19 | #include "rtc_base/experiments/field_trial_parser.h" |
Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 20 | #include "rtc_base/logging.h" |
| 21 | #include "rtc_base/numerics/safe_conversions.h" |
| 22 | |
| 23 | namespace webrtc { |
| 24 | |
| 25 | namespace { |
| 26 | |
Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 27 | const int kDefaultAcceptedQueueMs = 250; |
| 28 | |
Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 29 | const int kDefaultMinPushbackTargetBitrateBps = 30000; |
| 30 | |
Erik Språng | 4b4266f | 2019-01-23 12:48:13 +0100 | [diff] [blame] | 31 | const char kVp8TrustedRateControllerFieldTrialName[] = |
| 32 | "WebRTC-LibvpxVp8TrustedRateController"; |
| 33 | const char kVp9TrustedRateControllerFieldTrialName[] = |
| 34 | "WebRTC-LibvpxVp9TrustedRateController"; |
| 35 | |
Erik Språng | 2c58ba1 | 2019-01-23 16:53:18 +0100 | [diff] [blame] | 36 | const char* kVideoHysteresisFieldTrialname = |
| 37 | "WebRTC-SimulcastUpswitchHysteresisPercent"; |
| 38 | const double kDefaultVideoHysteresisFactor = 1.0; |
| 39 | const char* kScreenshareHysteresisFieldTrialname = |
| 40 | "WebRTC-SimulcastScreenshareUpswitchHysteresisPercent"; |
| 41 | // Default to 35% hysteresis for simulcast screenshare. |
| 42 | const double kDefaultScreenshareHysteresisFactor = 1.35; |
| 43 | |
Erik Språng | 4b4266f | 2019-01-23 12:48:13 +0100 | [diff] [blame] | 44 | bool IsEnabled(const WebRtcKeyValueConfig* const key_value_config, |
| 45 | absl::string_view key) { |
| 46 | return key_value_config->Lookup(key).find("Enabled") == 0; |
| 47 | } |
| 48 | |
Erik Språng | 2c58ba1 | 2019-01-23 16:53:18 +0100 | [diff] [blame] | 49 | double ParseHysteresisFactor(const WebRtcKeyValueConfig* const key_value_config, |
| 50 | absl::string_view key, |
| 51 | double default_value) { |
| 52 | std::string group_name = key_value_config->Lookup(key); |
| 53 | int percent = 0; |
| 54 | if (!group_name.empty() && sscanf(group_name.c_str(), "%d", &percent) == 1 && |
| 55 | percent >= 0) { |
| 56 | return 1.0 + (percent / 100.0); |
| 57 | } |
| 58 | return default_value; |
| 59 | } |
| 60 | |
Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 61 | } // namespace |
| 62 | |
| 63 | RateControlSettings::RateControlSettings( |
| 64 | const WebRtcKeyValueConfig* const key_value_config) |
Evan Shrubsole | dd33d8e | 2019-04-09 09:59:00 +0200 | [diff] [blame^] | 65 | : congestion_window_("QueueSize"), |
| 66 | congestion_window_pushback_("MinBitrate"), |
Erik Språng | cd76eab | 2019-01-21 18:06:46 +0100 | [diff] [blame] | 67 | pacing_factor_("pacing_factor"), |
Erik Språng | 4b4266f | 2019-01-23 12:48:13 +0100 | [diff] [blame] | 68 | alr_probing_("alr_probing", false), |
| 69 | trust_vp8_( |
| 70 | "trust_vp8", |
| 71 | IsEnabled(key_value_config, kVp8TrustedRateControllerFieldTrialName)), |
Erik Språng | 2c58ba1 | 2019-01-23 16:53:18 +0100 | [diff] [blame] | 72 | trust_vp9_( |
| 73 | "trust_vp9", |
| 74 | IsEnabled(key_value_config, kVp9TrustedRateControllerFieldTrialName)), |
| 75 | video_hysteresis_("video_hysteresis", |
| 76 | ParseHysteresisFactor(key_value_config, |
| 77 | kVideoHysteresisFieldTrialname, |
| 78 | kDefaultVideoHysteresisFactor)), |
| 79 | screenshare_hysteresis_( |
| 80 | "screenshare_hysteresis", |
| 81 | ParseHysteresisFactor(key_value_config, |
| 82 | kScreenshareHysteresisFieldTrialname, |
Erik Språng | 5118bbc | 2019-01-29 18:28:06 +0100 | [diff] [blame] | 83 | kDefaultScreenshareHysteresisFactor)), |
Erik Språng | 7ca375c | 2019-02-06 16:20:17 +0100 | [diff] [blame] | 84 | probe_max_allocation_("probe_max_allocation", true), |
Erik Språng | 7f24fb9 | 2019-02-13 10:49:37 +0100 | [diff] [blame] | 85 | bitrate_adjuster_("bitrate_adjuster", false), |
| 86 | vp8_s0_boost_("vp8_s0_boost", true) { |
Evan Shrubsole | dd33d8e | 2019-04-09 09:59:00 +0200 | [diff] [blame^] | 87 | ParseFieldTrial({&congestion_window_, &congestion_window_pushback_}, |
| 88 | key_value_config->Lookup("WebRTC-CongestionWindow")); |
| 89 | ParseFieldTrial({&pacing_factor_, &alr_probing_, &trust_vp8_, &trust_vp9_, |
Erik Språng | 7f24fb9 | 2019-02-13 10:49:37 +0100 | [diff] [blame] | 90 | &video_hysteresis_, &screenshare_hysteresis_, |
| 91 | &probe_max_allocation_, &bitrate_adjuster_, &vp8_s0_boost_}, |
| 92 | key_value_config->Lookup("WebRTC-VideoRateControl")); |
Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | RateControlSettings::~RateControlSettings() = default; |
| 96 | RateControlSettings::RateControlSettings(RateControlSettings&&) = default; |
| 97 | |
| 98 | RateControlSettings RateControlSettings::ParseFromFieldTrials() { |
| 99 | FieldTrialBasedConfig field_trial_config; |
| 100 | return RateControlSettings(&field_trial_config); |
| 101 | } |
| 102 | |
| 103 | RateControlSettings RateControlSettings::ParseFromKeyValueConfig( |
| 104 | const WebRtcKeyValueConfig* const key_value_config) { |
| 105 | FieldTrialBasedConfig field_trial_config; |
| 106 | return RateControlSettings(key_value_config ? key_value_config |
| 107 | : &field_trial_config); |
| 108 | } |
| 109 | |
| 110 | bool RateControlSettings::UseCongestionWindow() const { |
Jonas Olsson | cb96809 | 2019-03-12 13:57:15 +0100 | [diff] [blame] | 111 | return static_cast<bool>(congestion_window_); |
Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 112 | } |
| 113 | |
| 114 | int64_t RateControlSettings::GetCongestionWindowAdditionalTimeMs() const { |
| 115 | return congestion_window_.GetOptional().value_or(kDefaultAcceptedQueueMs); |
| 116 | } |
| 117 | |
| 118 | bool RateControlSettings::UseCongestionWindowPushback() const { |
| 119 | return congestion_window_ && congestion_window_pushback_; |
| 120 | } |
| 121 | |
| 122 | uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps() |
| 123 | const { |
| 124 | return congestion_window_pushback_.GetOptional().value_or( |
| 125 | kDefaultMinPushbackTargetBitrateBps); |
| 126 | } |
| 127 | |
Erik Språng | cd76eab | 2019-01-21 18:06:46 +0100 | [diff] [blame] | 128 | absl::optional<double> RateControlSettings::GetPacingFactor() const { |
| 129 | return pacing_factor_.GetOptional(); |
| 130 | } |
| 131 | |
| 132 | bool RateControlSettings::UseAlrProbing() const { |
| 133 | return alr_probing_.Get(); |
| 134 | } |
| 135 | |
Erik Språng | 4b4266f | 2019-01-23 12:48:13 +0100 | [diff] [blame] | 136 | bool RateControlSettings::LibvpxVp8TrustedRateController() const { |
| 137 | return trust_vp8_.Get(); |
| 138 | } |
| 139 | |
Erik Språng | 7f24fb9 | 2019-02-13 10:49:37 +0100 | [diff] [blame] | 140 | bool RateControlSettings::Vp8BoostBaseLayerQuality() const { |
| 141 | return vp8_s0_boost_.Get(); |
| 142 | } |
| 143 | |
Erik Språng | 4b4266f | 2019-01-23 12:48:13 +0100 | [diff] [blame] | 144 | bool RateControlSettings::LibvpxVp9TrustedRateController() const { |
| 145 | return trust_vp9_.Get(); |
| 146 | } |
| 147 | |
Rasmus Brandt | c402dbe | 2019-02-04 11:09:46 +0100 | [diff] [blame] | 148 | double RateControlSettings::GetSimulcastHysteresisFactor( |
| 149 | VideoCodecMode mode) const { |
| 150 | if (mode == VideoCodecMode::kScreensharing) { |
| 151 | return GetSimulcastScreenshareHysteresisFactor(); |
| 152 | } |
| 153 | return GetSimulcastVideoHysteresisFactor(); |
| 154 | } |
| 155 | |
| 156 | double RateControlSettings::GetSimulcastHysteresisFactor( |
| 157 | VideoEncoderConfig::ContentType content_type) const { |
| 158 | if (content_type == VideoEncoderConfig::ContentType::kScreen) { |
| 159 | return GetSimulcastScreenshareHysteresisFactor(); |
| 160 | } |
| 161 | return GetSimulcastVideoHysteresisFactor(); |
| 162 | } |
| 163 | |
Erik Språng | 2c58ba1 | 2019-01-23 16:53:18 +0100 | [diff] [blame] | 164 | double RateControlSettings::GetSimulcastVideoHysteresisFactor() const { |
| 165 | return video_hysteresis_.Get(); |
| 166 | } |
| 167 | |
| 168 | double RateControlSettings::GetSimulcastScreenshareHysteresisFactor() const { |
| 169 | return screenshare_hysteresis_.Get(); |
| 170 | } |
| 171 | |
Erik Språng | 5118bbc | 2019-01-29 18:28:06 +0100 | [diff] [blame] | 172 | bool RateControlSettings::TriggerProbeOnMaxAllocatedBitrateChange() const { |
| 173 | return probe_max_allocation_.Get(); |
| 174 | } |
| 175 | |
Erik Språng | 7ca375c | 2019-02-06 16:20:17 +0100 | [diff] [blame] | 176 | bool RateControlSettings::UseEncoderBitrateAdjuster() const { |
| 177 | return bitrate_adjuster_.Get(); |
| 178 | } |
| 179 | |
Erik Språng | 7121564 | 2019-01-21 16:30:55 +0100 | [diff] [blame] | 180 | } // namespace webrtc |