webrtc/rtc_base/experiments/rate_control_settings.cc
Erik Språng 3d11e2f81c Allow encoder target bitrate to reach media rate if there is headroom.
This CL adds a field trial that enables the EncoderBitrateAdjuster to
allow higher target bitrate if we are not network constrained. We still
don't allow the bitrate to go higher than the average target media rate
though.

Bug: webrtc:10155
Change-Id: Id5995070aa0cbe84b9305a422279141b38664bb1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132717
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27627}
2019-04-15 15:11:39 +00:00

197 lines
6.7 KiB
C++

/*
* 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/experiments/field_trial_parser.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
namespace {
const int kDefaultAcceptedQueueMs = 250;
const int kDefaultMinPushbackTargetBitrateBps = 30000;
const char kVp8TrustedRateControllerFieldTrialName[] =
"WebRTC-LibvpxVp8TrustedRateController";
const char kVp9TrustedRateControllerFieldTrialName[] =
"WebRTC-LibvpxVp9TrustedRateController";
const char* kVideoHysteresisFieldTrialname =
"WebRTC-SimulcastUpswitchHysteresisPercent";
const double kDefaultVideoHysteresisFactor = 1.0;
const char* kScreenshareHysteresisFieldTrialname =
"WebRTC-SimulcastScreenshareUpswitchHysteresisPercent";
// Default to 35% hysteresis for simulcast screenshare.
const double kDefaultScreenshareHysteresisFactor = 1.35;
bool IsEnabled(const WebRtcKeyValueConfig* const key_value_config,
absl::string_view key) {
return key_value_config->Lookup(key).find("Enabled") == 0;
}
double ParseHysteresisFactor(const WebRtcKeyValueConfig* const key_value_config,
absl::string_view key,
double default_value) {
std::string group_name = key_value_config->Lookup(key);
int percent = 0;
if (!group_name.empty() && sscanf(group_name.c_str(), "%d", &percent) == 1 &&
percent >= 0) {
return 1.0 + (percent / 100.0);
}
return default_value;
}
} // namespace
RateControlSettings::RateControlSettings(
const WebRtcKeyValueConfig* const key_value_config)
: congestion_window_("QueueSize"),
congestion_window_pushback_("MinBitrate"),
pacing_factor_("pacing_factor"),
alr_probing_("alr_probing", false),
trust_vp8_(
"trust_vp8",
IsEnabled(key_value_config, kVp8TrustedRateControllerFieldTrialName)),
trust_vp9_(
"trust_vp9",
IsEnabled(key_value_config, kVp9TrustedRateControllerFieldTrialName)),
video_hysteresis_("video_hysteresis",
ParseHysteresisFactor(key_value_config,
kVideoHysteresisFieldTrialname,
kDefaultVideoHysteresisFactor)),
screenshare_hysteresis_(
"screenshare_hysteresis",
ParseHysteresisFactor(key_value_config,
kScreenshareHysteresisFieldTrialname,
kDefaultScreenshareHysteresisFactor)),
probe_max_allocation_("probe_max_allocation", true),
bitrate_adjuster_("bitrate_adjuster", false),
adjuster_use_headroom_("adjuster_use_headroom", false),
vp8_s0_boost_("vp8_s0_boost", true),
vp8_dynamic_rate_("vp8_dynamic_rate", false),
vp9_dynamic_rate_("vp9_dynamic_rate", false) {
ParseFieldTrial({&congestion_window_, &congestion_window_pushback_},
key_value_config->Lookup("WebRTC-CongestionWindow"));
ParseFieldTrial(
{&pacing_factor_, &alr_probing_, &trust_vp8_, &trust_vp9_,
&video_hysteresis_, &screenshare_hysteresis_, &probe_max_allocation_,
&bitrate_adjuster_, &adjuster_use_headroom_, &vp8_s0_boost_,
&vp8_dynamic_rate_, &vp9_dynamic_rate_},
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 static_cast<bool>(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);
}
absl::optional<double> RateControlSettings::GetPacingFactor() const {
return pacing_factor_.GetOptional();
}
bool RateControlSettings::UseAlrProbing() const {
return alr_probing_.Get();
}
bool RateControlSettings::LibvpxVp8TrustedRateController() const {
return trust_vp8_.Get();
}
bool RateControlSettings::Vp8BoostBaseLayerQuality() const {
return vp8_s0_boost_.Get();
}
bool RateControlSettings::Vp8DynamicRateSettings() const {
return vp8_dynamic_rate_.Get();
}
bool RateControlSettings::LibvpxVp9TrustedRateController() const {
return trust_vp9_.Get();
}
bool RateControlSettings::Vp9DynamicRateSettings() const {
return vp9_dynamic_rate_.Get();
}
double RateControlSettings::GetSimulcastHysteresisFactor(
VideoCodecMode mode) const {
if (mode == VideoCodecMode::kScreensharing) {
return GetSimulcastScreenshareHysteresisFactor();
}
return GetSimulcastVideoHysteresisFactor();
}
double RateControlSettings::GetSimulcastHysteresisFactor(
VideoEncoderConfig::ContentType content_type) const {
if (content_type == VideoEncoderConfig::ContentType::kScreen) {
return GetSimulcastScreenshareHysteresisFactor();
}
return GetSimulcastVideoHysteresisFactor();
}
double RateControlSettings::GetSimulcastVideoHysteresisFactor() const {
return video_hysteresis_.Get();
}
double RateControlSettings::GetSimulcastScreenshareHysteresisFactor() const {
return screenshare_hysteresis_.Get();
}
bool RateControlSettings::TriggerProbeOnMaxAllocatedBitrateChange() const {
return probe_max_allocation_.Get();
}
bool RateControlSettings::UseEncoderBitrateAdjuster() const {
return bitrate_adjuster_.Get();
}
bool RateControlSettings::BitrateAdjusterCanUseNetworkHeadroom() const {
return adjuster_use_headroom_.Get();
}
} // namespace webrtc