blob: eeb2f4957b8e722f5a8008bedd5ba44d5d30d7fa [file] [log] [blame]
Erik Språng71215642019-01-21 16:30:55 +01001/*
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 Shrubsoleae68ea02019-04-09 09:59:00 +020019#include "rtc_base/experiments/field_trial_parser.h"
Erik Språng71215642019-01-21 16:30:55 +010020#include "rtc_base/logging.h"
21#include "rtc_base/numerics/safe_conversions.h"
22
23namespace webrtc {
24
25namespace {
26
Erik Språng71215642019-01-21 16:30:55 +010027const int kDefaultAcceptedQueueMs = 250;
28
Erik Språng71215642019-01-21 16:30:55 +010029const int kDefaultMinPushbackTargetBitrateBps = 30000;
30
Erik Språng4b4266f2019-01-23 12:48:13 +010031const char kVp8TrustedRateControllerFieldTrialName[] =
32 "WebRTC-LibvpxVp8TrustedRateController";
33const char kVp9TrustedRateControllerFieldTrialName[] =
34 "WebRTC-LibvpxVp9TrustedRateController";
35
Erik Språng2c58ba12019-01-23 16:53:18 +010036const char* kVideoHysteresisFieldTrialname =
37 "WebRTC-SimulcastUpswitchHysteresisPercent";
38const double kDefaultVideoHysteresisFactor = 1.0;
39const char* kScreenshareHysteresisFieldTrialname =
40 "WebRTC-SimulcastScreenshareUpswitchHysteresisPercent";
41// Default to 35% hysteresis for simulcast screenshare.
42const double kDefaultScreenshareHysteresisFactor = 1.35;
43
Erik Språng4b4266f2019-01-23 12:48:13 +010044bool 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ång2c58ba12019-01-23 16:53:18 +010049double 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ång71215642019-01-21 16:30:55 +010061} // namespace
62
63RateControlSettings::RateControlSettings(
64 const WebRtcKeyValueConfig* const key_value_config)
Evan Shrubsoleae68ea02019-04-09 09:59:00 +020065 : congestion_window_("QueueSize"),
66 congestion_window_pushback_("MinBitrate"),
Erik Språngcd76eab2019-01-21 18:06:46 +010067 pacing_factor_("pacing_factor"),
Erik Språng4b4266f2019-01-23 12:48:13 +010068 alr_probing_("alr_probing", false),
Åsa Perssond7dd49f2019-05-08 14:44:12 +020069 vp8_qp_max_("vp8_qp_max"),
Erik Språng4b4266f2019-01-23 12:48:13 +010070 trust_vp8_(
71 "trust_vp8",
72 IsEnabled(key_value_config, kVp8TrustedRateControllerFieldTrialName)),
Erik Språng2c58ba12019-01-23 16:53:18 +010073 trust_vp9_(
74 "trust_vp9",
75 IsEnabled(key_value_config, kVp9TrustedRateControllerFieldTrialName)),
76 video_hysteresis_("video_hysteresis",
77 ParseHysteresisFactor(key_value_config,
78 kVideoHysteresisFieldTrialname,
79 kDefaultVideoHysteresisFactor)),
80 screenshare_hysteresis_(
81 "screenshare_hysteresis",
82 ParseHysteresisFactor(key_value_config,
83 kScreenshareHysteresisFieldTrialname,
Erik Språng5118bbc2019-01-29 18:28:06 +010084 kDefaultScreenshareHysteresisFactor)),
Erik Språng7ca375c2019-02-06 16:20:17 +010085 probe_max_allocation_("probe_max_allocation", true),
Erik Språng7f24fb92019-02-13 10:49:37 +010086 bitrate_adjuster_("bitrate_adjuster", false),
Erik Språng3d11e2f2019-04-15 14:48:30 +020087 adjuster_use_headroom_("adjuster_use_headroom", false),
Erik Språng7a3fe892019-04-15 12:22:55 +020088 vp8_s0_boost_("vp8_s0_boost", true),
89 vp8_dynamic_rate_("vp8_dynamic_rate", false),
90 vp9_dynamic_rate_("vp9_dynamic_rate", false) {
Evan Shrubsoleae68ea02019-04-09 09:59:00 +020091 ParseFieldTrial({&congestion_window_, &congestion_window_pushback_},
92 key_value_config->Lookup("WebRTC-CongestionWindow"));
Erik Språng3d11e2f2019-04-15 14:48:30 +020093 ParseFieldTrial(
Åsa Perssond7dd49f2019-05-08 14:44:12 +020094 {&pacing_factor_, &alr_probing_, &vp8_qp_max_, &trust_vp8_, &trust_vp9_,
Erik Språng3d11e2f2019-04-15 14:48:30 +020095 &video_hysteresis_, &screenshare_hysteresis_, &probe_max_allocation_,
96 &bitrate_adjuster_, &adjuster_use_headroom_, &vp8_s0_boost_,
97 &vp8_dynamic_rate_, &vp9_dynamic_rate_},
98 key_value_config->Lookup("WebRTC-VideoRateControl"));
Erik Språng71215642019-01-21 16:30:55 +010099}
100
101RateControlSettings::~RateControlSettings() = default;
102RateControlSettings::RateControlSettings(RateControlSettings&&) = default;
103
104RateControlSettings RateControlSettings::ParseFromFieldTrials() {
105 FieldTrialBasedConfig field_trial_config;
106 return RateControlSettings(&field_trial_config);
107}
108
109RateControlSettings RateControlSettings::ParseFromKeyValueConfig(
110 const WebRtcKeyValueConfig* const key_value_config) {
111 FieldTrialBasedConfig field_trial_config;
112 return RateControlSettings(key_value_config ? key_value_config
113 : &field_trial_config);
114}
115
116bool RateControlSettings::UseCongestionWindow() const {
Jonas Olssoncb968092019-03-12 13:57:15 +0100117 return static_cast<bool>(congestion_window_);
Erik Språng71215642019-01-21 16:30:55 +0100118}
119
120int64_t RateControlSettings::GetCongestionWindowAdditionalTimeMs() const {
121 return congestion_window_.GetOptional().value_or(kDefaultAcceptedQueueMs);
122}
123
124bool RateControlSettings::UseCongestionWindowPushback() const {
125 return congestion_window_ && congestion_window_pushback_;
126}
127
128uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps()
129 const {
130 return congestion_window_pushback_.GetOptional().value_or(
131 kDefaultMinPushbackTargetBitrateBps);
132}
133
Erik Språngcd76eab2019-01-21 18:06:46 +0100134absl::optional<double> RateControlSettings::GetPacingFactor() const {
135 return pacing_factor_.GetOptional();
136}
137
138bool RateControlSettings::UseAlrProbing() const {
139 return alr_probing_.Get();
140}
141
Åsa Perssond7dd49f2019-05-08 14:44:12 +0200142absl::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
143 if (vp8_qp_max_ && (vp8_qp_max_.Value() < 0 || vp8_qp_max_.Value() > 63)) {
144 RTC_LOG(LS_WARNING) << "Unsupported vp8_qp_max_ value, ignored.";
145 return absl::nullopt;
146 }
147 return vp8_qp_max_.GetOptional();
148}
149
Erik Språng4b4266f2019-01-23 12:48:13 +0100150bool RateControlSettings::LibvpxVp8TrustedRateController() const {
151 return trust_vp8_.Get();
152}
153
Erik Språng7f24fb92019-02-13 10:49:37 +0100154bool RateControlSettings::Vp8BoostBaseLayerQuality() const {
155 return vp8_s0_boost_.Get();
156}
157
Erik Språng7a3fe892019-04-15 12:22:55 +0200158bool RateControlSettings::Vp8DynamicRateSettings() const {
159 return vp8_dynamic_rate_.Get();
160}
161
Erik Språng4b4266f2019-01-23 12:48:13 +0100162bool RateControlSettings::LibvpxVp9TrustedRateController() const {
163 return trust_vp9_.Get();
164}
165
Erik Språng7a3fe892019-04-15 12:22:55 +0200166bool RateControlSettings::Vp9DynamicRateSettings() const {
167 return vp9_dynamic_rate_.Get();
168}
169
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100170double RateControlSettings::GetSimulcastHysteresisFactor(
171 VideoCodecMode mode) const {
172 if (mode == VideoCodecMode::kScreensharing) {
173 return GetSimulcastScreenshareHysteresisFactor();
174 }
175 return GetSimulcastVideoHysteresisFactor();
176}
177
178double RateControlSettings::GetSimulcastHysteresisFactor(
179 VideoEncoderConfig::ContentType content_type) const {
180 if (content_type == VideoEncoderConfig::ContentType::kScreen) {
181 return GetSimulcastScreenshareHysteresisFactor();
182 }
183 return GetSimulcastVideoHysteresisFactor();
184}
185
Erik Språng2c58ba12019-01-23 16:53:18 +0100186double RateControlSettings::GetSimulcastVideoHysteresisFactor() const {
187 return video_hysteresis_.Get();
188}
189
190double RateControlSettings::GetSimulcastScreenshareHysteresisFactor() const {
191 return screenshare_hysteresis_.Get();
192}
193
Erik Språng5118bbc2019-01-29 18:28:06 +0100194bool RateControlSettings::TriggerProbeOnMaxAllocatedBitrateChange() const {
195 return probe_max_allocation_.Get();
196}
197
Erik Språng7ca375c2019-02-06 16:20:17 +0100198bool RateControlSettings::UseEncoderBitrateAdjuster() const {
199 return bitrate_adjuster_.Get();
200}
201
Erik Språng3d11e2f2019-04-15 14:48:30 +0200202bool RateControlSettings::BitrateAdjusterCanUseNetworkHeadroom() const {
203 return adjuster_use_headroom_.Get();
204}
205
Erik Språng71215642019-01-21 16:30:55 +0100206} // namespace webrtc