Move congestion window field trial parsing to new class.

This cl is part of work to move several experiments into a joint
experiment group. Most of them vill be ralted to video, hence the name.

Bug: webrtc:10223
Change-Id: I8767c43abb6aa910ab51710eeb908e0f9df1e296
Reviewed-on: https://webrtc-review.googlesource.com/c/118361
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26346}
This commit is contained in:
Erik Språng
2019-01-21 16:30:55 +01:00
committed by Commit Bot
parent b4c6d1e6d9
commit 7121564e97
12 changed files with 221 additions and 149 deletions

View File

@ -46,6 +46,7 @@ rtc_static_library("congestion_controller") {
"../../rtc_base:deprecation",
"../../rtc_base:ptr_util",
"../../rtc_base:rate_limiter",
"../../rtc_base/experiments:rate_control_settings",
"../../rtc_base/network:sent_packet",
"../../system_wrappers",
"../../system_wrappers:field_trial",

View File

@ -45,6 +45,7 @@ rtc_static_library("goog_cc") {
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/experiments:alr_experiment",
"../../../rtc_base/experiments:field_trial_parser",
"../../../rtc_base/experiments:rate_control_settings",
"../../../system_wrappers",
"../../bitrate_controller",
"../../remote_bitrate_estimator",
@ -77,6 +78,7 @@ rtc_source_set("pushback_controller") {
"../../../api/units:data_size",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/experiments:rate_control_settings",
"//third_party/abseil-cpp/absl/types:optional",
]
}

View File

@ -15,46 +15,18 @@
#include "modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/rate_control_settings.h"
namespace webrtc {
namespace {
// When CongestionWindowPushback is enabled, the pacer is oblivious to
// the congestion window. The relation between outstanding data and
// the congestion window affects encoder allocations directly.
// This experiment is build on top of congestion window experiment.
const char kCongestionPushbackExperiment[] = "WebRTC-CongestionWindowPushback";
const uint32_t kDefaultMinPushbackTargetBitrateBps = 30000;
bool ReadCongestionWindowPushbackExperimentParameter(
const WebRtcKeyValueConfig* key_value_config,
uint32_t* min_pushback_target_bitrate_bps) {
RTC_DCHECK(min_pushback_target_bitrate_bps);
std::string experiment_string =
key_value_config->Lookup(kCongestionPushbackExperiment);
int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%" PRIu32,
min_pushback_target_bitrate_bps);
if (parsed_values == 1) {
RTC_CHECK_GE(*min_pushback_target_bitrate_bps, 0)
<< "Min pushback target bitrate must be greater than or equal to 0.";
return true;
}
return false;
}
} // namespace
CongestionWindowPushbackController::CongestionWindowPushbackController(
const WebRtcKeyValueConfig* key_value_config)
: add_pacing_(
key_value_config->Lookup("WebRTC-AddPacingToCongestionWindowPushback")
.find("Enabled") == 0) {
if (!ReadCongestionWindowPushbackExperimentParameter(
key_value_config, &min_pushback_target_bitrate_bps_)) {
min_pushback_target_bitrate_bps_ = kDefaultMinPushbackTargetBitrateBps;
}
}
.find("Enabled") == 0),
min_pushback_target_bitrate_bps_(
RateControlSettings::ParseFromKeyValueConfig(key_value_config)
.CongestionWindowMinPushbackTargetBitrateBps()) {}
CongestionWindowPushbackController::CongestionWindowPushbackController(
const WebRtcKeyValueConfig* key_value_config,

View File

@ -43,7 +43,7 @@ class CongestionWindowPushbackController {
int64_t outstanding_bytes_ = 0;
int64_t pacing_bytes_ = 0;
const bool add_pacing_;
uint32_t min_pushback_target_bitrate_bps_;
const uint32_t min_pushback_target_bitrate_bps_;
double encoding_rate_ratio_ = 1.0;
};

View File

@ -32,15 +32,6 @@
namespace webrtc {
namespace {
const char kCwndExperiment[] = "WebRTC-CwndExperiment";
// When CongestionWindowPushback is enabled, the pacer is oblivious to
// the congestion window. The relation between outstanding data and
// the congestion window affects encoder allocations directly.
const char kCongestionPushbackExperiment[] = "WebRTC-CongestionWindowPushback";
const int64_t kDefaultAcceptedQueueMs = 250;
// From RTCPSender video report interval.
constexpr TimeDelta kLossUpdateInterval = TimeDelta::Millis<1000>();
@ -51,37 +42,6 @@ constexpr TimeDelta kLossUpdateInterval = TimeDelta::Millis<1000>();
// overshoots from the encoder.
const float kDefaultPaceMultiplier = 2.5f;
std::unique_ptr<CongestionWindowPushbackController>
MaybeCreateCongestionWindowPushbackController(
const WebRtcKeyValueConfig* const key_value_config) {
if (key_value_config->Lookup(kCongestionPushbackExperiment).find("Enabled") ==
0 &&
key_value_config->Lookup(kCwndExperiment).find("Enabled") == 0)
return absl::make_unique<CongestionWindowPushbackController>(
key_value_config);
return nullptr;
}
bool CwndExperimentEnabled(const WebRtcKeyValueConfig* const key_value_config) {
std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
// The experiment is enabled iff the field trial string begins with "Enabled".
return experiment_string.find("Enabled") == 0;
}
bool ReadCwndExperimentParameter(
const WebRtcKeyValueConfig* const key_value_config,
int64_t* accepted_queue_ms) {
RTC_DCHECK(accepted_queue_ms);
std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
int parsed_values =
sscanf(experiment_string.c_str(), "Enabled-%" PRId64, accepted_queue_ms);
if (parsed_values == 1) {
RTC_CHECK_GE(*accepted_queue_ms, 0)
<< "Accepted must be greater than or equal to 0.";
return true;
}
return false;
}
// Makes sure that the bitrate and the min, max values are in valid range.
static void ClampBitrates(int64_t* bitrate_bps,
int64_t* min_bitrate_bps,
@ -140,9 +100,14 @@ GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
fall_back_to_probe_rate_(
key_value_config_->Lookup("WebRTC-Bwe-ProbeRateFallback")
.find("Enabled") == 0),
rate_control_experiments_(
RateControlSettings::ParseFromKeyValueConfig(key_value_config_)),
probe_controller_(new ProbeController(key_value_config_)),
congestion_window_pushback_controller_(
MaybeCreateCongestionWindowPushbackController(key_value_config_)),
rate_control_experiments_.UseCongestionWindowPushback()
? absl::make_unique<CongestionWindowPushbackController>(
key_value_config_)
: nullptr),
bandwidth_estimation_(
absl::make_unique<SendSideBandwidthEstimation>(event_log_)),
alr_detector_(absl::make_unique<AlrDetector>()),
@ -170,21 +135,13 @@ GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
DataRate::Zero())),
max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
DataRate::Zero())),
max_total_allocated_bitrate_(DataRate::Zero()),
in_cwnd_experiment_(CwndExperimentEnabled(key_value_config_)),
accepted_queue_ms_(kDefaultAcceptedQueueMs) {
max_total_allocated_bitrate_(DataRate::Zero()) {
RTC_DCHECK(config.constraints.at_time.IsFinite());
ParseFieldTrial(
{&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
key_value_config_->Lookup("WebRTC-Bwe-SafeResetOnRouteChange"));
if (delay_based_bwe_)
delay_based_bwe_->SetMinBitrate(congestion_controller::GetMinBitrate());
if (in_cwnd_experiment_ &&
!ReadCwndExperimentParameter(key_value_config_, &accepted_queue_ms_)) {
RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
"from field trial string. Experiment disabled.";
in_cwnd_experiment_ = false;
}
}
GoogCcNetworkController::~GoogCcNetworkController() {}
@ -589,13 +546,15 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
// No valid RTT could be because send-side BWE isn't used, in which case
// we don't try to limit the outstanding packets.
if (in_cwnd_experiment_ && max_feedback_rtt.IsFinite()) {
if (rate_control_experiments_.UseCongestionWindow() &&
max_feedback_rtt.IsFinite()) {
int64_t min_feedback_max_rtt_ms =
*std::min_element(feedback_max_rtts_.begin(), feedback_max_rtts_.end());
const DataSize kMinCwnd = DataSize::bytes(2 * 1500);
TimeDelta time_window =
TimeDelta::ms(min_feedback_max_rtt_ms + accepted_queue_ms_);
TimeDelta time_window = TimeDelta::ms(
min_feedback_max_rtt_ms +
rate_control_experiments_.GetCongestionWindowAdditionalTimeMs());
DataSize data_window = last_raw_target_rate_ * time_window;
if (current_data_window_) {
data_window =

View File

@ -34,6 +34,7 @@
#include "modules/congestion_controller/goog_cc/probe_controller.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/experiments/rate_control_settings.h"
namespace webrtc {
@ -78,6 +79,7 @@ class GoogCcNetworkController : public NetworkControllerInterface {
FieldTrialFlag safe_reset_acknowledged_rate_;
const bool use_stable_bandwidth_estimate_;
const bool fall_back_to_probe_rate_;
const RateControlSettings rate_control_experiments_;
const std::unique_ptr<ProbeController> probe_controller_;
const std::unique_ptr<CongestionWindowPushbackController>
@ -113,8 +115,6 @@ class GoogCcNetworkController : public NetworkControllerInterface {
DataRate max_padding_rate_;
DataRate max_total_allocated_bitrate_;
bool in_cwnd_experiment_;
int64_t accepted_queue_ms_;
bool previously_in_alr = false;
absl::optional<DataSize> current_data_window_;

View File

@ -168,8 +168,7 @@ class DEPRECATED_SendSideCongestionController
std::unique_ptr<ProbeBitrateEstimator> probe_bitrate_estimator_
RTC_GUARDED_BY(bwe_lock_);
std::unique_ptr<DelayBasedBwe> delay_based_bwe_ RTC_GUARDED_BY(bwe_lock_);
bool in_cwnd_experiment_;
int64_t accepted_queue_ms_;
absl::optional<int64_t> cwnd_experiment_parameter_;
bool was_in_alr_;
const bool send_side_bwe_with_overhead_;
size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(bwe_lock_);

View File

@ -28,6 +28,7 @@
#include "modules/congestion_controller/goog_cc/probe_controller.h"
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/rate_control_settings.h"
#include "rtc_base/logging.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/rate_limiter.h"
@ -36,48 +37,7 @@
namespace webrtc {
namespace {
const char kCwndExperiment[] = "WebRTC-CwndExperiment";
const char kPacerPushbackExperiment[] = "WebRTC-PacerPushbackExperiment";
// When CongestionWindowPushback is enabled, the pacer is oblivious to
// the congestion window. The relation between outstanding data and
// the congestion window affects encoder allocations directly.
const char kCongestionPushbackExperiment[] = "WebRTC-CongestionWindowPushback";
const int64_t kDefaultAcceptedQueueMs = 250;
bool CwndExperimentEnabled(const WebRtcKeyValueConfig* const key_value_config) {
std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
// The experiment is enabled iff the field trial string begins with "Enabled".
return experiment_string.find("Enabled") == 0;
}
bool ReadCwndExperimentParameter(
const WebRtcKeyValueConfig* const key_value_config,
int64_t* accepted_queue_ms) {
RTC_DCHECK(accepted_queue_ms);
std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
int parsed_values =
sscanf(experiment_string.c_str(), "Enabled-%" PRId64, accepted_queue_ms);
if (parsed_values == 1) {
RTC_CHECK_GE(*accepted_queue_ms, 0)
<< "Accepted must be greater than or equal to 0.";
return true;
}
return false;
}
std::unique_ptr<CongestionWindowPushbackController>
MaybeCreateCongestionWindowPushbackController(
const WebRtcKeyValueConfig* const key_value_config) {
if (key_value_config->Lookup(kCongestionPushbackExperiment).find("Enabled") ==
0 &&
key_value_config->Lookup(kCwndExperiment).find("Enabled") == 0)
return absl::make_unique<CongestionWindowPushbackController>(
key_value_config);
return nullptr;
}
static const int64_t kRetransmitWindowSizeMs = 500;
// Makes sure that the bitrate and the min, max values are in valid range.
@ -152,24 +112,25 @@ DEPRECATED_SendSideCongestionController::
min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log_)),
delay_based_bwe_(new DelayBasedBwe(key_value_config_, event_log_)),
in_cwnd_experiment_(CwndExperimentEnabled(key_value_config_)),
accepted_queue_ms_(kDefaultAcceptedQueueMs),
was_in_alr_(false),
send_side_bwe_with_overhead_(
key_value_config_->Lookup("WebRTC-SendSideBwe-WithOverhead")
.find("Enabled") == 0),
transport_overhead_bytes_per_packet_(0),
pacer_pushback_experiment_(
IsPacerPushbackExperimentEnabled(key_value_config_)),
congestion_window_pushback_controller_(
MaybeCreateCongestionWindowPushbackController(key_value_config_)) {
delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps_));
if (in_cwnd_experiment_ &&
!ReadCwndExperimentParameter(key_value_config_, &accepted_queue_ms_)) {
RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
"from field trial string. Experiment disabled.";
in_cwnd_experiment_ = false;
IsPacerPushbackExperimentEnabled(key_value_config_)) {
RateControlSettings experiment_params =
RateControlSettings::ParseFromKeyValueConfig(key_value_config);
if (experiment_params.UseCongestionWindow()) {
cwnd_experiment_parameter_ =
experiment_params.GetCongestionWindowAdditionalTimeMs();
}
if (experiment_params.UseCongestionWindowPushback()) {
congestion_window_pushback_controller_ =
absl::make_unique<CongestionWindowPushbackController>(
key_value_config_);
}
delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps_));
}
DEPRECATED_SendSideCongestionController::
@ -185,8 +146,7 @@ void DEPRECATED_SendSideCongestionController::EnableCongestionWindowPushback(
RTC_CHECK_GE(min_pushback_target_bitrate_bps, 0)
<< "Min pushback target bitrate must be greater than or equal to 0.";
in_cwnd_experiment_ = true;
accepted_queue_ms_ = accepted_queue_ms;
cwnd_experiment_parameter_ = accepted_queue_ms;
congestion_window_pushback_controller_ =
absl::make_unique<CongestionWindowPushbackController>(
key_value_config_, min_pushback_target_bitrate_bps);
@ -364,7 +324,7 @@ void DEPRECATED_SendSideCongestionController::OnSentPacket(
return;
transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
sent_packet.send_time_ms);
if (in_cwnd_experiment_)
if (cwnd_experiment_parameter_)
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
}
@ -472,14 +432,14 @@ void DEPRECATED_SendSideCongestionController::OnTransportFeedback(
rtc::CritScope cs(&probe_lock_);
SendProbes(probe_controller_->RequestProbe(clock_->TimeInMilliseconds()));
}
if (in_cwnd_experiment_) {
if (cwnd_experiment_parameter_) {
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
}
}
void DEPRECATED_SendSideCongestionController::LimitOutstandingBytes(
size_t num_outstanding_bytes) {
RTC_DCHECK(in_cwnd_experiment_);
RTC_DCHECK(cwnd_experiment_parameter_);
rtc::CritScope lock(&network_state_lock_);
absl::optional<int64_t> min_rtt_ms =
transport_feedback_adapter_.GetMinFeedbackLoopRtt();
@ -489,7 +449,7 @@ void DEPRECATED_SendSideCongestionController::LimitOutstandingBytes(
return;
const size_t kMinCwndBytes = 2 * 1500;
size_t max_outstanding_bytes =
std::max<size_t>((*min_rtt_ms + accepted_queue_ms_) *
std::max<size_t>((*min_rtt_ms + *cwnd_experiment_parameter_) *
last_reported_bitrate_bps_ / 1000 / 8,
kMinCwndBytes);
if (congestion_window_pushback_controller_) {

View File

@ -97,6 +97,22 @@ rtc_static_library("jitter_upper_bound_experiment") {
]
}
rtc_static_library("rate_control_settings") {
sources = [
"rate_control_settings.cc",
"rate_control_settings.h",
]
deps = [
":field_trial_parser",
"../:rtc_base_approved",
"../../api/transport:field_trial_based_config",
"../../api/transport:webrtc_key_value_config",
"../../system_wrappers:field_trial",
"//third_party/abseil-cpp/absl/memory:memory",
"//third_party/abseil-cpp/absl/types:optional",
]
}
if (rtc_include_tests) {
rtc_source_set("experiments_unittests") {
testonly = true

View File

@ -6,3 +6,5 @@ per-file jitter_upper_bound_experiment*=sprang@webrtc.org
per-file normalize_simulcast_size_experiment*=asapersson@webrtc.org
per-file quality_scaling_experiment*=asapersson@webrtc.org
per-file rtt_mult_experiment*=mhoro@webrtc.org
per-file rate_control_settings*=sprang@webrtc.org
per-file rate_control_settings*=srte@webrtc.org

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "rtc_base/experiments/rate_control_settings.h"
#include <inttypes.h>
#include <stdio.h>
#include <string>
#include "api/transport/field_trial_based_config.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
namespace {
const char* kCongestionWindowFieldTrialName = "WebRTC-CwndExperiment";
const int kDefaultAcceptedQueueMs = 250;
const char* kCongestionWindowPushbackFieldTrialName =
"WebRTC-CongestionWindowPushback";
const int kDefaultMinPushbackTargetBitrateBps = 30000;
absl::optional<int> MaybeReadCwndExperimentParameter(
const WebRtcKeyValueConfig* const key_value_config) {
int64_t accepted_queue_ms;
std::string experiment_string =
key_value_config->Lookup(kCongestionWindowFieldTrialName);
int parsed_values =
sscanf(experiment_string.c_str(), "Enabled-%" PRId64, &accepted_queue_ms);
if (parsed_values == 1) {
RTC_CHECK_GE(accepted_queue_ms, 0)
<< "Accepted must be greater than or equal to 0.";
return rtc::checked_cast<int>(accepted_queue_ms);
} else if (experiment_string.find("Enabled") == 0) {
return kDefaultAcceptedQueueMs;
}
return absl::nullopt;
}
absl::optional<int> MaybeReadCongestionWindowPushbackExperimentParameter(
const WebRtcKeyValueConfig* const key_value_config) {
uint32_t min_pushback_target_bitrate_bps;
std::string experiment_string =
key_value_config->Lookup(kCongestionWindowPushbackFieldTrialName);
int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%" PRIu32,
&min_pushback_target_bitrate_bps);
if (parsed_values == 1) {
RTC_CHECK_GE(min_pushback_target_bitrate_bps, 0)
<< "Min pushback target bitrate must be greater than or equal to 0.";
return rtc::checked_cast<int>(min_pushback_target_bitrate_bps);
} else if (experiment_string.find("Enabled") == 0) {
return kDefaultMinPushbackTargetBitrateBps;
}
return absl::nullopt;
}
} // namespace
RateControlSettings::RateControlSettings(
const WebRtcKeyValueConfig* const key_value_config)
: congestion_window_("cwnd",
MaybeReadCwndExperimentParameter(key_value_config)),
congestion_window_pushback_(
"cwnd_pushback",
MaybeReadCongestionWindowPushbackExperimentParameter(
key_value_config)) {
ParseFieldTrial({&congestion_window_, &congestion_window_pushback_},
key_value_config->Lookup("WebRTC-VideoRateControl"));
}
RateControlSettings::~RateControlSettings() = default;
RateControlSettings::RateControlSettings(RateControlSettings&&) = default;
RateControlSettings RateControlSettings::ParseFromFieldTrials() {
FieldTrialBasedConfig field_trial_config;
return RateControlSettings(&field_trial_config);
}
RateControlSettings RateControlSettings::ParseFromKeyValueConfig(
const WebRtcKeyValueConfig* const key_value_config) {
FieldTrialBasedConfig field_trial_config;
return RateControlSettings(key_value_config ? key_value_config
: &field_trial_config);
}
bool RateControlSettings::UseCongestionWindow() const {
return congestion_window_;
}
int64_t RateControlSettings::GetCongestionWindowAdditionalTimeMs() const {
return congestion_window_.GetOptional().value_or(kDefaultAcceptedQueueMs);
}
bool RateControlSettings::UseCongestionWindowPushback() const {
return congestion_window_ && congestion_window_pushback_;
}
uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps()
const {
return congestion_window_pushback_.GetOptional().value_or(
kDefaultMinPushbackTargetBitrateBps);
}
} // namespace webrtc

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef RTC_BASE_EXPERIMENTS_RATE_CONTROL_SETTINGS_H_
#define RTC_BASE_EXPERIMENTS_RATE_CONTROL_SETTINGS_H_
#include "absl/types/optional.h"
#include "api/transport/webrtc_key_value_config.h"
#include "rtc_base/experiments/field_trial_parser.h"
namespace webrtc {
class RateControlSettings final {
public:
~RateControlSettings();
RateControlSettings(RateControlSettings&&);
static RateControlSettings ParseFromFieldTrials();
static RateControlSettings ParseFromKeyValueConfig(
const WebRtcKeyValueConfig* const key_value_config);
// When CongestionWindowPushback is enabled, the pacer is oblivious to
// the congestion window. The relation between outstanding data and
// the congestion window affects encoder allocations directly.
bool UseCongestionWindow() const;
int64_t GetCongestionWindowAdditionalTimeMs() const;
bool UseCongestionWindowPushback() const;
uint32_t CongestionWindowMinPushbackTargetBitrateBps() const;
private:
explicit RateControlSettings(
const WebRtcKeyValueConfig* const key_value_config);
FieldTrialOptional<int> congestion_window_;
FieldTrialOptional<int> congestion_window_pushback_;
};
} // namespace webrtc
#endif // RTC_BASE_EXPERIMENTS_RATE_CONTROL_SETTINGS_H_