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:
@ -46,6 +46,7 @@ rtc_static_library("congestion_controller") {
|
|||||||
"../../rtc_base:deprecation",
|
"../../rtc_base:deprecation",
|
||||||
"../../rtc_base:ptr_util",
|
"../../rtc_base:ptr_util",
|
||||||
"../../rtc_base:rate_limiter",
|
"../../rtc_base:rate_limiter",
|
||||||
|
"../../rtc_base/experiments:rate_control_settings",
|
||||||
"../../rtc_base/network:sent_packet",
|
"../../rtc_base/network:sent_packet",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
"../../system_wrappers:field_trial",
|
"../../system_wrappers:field_trial",
|
||||||
|
@ -45,6 +45,7 @@ rtc_static_library("goog_cc") {
|
|||||||
"../../../rtc_base:rtc_base_approved",
|
"../../../rtc_base:rtc_base_approved",
|
||||||
"../../../rtc_base/experiments:alr_experiment",
|
"../../../rtc_base/experiments:alr_experiment",
|
||||||
"../../../rtc_base/experiments:field_trial_parser",
|
"../../../rtc_base/experiments:field_trial_parser",
|
||||||
|
"../../../rtc_base/experiments:rate_control_settings",
|
||||||
"../../../system_wrappers",
|
"../../../system_wrappers",
|
||||||
"../../bitrate_controller",
|
"../../bitrate_controller",
|
||||||
"../../remote_bitrate_estimator",
|
"../../remote_bitrate_estimator",
|
||||||
@ -77,6 +78,7 @@ rtc_source_set("pushback_controller") {
|
|||||||
"../../../api/units:data_size",
|
"../../../api/units:data_size",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
"../../../rtc_base:rtc_base_approved",
|
"../../../rtc_base:rtc_base_approved",
|
||||||
|
"../../../rtc_base/experiments:rate_control_settings",
|
||||||
"//third_party/abseil-cpp/absl/types:optional",
|
"//third_party/abseil-cpp/absl/types:optional",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -15,46 +15,18 @@
|
|||||||
|
|
||||||
#include "modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h"
|
#include "modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
#include "rtc_base/experiments/rate_control_settings.h"
|
||||||
|
|
||||||
namespace webrtc {
|
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(
|
CongestionWindowPushbackController::CongestionWindowPushbackController(
|
||||||
const WebRtcKeyValueConfig* key_value_config)
|
const WebRtcKeyValueConfig* key_value_config)
|
||||||
: add_pacing_(
|
: add_pacing_(
|
||||||
key_value_config->Lookup("WebRTC-AddPacingToCongestionWindowPushback")
|
key_value_config->Lookup("WebRTC-AddPacingToCongestionWindowPushback")
|
||||||
.find("Enabled") == 0) {
|
.find("Enabled") == 0),
|
||||||
if (!ReadCongestionWindowPushbackExperimentParameter(
|
min_pushback_target_bitrate_bps_(
|
||||||
key_value_config, &min_pushback_target_bitrate_bps_)) {
|
RateControlSettings::ParseFromKeyValueConfig(key_value_config)
|
||||||
min_pushback_target_bitrate_bps_ = kDefaultMinPushbackTargetBitrateBps;
|
.CongestionWindowMinPushbackTargetBitrateBps()) {}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CongestionWindowPushbackController::CongestionWindowPushbackController(
|
CongestionWindowPushbackController::CongestionWindowPushbackController(
|
||||||
const WebRtcKeyValueConfig* key_value_config,
|
const WebRtcKeyValueConfig* key_value_config,
|
||||||
|
@ -43,7 +43,7 @@ class CongestionWindowPushbackController {
|
|||||||
int64_t outstanding_bytes_ = 0;
|
int64_t outstanding_bytes_ = 0;
|
||||||
int64_t pacing_bytes_ = 0;
|
int64_t pacing_bytes_ = 0;
|
||||||
const bool add_pacing_;
|
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;
|
double encoding_rate_ratio_ = 1.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,15 +32,6 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
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.
|
// From RTCPSender video report interval.
|
||||||
constexpr TimeDelta kLossUpdateInterval = TimeDelta::Millis<1000>();
|
constexpr TimeDelta kLossUpdateInterval = TimeDelta::Millis<1000>();
|
||||||
|
|
||||||
@ -51,37 +42,6 @@ constexpr TimeDelta kLossUpdateInterval = TimeDelta::Millis<1000>();
|
|||||||
// overshoots from the encoder.
|
// overshoots from the encoder.
|
||||||
const float kDefaultPaceMultiplier = 2.5f;
|
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.
|
// Makes sure that the bitrate and the min, max values are in valid range.
|
||||||
static void ClampBitrates(int64_t* bitrate_bps,
|
static void ClampBitrates(int64_t* bitrate_bps,
|
||||||
int64_t* min_bitrate_bps,
|
int64_t* min_bitrate_bps,
|
||||||
@ -140,9 +100,14 @@ GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
|
|||||||
fall_back_to_probe_rate_(
|
fall_back_to_probe_rate_(
|
||||||
key_value_config_->Lookup("WebRTC-Bwe-ProbeRateFallback")
|
key_value_config_->Lookup("WebRTC-Bwe-ProbeRateFallback")
|
||||||
.find("Enabled") == 0),
|
.find("Enabled") == 0),
|
||||||
|
rate_control_experiments_(
|
||||||
|
RateControlSettings::ParseFromKeyValueConfig(key_value_config_)),
|
||||||
probe_controller_(new ProbeController(key_value_config_)),
|
probe_controller_(new ProbeController(key_value_config_)),
|
||||||
congestion_window_pushback_controller_(
|
congestion_window_pushback_controller_(
|
||||||
MaybeCreateCongestionWindowPushbackController(key_value_config_)),
|
rate_control_experiments_.UseCongestionWindowPushback()
|
||||||
|
? absl::make_unique<CongestionWindowPushbackController>(
|
||||||
|
key_value_config_)
|
||||||
|
: nullptr),
|
||||||
bandwidth_estimation_(
|
bandwidth_estimation_(
|
||||||
absl::make_unique<SendSideBandwidthEstimation>(event_log_)),
|
absl::make_unique<SendSideBandwidthEstimation>(event_log_)),
|
||||||
alr_detector_(absl::make_unique<AlrDetector>()),
|
alr_detector_(absl::make_unique<AlrDetector>()),
|
||||||
@ -170,21 +135,13 @@ GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
|
|||||||
DataRate::Zero())),
|
DataRate::Zero())),
|
||||||
max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
|
max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
|
||||||
DataRate::Zero())),
|
DataRate::Zero())),
|
||||||
max_total_allocated_bitrate_(DataRate::Zero()),
|
max_total_allocated_bitrate_(DataRate::Zero()) {
|
||||||
in_cwnd_experiment_(CwndExperimentEnabled(key_value_config_)),
|
|
||||||
accepted_queue_ms_(kDefaultAcceptedQueueMs) {
|
|
||||||
RTC_DCHECK(config.constraints.at_time.IsFinite());
|
RTC_DCHECK(config.constraints.at_time.IsFinite());
|
||||||
ParseFieldTrial(
|
ParseFieldTrial(
|
||||||
{&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
|
{&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
|
||||||
key_value_config_->Lookup("WebRTC-Bwe-SafeResetOnRouteChange"));
|
key_value_config_->Lookup("WebRTC-Bwe-SafeResetOnRouteChange"));
|
||||||
if (delay_based_bwe_)
|
if (delay_based_bwe_)
|
||||||
delay_based_bwe_->SetMinBitrate(congestion_controller::GetMinBitrate());
|
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() {}
|
GoogCcNetworkController::~GoogCcNetworkController() {}
|
||||||
@ -589,13 +546,15 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
|||||||
|
|
||||||
// No valid RTT could be because send-side BWE isn't used, in which case
|
// No valid RTT could be because send-side BWE isn't used, in which case
|
||||||
// we don't try to limit the outstanding packets.
|
// 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 =
|
int64_t min_feedback_max_rtt_ms =
|
||||||
*std::min_element(feedback_max_rtts_.begin(), feedback_max_rtts_.end());
|
*std::min_element(feedback_max_rtts_.begin(), feedback_max_rtts_.end());
|
||||||
|
|
||||||
const DataSize kMinCwnd = DataSize::bytes(2 * 1500);
|
const DataSize kMinCwnd = DataSize::bytes(2 * 1500);
|
||||||
TimeDelta time_window =
|
TimeDelta time_window = TimeDelta::ms(
|
||||||
TimeDelta::ms(min_feedback_max_rtt_ms + accepted_queue_ms_);
|
min_feedback_max_rtt_ms +
|
||||||
|
rate_control_experiments_.GetCongestionWindowAdditionalTimeMs());
|
||||||
DataSize data_window = last_raw_target_rate_ * time_window;
|
DataSize data_window = last_raw_target_rate_ * time_window;
|
||||||
if (current_data_window_) {
|
if (current_data_window_) {
|
||||||
data_window =
|
data_window =
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "modules/congestion_controller/goog_cc/probe_controller.h"
|
#include "modules/congestion_controller/goog_cc/probe_controller.h"
|
||||||
#include "rtc_base/constructor_magic.h"
|
#include "rtc_base/constructor_magic.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
|
#include "rtc_base/experiments/rate_control_settings.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ class GoogCcNetworkController : public NetworkControllerInterface {
|
|||||||
FieldTrialFlag safe_reset_acknowledged_rate_;
|
FieldTrialFlag safe_reset_acknowledged_rate_;
|
||||||
const bool use_stable_bandwidth_estimate_;
|
const bool use_stable_bandwidth_estimate_;
|
||||||
const bool fall_back_to_probe_rate_;
|
const bool fall_back_to_probe_rate_;
|
||||||
|
const RateControlSettings rate_control_experiments_;
|
||||||
|
|
||||||
const std::unique_ptr<ProbeController> probe_controller_;
|
const std::unique_ptr<ProbeController> probe_controller_;
|
||||||
const std::unique_ptr<CongestionWindowPushbackController>
|
const std::unique_ptr<CongestionWindowPushbackController>
|
||||||
@ -113,8 +115,6 @@ class GoogCcNetworkController : public NetworkControllerInterface {
|
|||||||
DataRate max_padding_rate_;
|
DataRate max_padding_rate_;
|
||||||
DataRate max_total_allocated_bitrate_;
|
DataRate max_total_allocated_bitrate_;
|
||||||
|
|
||||||
bool in_cwnd_experiment_;
|
|
||||||
int64_t accepted_queue_ms_;
|
|
||||||
bool previously_in_alr = false;
|
bool previously_in_alr = false;
|
||||||
|
|
||||||
absl::optional<DataSize> current_data_window_;
|
absl::optional<DataSize> current_data_window_;
|
||||||
|
@ -168,8 +168,7 @@ class DEPRECATED_SendSideCongestionController
|
|||||||
std::unique_ptr<ProbeBitrateEstimator> probe_bitrate_estimator_
|
std::unique_ptr<ProbeBitrateEstimator> probe_bitrate_estimator_
|
||||||
RTC_GUARDED_BY(bwe_lock_);
|
RTC_GUARDED_BY(bwe_lock_);
|
||||||
std::unique_ptr<DelayBasedBwe> delay_based_bwe_ RTC_GUARDED_BY(bwe_lock_);
|
std::unique_ptr<DelayBasedBwe> delay_based_bwe_ RTC_GUARDED_BY(bwe_lock_);
|
||||||
bool in_cwnd_experiment_;
|
absl::optional<int64_t> cwnd_experiment_parameter_;
|
||||||
int64_t accepted_queue_ms_;
|
|
||||||
bool was_in_alr_;
|
bool was_in_alr_;
|
||||||
const bool send_side_bwe_with_overhead_;
|
const bool send_side_bwe_with_overhead_;
|
||||||
size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(bwe_lock_);
|
size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(bwe_lock_);
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "modules/congestion_controller/goog_cc/probe_controller.h"
|
#include "modules/congestion_controller/goog_cc/probe_controller.h"
|
||||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
#include "rtc_base/experiments/rate_control_settings.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/network/sent_packet.h"
|
#include "rtc_base/network/sent_packet.h"
|
||||||
#include "rtc_base/rate_limiter.h"
|
#include "rtc_base/rate_limiter.h"
|
||||||
@ -36,48 +37,7 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const char kCwndExperiment[] = "WebRTC-CwndExperiment";
|
|
||||||
const char kPacerPushbackExperiment[] = "WebRTC-PacerPushbackExperiment";
|
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;
|
static const int64_t kRetransmitWindowSizeMs = 500;
|
||||||
|
|
||||||
// Makes sure that the bitrate and the min, max values are in valid range.
|
// 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()),
|
min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
|
||||||
probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log_)),
|
probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log_)),
|
||||||
delay_based_bwe_(new DelayBasedBwe(key_value_config_, 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),
|
was_in_alr_(false),
|
||||||
send_side_bwe_with_overhead_(
|
send_side_bwe_with_overhead_(
|
||||||
key_value_config_->Lookup("WebRTC-SendSideBwe-WithOverhead")
|
key_value_config_->Lookup("WebRTC-SendSideBwe-WithOverhead")
|
||||||
.find("Enabled") == 0),
|
.find("Enabled") == 0),
|
||||||
transport_overhead_bytes_per_packet_(0),
|
transport_overhead_bytes_per_packet_(0),
|
||||||
pacer_pushback_experiment_(
|
pacer_pushback_experiment_(
|
||||||
IsPacerPushbackExperimentEnabled(key_value_config_)),
|
IsPacerPushbackExperimentEnabled(key_value_config_)) {
|
||||||
congestion_window_pushback_controller_(
|
RateControlSettings experiment_params =
|
||||||
MaybeCreateCongestionWindowPushbackController(key_value_config_)) {
|
RateControlSettings::ParseFromKeyValueConfig(key_value_config);
|
||||||
delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps_));
|
if (experiment_params.UseCongestionWindow()) {
|
||||||
if (in_cwnd_experiment_ &&
|
cwnd_experiment_parameter_ =
|
||||||
!ReadCwndExperimentParameter(key_value_config_, &accepted_queue_ms_)) {
|
experiment_params.GetCongestionWindowAdditionalTimeMs();
|
||||||
RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
|
|
||||||
"from field trial string. Experiment disabled.";
|
|
||||||
in_cwnd_experiment_ = false;
|
|
||||||
}
|
}
|
||||||
|
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::
|
DEPRECATED_SendSideCongestionController::
|
||||||
@ -185,8 +146,7 @@ void DEPRECATED_SendSideCongestionController::EnableCongestionWindowPushback(
|
|||||||
RTC_CHECK_GE(min_pushback_target_bitrate_bps, 0)
|
RTC_CHECK_GE(min_pushback_target_bitrate_bps, 0)
|
||||||
<< "Min pushback target bitrate must be greater than or equal to 0.";
|
<< "Min pushback target bitrate must be greater than or equal to 0.";
|
||||||
|
|
||||||
in_cwnd_experiment_ = true;
|
cwnd_experiment_parameter_ = accepted_queue_ms;
|
||||||
accepted_queue_ms_ = accepted_queue_ms;
|
|
||||||
congestion_window_pushback_controller_ =
|
congestion_window_pushback_controller_ =
|
||||||
absl::make_unique<CongestionWindowPushbackController>(
|
absl::make_unique<CongestionWindowPushbackController>(
|
||||||
key_value_config_, min_pushback_target_bitrate_bps);
|
key_value_config_, min_pushback_target_bitrate_bps);
|
||||||
@ -364,7 +324,7 @@ void DEPRECATED_SendSideCongestionController::OnSentPacket(
|
|||||||
return;
|
return;
|
||||||
transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
|
transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
|
||||||
sent_packet.send_time_ms);
|
sent_packet.send_time_ms);
|
||||||
if (in_cwnd_experiment_)
|
if (cwnd_experiment_parameter_)
|
||||||
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
|
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,14 +432,14 @@ void DEPRECATED_SendSideCongestionController::OnTransportFeedback(
|
|||||||
rtc::CritScope cs(&probe_lock_);
|
rtc::CritScope cs(&probe_lock_);
|
||||||
SendProbes(probe_controller_->RequestProbe(clock_->TimeInMilliseconds()));
|
SendProbes(probe_controller_->RequestProbe(clock_->TimeInMilliseconds()));
|
||||||
}
|
}
|
||||||
if (in_cwnd_experiment_) {
|
if (cwnd_experiment_parameter_) {
|
||||||
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
|
LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEPRECATED_SendSideCongestionController::LimitOutstandingBytes(
|
void DEPRECATED_SendSideCongestionController::LimitOutstandingBytes(
|
||||||
size_t num_outstanding_bytes) {
|
size_t num_outstanding_bytes) {
|
||||||
RTC_DCHECK(in_cwnd_experiment_);
|
RTC_DCHECK(cwnd_experiment_parameter_);
|
||||||
rtc::CritScope lock(&network_state_lock_);
|
rtc::CritScope lock(&network_state_lock_);
|
||||||
absl::optional<int64_t> min_rtt_ms =
|
absl::optional<int64_t> min_rtt_ms =
|
||||||
transport_feedback_adapter_.GetMinFeedbackLoopRtt();
|
transport_feedback_adapter_.GetMinFeedbackLoopRtt();
|
||||||
@ -489,7 +449,7 @@ void DEPRECATED_SendSideCongestionController::LimitOutstandingBytes(
|
|||||||
return;
|
return;
|
||||||
const size_t kMinCwndBytes = 2 * 1500;
|
const size_t kMinCwndBytes = 2 * 1500;
|
||||||
size_t max_outstanding_bytes =
|
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,
|
last_reported_bitrate_bps_ / 1000 / 8,
|
||||||
kMinCwndBytes);
|
kMinCwndBytes);
|
||||||
if (congestion_window_pushback_controller_) {
|
if (congestion_window_pushback_controller_) {
|
||||||
|
@ -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) {
|
if (rtc_include_tests) {
|
||||||
rtc_source_set("experiments_unittests") {
|
rtc_source_set("experiments_unittests") {
|
||||||
testonly = true
|
testonly = true
|
||||||
|
@ -6,3 +6,5 @@ per-file jitter_upper_bound_experiment*=sprang@webrtc.org
|
|||||||
per-file normalize_simulcast_size_experiment*=asapersson@webrtc.org
|
per-file normalize_simulcast_size_experiment*=asapersson@webrtc.org
|
||||||
per-file quality_scaling_experiment*=asapersson@webrtc.org
|
per-file quality_scaling_experiment*=asapersson@webrtc.org
|
||||||
per-file rtt_mult_experiment*=mhoro@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
|
||||||
|
114
rtc_base/experiments/rate_control_settings.cc
Normal file
114
rtc_base/experiments/rate_control_settings.cc
Normal 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
|
47
rtc_base/experiments/rate_control_settings.h
Normal file
47
rtc_base/experiments/rate_control_settings.h
Normal 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_
|
Reference in New Issue
Block a user