blob: 579b8a5db9043207a713c86e439f001fd0160b11 [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"
19#include "rtc_base/logging.h"
20#include "rtc_base/numerics/safe_conversions.h"
21
22namespace webrtc {
23
24namespace {
25
Erik Språng71215642019-01-21 16:30:55 +010026const int kDefaultAcceptedQueueMs = 250;
27
Erik Språng71215642019-01-21 16:30:55 +010028const int kDefaultMinPushbackTargetBitrateBps = 30000;
29
Erik Språng4b4266f2019-01-23 12:48:13 +010030const char kVp8TrustedRateControllerFieldTrialName[] =
31 "WebRTC-LibvpxVp8TrustedRateController";
32const char kVp9TrustedRateControllerFieldTrialName[] =
33 "WebRTC-LibvpxVp9TrustedRateController";
34
Rasmus Brandt2b9317a2019-10-30 13:01:46 +010035const char kUseBaseHeavyVp8Tl3RateAllocationFieldTrialName[] =
36 "WebRTC-UseBaseHeavyVP8TL3RateAllocation";
37
Erik Språng2c58ba12019-01-23 16:53:18 +010038const char* kVideoHysteresisFieldTrialname =
39 "WebRTC-SimulcastUpswitchHysteresisPercent";
Erik Språng2c58ba12019-01-23 16:53:18 +010040const char* kScreenshareHysteresisFieldTrialname =
41 "WebRTC-SimulcastScreenshareUpswitchHysteresisPercent";
Erik Språng2c58ba12019-01-23 16:53:18 +010042
Erik Språng4b4266f2019-01-23 12:48:13 +010043bool IsEnabled(const WebRtcKeyValueConfig* const key_value_config,
44 absl::string_view key) {
45 return key_value_config->Lookup(key).find("Enabled") == 0;
46}
47
Sebastian Jansson0ee80082019-08-14 13:16:26 +020048void ParseHysteresisFactor(const WebRtcKeyValueConfig* const key_value_config,
49 absl::string_view key,
50 double* output_value) {
Erik Språng2c58ba12019-01-23 16:53:18 +010051 std::string group_name = key_value_config->Lookup(key);
52 int percent = 0;
53 if (!group_name.empty() && sscanf(group_name.c_str(), "%d", &percent) == 1 &&
54 percent >= 0) {
Sebastian Jansson0ee80082019-08-14 13:16:26 +020055 *output_value = 1.0 + (percent / 100.0);
Erik Språng2c58ba12019-01-23 16:53:18 +010056 }
Erik Språng2c58ba12019-01-23 16:53:18 +010057}
58
Erik Språng71215642019-01-21 16:30:55 +010059} // namespace
60
Sebastian Jansson0ee80082019-08-14 13:16:26 +020061constexpr char CongestionWindowConfig::kKey[];
62
63std::unique_ptr<StructParametersParser> CongestionWindowConfig::Parser() {
64 return StructParametersParser::Create("QueueSize", &queue_size_ms, //
65 "MinBitrate", &min_bitrate_bps);
66}
67
68// static
69CongestionWindowConfig CongestionWindowConfig::Parse(absl::string_view config) {
70 CongestionWindowConfig res;
71 res.Parser()->Parse(config);
72 return res;
73}
74
75constexpr char VideoRateControlConfig::kKey[];
76
77std::unique_ptr<StructParametersParser> VideoRateControlConfig::Parser() {
78 // The empty comments ensures that each pair is on a separate line.
79 return StructParametersParser::Create(
Rasmus Brandt2b9317a2019-10-30 13:01:46 +010080 "pacing_factor", &pacing_factor, //
81 "alr_probing", &alr_probing, //
82 "vp8_qp_max", &vp8_qp_max, //
83 "vp8_min_pixels", &vp8_min_pixels, //
84 "trust_vp8", &trust_vp8, //
85 "trust_vp9", &trust_vp9, //
86 "video_hysteresis", &video_hysteresis, //
87 "screenshare_hysteresis", &screenshare_hysteresis, //
88 "probe_max_allocation", &probe_max_allocation, //
89 "bitrate_adjuster", &bitrate_adjuster, //
90 "adjuster_use_headroom", &adjuster_use_headroom, //
91 "vp8_s0_boost", &vp8_s0_boost, //
92 "vp8_base_heavy_tl3_alloc", &vp8_base_heavy_tl3_alloc, //
93 "vp8_dynamic_rate", &vp8_dynamic_rate, //
Sebastian Jansson0ee80082019-08-14 13:16:26 +020094 "vp9_dynamic_rate", &vp9_dynamic_rate);
95}
96
Erik Språng71215642019-01-21 16:30:55 +010097RateControlSettings::RateControlSettings(
98 const WebRtcKeyValueConfig* const key_value_config)
Sebastian Jansson0ee80082019-08-14 13:16:26 +020099 : congestion_window_config_(CongestionWindowConfig::Parse(
100 key_value_config->Lookup(CongestionWindowConfig::kKey))) {
101 video_config_.trust_vp8 =
102 IsEnabled(key_value_config, kVp8TrustedRateControllerFieldTrialName);
103 video_config_.trust_vp9 =
104 IsEnabled(key_value_config, kVp9TrustedRateControllerFieldTrialName);
Rasmus Brandt2b9317a2019-10-30 13:01:46 +0100105 video_config_.vp8_base_heavy_tl3_alloc = IsEnabled(
106 key_value_config, kUseBaseHeavyVp8Tl3RateAllocationFieldTrialName);
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200107 ParseHysteresisFactor(key_value_config, kVideoHysteresisFieldTrialname,
108 &video_config_.video_hysteresis);
109 ParseHysteresisFactor(key_value_config, kScreenshareHysteresisFieldTrialname,
110 &video_config_.screenshare_hysteresis);
111 video_config_.Parser()->Parse(
112 key_value_config->Lookup(VideoRateControlConfig::kKey));
Erik Språng71215642019-01-21 16:30:55 +0100113}
114
115RateControlSettings::~RateControlSettings() = default;
116RateControlSettings::RateControlSettings(RateControlSettings&&) = default;
117
118RateControlSettings RateControlSettings::ParseFromFieldTrials() {
119 FieldTrialBasedConfig field_trial_config;
120 return RateControlSettings(&field_trial_config);
121}
122
123RateControlSettings RateControlSettings::ParseFromKeyValueConfig(
124 const WebRtcKeyValueConfig* const key_value_config) {
125 FieldTrialBasedConfig field_trial_config;
126 return RateControlSettings(key_value_config ? key_value_config
127 : &field_trial_config);
128}
129
130bool RateControlSettings::UseCongestionWindow() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200131 return static_cast<bool>(congestion_window_config_.queue_size_ms);
Erik Språng71215642019-01-21 16:30:55 +0100132}
133
134int64_t RateControlSettings::GetCongestionWindowAdditionalTimeMs() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200135 return congestion_window_config_.queue_size_ms.value_or(
136 kDefaultAcceptedQueueMs);
Erik Språng71215642019-01-21 16:30:55 +0100137}
138
139bool RateControlSettings::UseCongestionWindowPushback() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200140 return congestion_window_config_.queue_size_ms &&
141 congestion_window_config_.min_bitrate_bps;
Erik Språng71215642019-01-21 16:30:55 +0100142}
143
144uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps()
145 const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200146 return congestion_window_config_.min_bitrate_bps.value_or(
Erik Språng71215642019-01-21 16:30:55 +0100147 kDefaultMinPushbackTargetBitrateBps);
148}
149
Erik Språngcd76eab2019-01-21 18:06:46 +0100150absl::optional<double> RateControlSettings::GetPacingFactor() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200151 return video_config_.pacing_factor;
Erik Språngcd76eab2019-01-21 18:06:46 +0100152}
153
154bool RateControlSettings::UseAlrProbing() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200155 return video_config_.alr_probing;
Erik Språngcd76eab2019-01-21 18:06:46 +0100156}
157
Åsa Perssond7dd49f2019-05-08 14:44:12 +0200158absl::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200159 if (video_config_.vp8_qp_max &&
160 (*video_config_.vp8_qp_max < 0 || *video_config_.vp8_qp_max > 63)) {
Åsa Perssond7dd49f2019-05-08 14:44:12 +0200161 RTC_LOG(LS_WARNING) << "Unsupported vp8_qp_max_ value, ignored.";
162 return absl::nullopt;
163 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200164 return video_config_.vp8_qp_max;
Åsa Perssond7dd49f2019-05-08 14:44:12 +0200165}
166
Åsa Perssona0948492019-06-27 13:44:30 +0200167absl::optional<int> RateControlSettings::LibvpxVp8MinPixels() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200168 if (video_config_.vp8_min_pixels && *video_config_.vp8_min_pixels < 1) {
Åsa Perssona0948492019-06-27 13:44:30 +0200169 return absl::nullopt;
170 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200171 return video_config_.vp8_min_pixels;
Åsa Perssona0948492019-06-27 13:44:30 +0200172}
173
Erik Språng4b4266f2019-01-23 12:48:13 +0100174bool RateControlSettings::LibvpxVp8TrustedRateController() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200175 return video_config_.trust_vp8;
Erik Språng4b4266f2019-01-23 12:48:13 +0100176}
177
Erik Språng7f24fb92019-02-13 10:49:37 +0100178bool RateControlSettings::Vp8BoostBaseLayerQuality() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200179 return video_config_.vp8_s0_boost;
Erik Språng7f24fb92019-02-13 10:49:37 +0100180}
181
Erik Språng7a3fe892019-04-15 12:22:55 +0200182bool RateControlSettings::Vp8DynamicRateSettings() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200183 return video_config_.vp8_dynamic_rate;
Erik Språng7a3fe892019-04-15 12:22:55 +0200184}
185
Erik Språng4b4266f2019-01-23 12:48:13 +0100186bool RateControlSettings::LibvpxVp9TrustedRateController() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200187 return video_config_.trust_vp9;
Erik Språng4b4266f2019-01-23 12:48:13 +0100188}
189
Erik Språng7a3fe892019-04-15 12:22:55 +0200190bool RateControlSettings::Vp9DynamicRateSettings() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200191 return video_config_.vp9_dynamic_rate;
Erik Språng7a3fe892019-04-15 12:22:55 +0200192}
193
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100194double RateControlSettings::GetSimulcastHysteresisFactor(
195 VideoCodecMode mode) const {
196 if (mode == VideoCodecMode::kScreensharing) {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200197 return video_config_.screenshare_hysteresis;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100198 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200199 return video_config_.video_hysteresis;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100200}
201
202double RateControlSettings::GetSimulcastHysteresisFactor(
203 VideoEncoderConfig::ContentType content_type) const {
204 if (content_type == VideoEncoderConfig::ContentType::kScreen) {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200205 return video_config_.screenshare_hysteresis;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100206 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200207 return video_config_.video_hysteresis;
Erik Språng2c58ba12019-01-23 16:53:18 +0100208}
209
Rasmus Brandt2b9317a2019-10-30 13:01:46 +0100210bool RateControlSettings::Vp8BaseHeavyTl3RateAllocation() const {
211 return video_config_.vp8_base_heavy_tl3_alloc;
212}
213
Erik Språng5118bbc2019-01-29 18:28:06 +0100214bool RateControlSettings::TriggerProbeOnMaxAllocatedBitrateChange() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200215 return video_config_.probe_max_allocation;
Erik Språng5118bbc2019-01-29 18:28:06 +0100216}
217
Erik Språng7ca375c2019-02-06 16:20:17 +0100218bool RateControlSettings::UseEncoderBitrateAdjuster() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200219 return video_config_.bitrate_adjuster;
Erik Språng7ca375c2019-02-06 16:20:17 +0100220}
221
Erik Språng3d11e2f2019-04-15 14:48:30 +0200222bool RateControlSettings::BitrateAdjusterCanUseNetworkHeadroom() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200223 return video_config_.adjuster_use_headroom;
Erik Språng3d11e2f2019-04-15 14:48:30 +0200224}
225
Erik Språng71215642019-01-21 16:30:55 +0100226} // namespace webrtc