blob: b82a981d0defe4cf6785a2cce54d372b5390323d [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
Erik Språng2c58ba12019-01-23 16:53:18 +010035const char* kVideoHysteresisFieldTrialname =
36 "WebRTC-SimulcastUpswitchHysteresisPercent";
Erik Språng2c58ba12019-01-23 16:53:18 +010037const char* kScreenshareHysteresisFieldTrialname =
38 "WebRTC-SimulcastScreenshareUpswitchHysteresisPercent";
Erik Språng2c58ba12019-01-23 16:53:18 +010039
Erik Språng4b4266f2019-01-23 12:48:13 +010040bool IsEnabled(const WebRtcKeyValueConfig* const key_value_config,
41 absl::string_view key) {
42 return key_value_config->Lookup(key).find("Enabled") == 0;
43}
44
Sebastian Jansson0ee80082019-08-14 13:16:26 +020045void ParseHysteresisFactor(const WebRtcKeyValueConfig* const key_value_config,
46 absl::string_view key,
47 double* output_value) {
Erik Språng2c58ba12019-01-23 16:53:18 +010048 std::string group_name = key_value_config->Lookup(key);
49 int percent = 0;
50 if (!group_name.empty() && sscanf(group_name.c_str(), "%d", &percent) == 1 &&
51 percent >= 0) {
Sebastian Jansson0ee80082019-08-14 13:16:26 +020052 *output_value = 1.0 + (percent / 100.0);
Erik Språng2c58ba12019-01-23 16:53:18 +010053 }
Erik Språng2c58ba12019-01-23 16:53:18 +010054}
55
Erik Språng71215642019-01-21 16:30:55 +010056} // namespace
57
Sebastian Jansson0ee80082019-08-14 13:16:26 +020058constexpr char CongestionWindowConfig::kKey[];
59
60std::unique_ptr<StructParametersParser> CongestionWindowConfig::Parser() {
61 return StructParametersParser::Create("QueueSize", &queue_size_ms, //
62 "MinBitrate", &min_bitrate_bps);
63}
64
65// static
66CongestionWindowConfig CongestionWindowConfig::Parse(absl::string_view config) {
67 CongestionWindowConfig res;
68 res.Parser()->Parse(config);
69 return res;
70}
71
72constexpr char VideoRateControlConfig::kKey[];
73
74std::unique_ptr<StructParametersParser> VideoRateControlConfig::Parser() {
75 // The empty comments ensures that each pair is on a separate line.
76 return StructParametersParser::Create(
77 "pacing_factor", &pacing_factor, //
78 "alr_probing", &alr_probing, //
79 "vp8_qp_max", &vp8_qp_max, //
80 "vp8_min_pixels", &vp8_min_pixels, //
81 "trust_vp8", &trust_vp8, //
82 "trust_vp9", &trust_vp9, //
83 "video_hysteresis", &video_hysteresis, //
84 "screenshare_hysteresis", &screenshare_hysteresis, //
85 "probe_max_allocation", &probe_max_allocation, //
86 "bitrate_adjuster", &bitrate_adjuster, //
87 "adjuster_use_headroom", &adjuster_use_headroom, //
88 "vp8_s0_boost", &vp8_s0_boost, //
89 "vp8_dynamic_rate", &vp8_dynamic_rate, //
90 "vp9_dynamic_rate", &vp9_dynamic_rate);
91}
92
Erik Språng71215642019-01-21 16:30:55 +010093RateControlSettings::RateControlSettings(
94 const WebRtcKeyValueConfig* const key_value_config)
Sebastian Jansson0ee80082019-08-14 13:16:26 +020095 : congestion_window_config_(CongestionWindowConfig::Parse(
96 key_value_config->Lookup(CongestionWindowConfig::kKey))) {
97 video_config_.trust_vp8 =
98 IsEnabled(key_value_config, kVp8TrustedRateControllerFieldTrialName);
99 video_config_.trust_vp9 =
100 IsEnabled(key_value_config, kVp9TrustedRateControllerFieldTrialName);
101 ParseHysteresisFactor(key_value_config, kVideoHysteresisFieldTrialname,
102 &video_config_.video_hysteresis);
103 ParseHysteresisFactor(key_value_config, kScreenshareHysteresisFieldTrialname,
104 &video_config_.screenshare_hysteresis);
105 video_config_.Parser()->Parse(
106 key_value_config->Lookup(VideoRateControlConfig::kKey));
Erik Språng71215642019-01-21 16:30:55 +0100107}
108
109RateControlSettings::~RateControlSettings() = default;
110RateControlSettings::RateControlSettings(RateControlSettings&&) = default;
111
112RateControlSettings RateControlSettings::ParseFromFieldTrials() {
113 FieldTrialBasedConfig field_trial_config;
114 return RateControlSettings(&field_trial_config);
115}
116
117RateControlSettings RateControlSettings::ParseFromKeyValueConfig(
118 const WebRtcKeyValueConfig* const key_value_config) {
119 FieldTrialBasedConfig field_trial_config;
120 return RateControlSettings(key_value_config ? key_value_config
121 : &field_trial_config);
122}
123
124bool RateControlSettings::UseCongestionWindow() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200125 return static_cast<bool>(congestion_window_config_.queue_size_ms);
Erik Språng71215642019-01-21 16:30:55 +0100126}
127
128int64_t RateControlSettings::GetCongestionWindowAdditionalTimeMs() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200129 return congestion_window_config_.queue_size_ms.value_or(
130 kDefaultAcceptedQueueMs);
Erik Språng71215642019-01-21 16:30:55 +0100131}
132
133bool RateControlSettings::UseCongestionWindowPushback() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200134 return congestion_window_config_.queue_size_ms &&
135 congestion_window_config_.min_bitrate_bps;
Erik Språng71215642019-01-21 16:30:55 +0100136}
137
138uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps()
139 const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200140 return congestion_window_config_.min_bitrate_bps.value_or(
Erik Språng71215642019-01-21 16:30:55 +0100141 kDefaultMinPushbackTargetBitrateBps);
142}
143
Erik Språngcd76eab2019-01-21 18:06:46 +0100144absl::optional<double> RateControlSettings::GetPacingFactor() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200145 return video_config_.pacing_factor;
Erik Språngcd76eab2019-01-21 18:06:46 +0100146}
147
148bool RateControlSettings::UseAlrProbing() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200149 return video_config_.alr_probing;
Erik Språngcd76eab2019-01-21 18:06:46 +0100150}
151
Åsa Perssond7dd49f2019-05-08 14:44:12 +0200152absl::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200153 if (video_config_.vp8_qp_max &&
154 (*video_config_.vp8_qp_max < 0 || *video_config_.vp8_qp_max > 63)) {
Åsa Perssond7dd49f2019-05-08 14:44:12 +0200155 RTC_LOG(LS_WARNING) << "Unsupported vp8_qp_max_ value, ignored.";
156 return absl::nullopt;
157 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200158 return video_config_.vp8_qp_max;
Åsa Perssond7dd49f2019-05-08 14:44:12 +0200159}
160
Åsa Perssona0948492019-06-27 13:44:30 +0200161absl::optional<int> RateControlSettings::LibvpxVp8MinPixels() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200162 if (video_config_.vp8_min_pixels && *video_config_.vp8_min_pixels < 1) {
Åsa Perssona0948492019-06-27 13:44:30 +0200163 return absl::nullopt;
164 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200165 return video_config_.vp8_min_pixels;
Åsa Perssona0948492019-06-27 13:44:30 +0200166}
167
Erik Språng4b4266f2019-01-23 12:48:13 +0100168bool RateControlSettings::LibvpxVp8TrustedRateController() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200169 return video_config_.trust_vp8;
Erik Språng4b4266f2019-01-23 12:48:13 +0100170}
171
Erik Språng7f24fb92019-02-13 10:49:37 +0100172bool RateControlSettings::Vp8BoostBaseLayerQuality() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200173 return video_config_.vp8_s0_boost;
Erik Språng7f24fb92019-02-13 10:49:37 +0100174}
175
Erik Språng7a3fe892019-04-15 12:22:55 +0200176bool RateControlSettings::Vp8DynamicRateSettings() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200177 return video_config_.vp8_dynamic_rate;
Erik Språng7a3fe892019-04-15 12:22:55 +0200178}
179
Erik Språng4b4266f2019-01-23 12:48:13 +0100180bool RateControlSettings::LibvpxVp9TrustedRateController() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200181 return video_config_.trust_vp9;
Erik Språng4b4266f2019-01-23 12:48:13 +0100182}
183
Erik Språng7a3fe892019-04-15 12:22:55 +0200184bool RateControlSettings::Vp9DynamicRateSettings() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200185 return video_config_.vp9_dynamic_rate;
Erik Språng7a3fe892019-04-15 12:22:55 +0200186}
187
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100188double RateControlSettings::GetSimulcastHysteresisFactor(
189 VideoCodecMode mode) const {
190 if (mode == VideoCodecMode::kScreensharing) {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200191 return video_config_.screenshare_hysteresis;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100192 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200193 return video_config_.video_hysteresis;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100194}
195
196double RateControlSettings::GetSimulcastHysteresisFactor(
197 VideoEncoderConfig::ContentType content_type) const {
198 if (content_type == VideoEncoderConfig::ContentType::kScreen) {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200199 return video_config_.screenshare_hysteresis;
Rasmus Brandtc402dbe2019-02-04 11:09:46 +0100200 }
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200201 return video_config_.video_hysteresis;
Erik Språng2c58ba12019-01-23 16:53:18 +0100202}
203
Erik Språng5118bbc2019-01-29 18:28:06 +0100204bool RateControlSettings::TriggerProbeOnMaxAllocatedBitrateChange() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200205 return video_config_.probe_max_allocation;
Erik Språng5118bbc2019-01-29 18:28:06 +0100206}
207
Erik Språng7ca375c2019-02-06 16:20:17 +0100208bool RateControlSettings::UseEncoderBitrateAdjuster() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200209 return video_config_.bitrate_adjuster;
Erik Språng7ca375c2019-02-06 16:20:17 +0100210}
211
Erik Språng3d11e2f2019-04-15 14:48:30 +0200212bool RateControlSettings::BitrateAdjusterCanUseNetworkHeadroom() const {
Sebastian Jansson0ee80082019-08-14 13:16:26 +0200213 return video_config_.adjuster_use_headroom;
Erik Språng3d11e2f2019-04-15 14:48:30 +0200214}
215
Erik Språng71215642019-01-21 16:30:55 +0100216} // namespace webrtc