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 "absl/strings/match.h"
19 #include "api/transport/field_trial_based_config.h"
20 #include "rtc_base/logging.h"
21 #include "rtc_base/numerics/safe_conversions.h"
22
23 namespace webrtc {
24
25 namespace {
26
27 const int kDefaultAcceptedQueueMs = 350;
28
29 const int kDefaultMinPushbackTargetBitrateBps = 30000;
30
31 const char kCongestionWindowDefaultFieldTrialString[] =
32 "QueueSize:350,MinBitrate:30000,DropFrame:true";
33
34 const char kUseBaseHeavyVp8Tl3RateAllocationFieldTrialName[] =
35 "WebRTC-UseBaseHeavyVP8TL3RateAllocation";
36
IsEnabled(const FieldTrialsView * const key_value_config,absl::string_view key)37 bool IsEnabled(const FieldTrialsView* const key_value_config,
38 absl::string_view key) {
39 return absl::StartsWith(key_value_config->Lookup(key), "Enabled");
40 }
41
42 } // namespace
43
44 constexpr char CongestionWindowConfig::kKey[];
45
Parser()46 std::unique_ptr<StructParametersParser> CongestionWindowConfig::Parser() {
47 return StructParametersParser::Create("QueueSize", &queue_size_ms, //
48 "MinBitrate", &min_bitrate_bps,
49 "InitWin", &initial_data_window,
50 "DropFrame", &drop_frame_only);
51 }
52
53 // static
Parse(absl::string_view config)54 CongestionWindowConfig CongestionWindowConfig::Parse(absl::string_view config) {
55 CongestionWindowConfig res;
56 res.Parser()->Parse(config);
57 return res;
58 }
59
60 constexpr char VideoRateControlConfig::kKey[];
61
Parser()62 std::unique_ptr<StructParametersParser> VideoRateControlConfig::Parser() {
63 // The empty comments ensures that each pair is on a separate line.
64 return StructParametersParser::Create(
65 "pacing_factor", &pacing_factor, //
66 "alr_probing", &alr_probing, //
67 "vp8_qp_max", &vp8_qp_max, //
68 "vp8_min_pixels", &vp8_min_pixels, //
69 "trust_vp8", &trust_vp8, //
70 "trust_vp9", &trust_vp9, //
71 "bitrate_adjuster", &bitrate_adjuster, //
72 "adjuster_use_headroom", &adjuster_use_headroom, //
73 "vp8_s0_boost", &vp8_s0_boost, //
74 "vp8_base_heavy_tl3_alloc", &vp8_base_heavy_tl3_alloc);
75 }
76
RateControlSettings(const FieldTrialsView * const key_value_config)77 RateControlSettings::RateControlSettings(
78 const FieldTrialsView* const key_value_config) {
79 std::string congestion_window_config =
80 key_value_config->Lookup(CongestionWindowConfig::kKey).empty()
81 ? kCongestionWindowDefaultFieldTrialString
82 : key_value_config->Lookup(CongestionWindowConfig::kKey);
83 congestion_window_config_ =
84 CongestionWindowConfig::Parse(congestion_window_config);
85 video_config_.vp8_base_heavy_tl3_alloc = IsEnabled(
86 key_value_config, kUseBaseHeavyVp8Tl3RateAllocationFieldTrialName);
87 video_config_.Parser()->Parse(
88 key_value_config->Lookup(VideoRateControlConfig::kKey));
89 }
90
91 RateControlSettings::~RateControlSettings() = default;
92 RateControlSettings::RateControlSettings(RateControlSettings&&) = default;
93
ParseFromFieldTrials()94 RateControlSettings RateControlSettings::ParseFromFieldTrials() {
95 FieldTrialBasedConfig field_trial_config;
96 return RateControlSettings(&field_trial_config);
97 }
98
ParseFromKeyValueConfig(const FieldTrialsView * const key_value_config)99 RateControlSettings RateControlSettings::ParseFromKeyValueConfig(
100 const FieldTrialsView* const key_value_config) {
101 FieldTrialBasedConfig field_trial_config;
102 return RateControlSettings(key_value_config ? key_value_config
103 : &field_trial_config);
104 }
105
UseCongestionWindow() const106 bool RateControlSettings::UseCongestionWindow() const {
107 return static_cast<bool>(congestion_window_config_.queue_size_ms);
108 }
109
GetCongestionWindowAdditionalTimeMs() const110 int64_t RateControlSettings::GetCongestionWindowAdditionalTimeMs() const {
111 return congestion_window_config_.queue_size_ms.value_or(
112 kDefaultAcceptedQueueMs);
113 }
114
UseCongestionWindowPushback() const115 bool RateControlSettings::UseCongestionWindowPushback() const {
116 return congestion_window_config_.queue_size_ms &&
117 congestion_window_config_.min_bitrate_bps;
118 }
119
UseCongestionWindowDropFrameOnly() const120 bool RateControlSettings::UseCongestionWindowDropFrameOnly() const {
121 return congestion_window_config_.drop_frame_only;
122 }
123
CongestionWindowMinPushbackTargetBitrateBps() const124 uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps()
125 const {
126 return congestion_window_config_.min_bitrate_bps.value_or(
127 kDefaultMinPushbackTargetBitrateBps);
128 }
129
130 absl::optional<DataSize>
CongestionWindowInitialDataWindow() const131 RateControlSettings::CongestionWindowInitialDataWindow() const {
132 return congestion_window_config_.initial_data_window;
133 }
134
GetPacingFactor() const135 absl::optional<double> RateControlSettings::GetPacingFactor() const {
136 return video_config_.pacing_factor;
137 }
138
UseAlrProbing() const139 bool RateControlSettings::UseAlrProbing() const {
140 return video_config_.alr_probing;
141 }
142
LibvpxVp8QpMax() const143 absl::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
144 if (video_config_.vp8_qp_max &&
145 (*video_config_.vp8_qp_max < 0 || *video_config_.vp8_qp_max > 63)) {
146 RTC_LOG(LS_WARNING) << "Unsupported vp8_qp_max_ value, ignored.";
147 return absl::nullopt;
148 }
149 return video_config_.vp8_qp_max;
150 }
151
LibvpxVp8MinPixels() const152 absl::optional<int> RateControlSettings::LibvpxVp8MinPixels() const {
153 if (video_config_.vp8_min_pixels && *video_config_.vp8_min_pixels < 1) {
154 return absl::nullopt;
155 }
156 return video_config_.vp8_min_pixels;
157 }
158
LibvpxVp8TrustedRateController() const159 bool RateControlSettings::LibvpxVp8TrustedRateController() const {
160 return video_config_.trust_vp8;
161 }
162
Vp8BoostBaseLayerQuality() const163 bool RateControlSettings::Vp8BoostBaseLayerQuality() const {
164 return video_config_.vp8_s0_boost;
165 }
166
LibvpxVp9TrustedRateController() const167 bool RateControlSettings::LibvpxVp9TrustedRateController() const {
168 return video_config_.trust_vp9;
169 }
170
Vp8BaseHeavyTl3RateAllocation() const171 bool RateControlSettings::Vp8BaseHeavyTl3RateAllocation() const {
172 return video_config_.vp8_base_heavy_tl3_alloc;
173 }
174
UseEncoderBitrateAdjuster() const175 bool RateControlSettings::UseEncoderBitrateAdjuster() const {
176 return video_config_.bitrate_adjuster;
177 }
178
BitrateAdjusterCanUseNetworkHeadroom() const179 bool RateControlSettings::BitrateAdjusterCanUseNetworkHeadroom() const {
180 return video_config_.adjuster_use_headroom;
181 }
182
183 } // namespace webrtc
184