webrtc/rtc_base/experiments/rate_control_settings.cc
Erik Språng 9d69cbeabf Changes default pacing factor to 1.1x
This changes the default behavior to use pacing factor of 1.1x instead
of 2.5x, it also sets libvpx rate controler as trusted, turns on the
encoder pushback mechanism and sets spatial hysteresis to 1.2.
The unused "dynamic rate" settings in libvpx is removed.

The new settings matches what has been used in chromium since 2019.
If needed, the legacy behavior can be enabled using the field trial
WebRTC-VideoRateControl.

Bug: webrtc:10155
Change-Id: I8186b491aa5bef61e8f568e96c980ca68f0c208f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/186661
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32477}
2020-10-23 13:43:32 +00:00

219 lines
7.5 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 "absl/strings/match.h"
#include "api/transport/field_trial_based_config.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 kUseBaseHeavyVp8Tl3RateAllocationFieldTrialName[] =
"WebRTC-UseBaseHeavyVP8TL3RateAllocation";
const char* kVideoHysteresisFieldTrialname =
"WebRTC-SimulcastUpswitchHysteresisPercent";
const char* kScreenshareHysteresisFieldTrialname =
"WebRTC-SimulcastScreenshareUpswitchHysteresisPercent";
bool IsEnabled(const WebRtcKeyValueConfig* const key_value_config,
absl::string_view key) {
return absl::StartsWith(key_value_config->Lookup(key), "Enabled");
}
void ParseHysteresisFactor(const WebRtcKeyValueConfig* const key_value_config,
absl::string_view key,
double* output_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) {
*output_value = 1.0 + (percent / 100.0);
}
}
} // namespace
constexpr char CongestionWindowConfig::kKey[];
std::unique_ptr<StructParametersParser> CongestionWindowConfig::Parser() {
return StructParametersParser::Create("QueueSize", &queue_size_ms, //
"MinBitrate", &min_bitrate_bps,
"InitWin", &initial_data_window,
"DropFrame", &drop_frame_only);
}
// static
CongestionWindowConfig CongestionWindowConfig::Parse(absl::string_view config) {
CongestionWindowConfig res;
res.Parser()->Parse(config);
return res;
}
constexpr char VideoRateControlConfig::kKey[];
std::unique_ptr<StructParametersParser> VideoRateControlConfig::Parser() {
// The empty comments ensures that each pair is on a separate line.
return StructParametersParser::Create(
"pacing_factor", &pacing_factor, //
"alr_probing", &alr_probing, //
"vp8_qp_max", &vp8_qp_max, //
"vp8_min_pixels", &vp8_min_pixels, //
"trust_vp8", &trust_vp8, //
"trust_vp9", &trust_vp9, //
"video_hysteresis", &video_hysteresis, //
"screenshare_hysteresis", &screenshare_hysteresis, //
"probe_max_allocation", &probe_max_allocation, //
"bitrate_adjuster", &bitrate_adjuster, //
"adjuster_use_headroom", &adjuster_use_headroom, //
"vp8_s0_boost", &vp8_s0_boost, //
"vp8_base_heavy_tl3_alloc", &vp8_base_heavy_tl3_alloc);
}
RateControlSettings::RateControlSettings(
const WebRtcKeyValueConfig* const key_value_config)
: congestion_window_config_(CongestionWindowConfig::Parse(
key_value_config->Lookup(CongestionWindowConfig::kKey))) {
video_config_.vp8_base_heavy_tl3_alloc = IsEnabled(
key_value_config, kUseBaseHeavyVp8Tl3RateAllocationFieldTrialName);
ParseHysteresisFactor(key_value_config, kVideoHysteresisFieldTrialname,
&video_config_.video_hysteresis);
ParseHysteresisFactor(key_value_config, kScreenshareHysteresisFieldTrialname,
&video_config_.screenshare_hysteresis);
video_config_.Parser()->Parse(
key_value_config->Lookup(VideoRateControlConfig::kKey));
}
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_config_.queue_size_ms);
}
int64_t RateControlSettings::GetCongestionWindowAdditionalTimeMs() const {
return congestion_window_config_.queue_size_ms.value_or(
kDefaultAcceptedQueueMs);
}
bool RateControlSettings::UseCongestionWindowPushback() const {
return congestion_window_config_.queue_size_ms &&
congestion_window_config_.min_bitrate_bps;
}
bool RateControlSettings::UseCongestionWindowDropFrameOnly() const {
return congestion_window_config_.drop_frame_only;
}
uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps()
const {
return congestion_window_config_.min_bitrate_bps.value_or(
kDefaultMinPushbackTargetBitrateBps);
}
absl::optional<DataSize>
RateControlSettings::CongestionWindowInitialDataWindow() const {
return congestion_window_config_.initial_data_window;
}
absl::optional<double> RateControlSettings::GetPacingFactor() const {
return video_config_.pacing_factor;
}
bool RateControlSettings::UseAlrProbing() const {
return video_config_.alr_probing;
}
absl::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
if (video_config_.vp8_qp_max &&
(*video_config_.vp8_qp_max < 0 || *video_config_.vp8_qp_max > 63)) {
RTC_LOG(LS_WARNING) << "Unsupported vp8_qp_max_ value, ignored.";
return absl::nullopt;
}
return video_config_.vp8_qp_max;
}
absl::optional<int> RateControlSettings::LibvpxVp8MinPixels() const {
if (video_config_.vp8_min_pixels && *video_config_.vp8_min_pixels < 1) {
return absl::nullopt;
}
return video_config_.vp8_min_pixels;
}
bool RateControlSettings::LibvpxVp8TrustedRateController() const {
return video_config_.trust_vp8;
}
bool RateControlSettings::Vp8BoostBaseLayerQuality() const {
return video_config_.vp8_s0_boost;
}
bool RateControlSettings::LibvpxVp9TrustedRateController() const {
return video_config_.trust_vp9;
}
double RateControlSettings::GetSimulcastHysteresisFactor(
VideoCodecMode mode) const {
if (mode == VideoCodecMode::kScreensharing) {
return video_config_.screenshare_hysteresis;
}
return video_config_.video_hysteresis;
}
double RateControlSettings::GetSimulcastHysteresisFactor(
VideoEncoderConfig::ContentType content_type) const {
if (content_type == VideoEncoderConfig::ContentType::kScreen) {
return video_config_.screenshare_hysteresis;
}
return video_config_.video_hysteresis;
}
bool RateControlSettings::Vp8BaseHeavyTl3RateAllocation() const {
return video_config_.vp8_base_heavy_tl3_alloc;
}
bool RateControlSettings::TriggerProbeOnMaxAllocatedBitrateChange() const {
return video_config_.probe_max_allocation;
}
bool RateControlSettings::UseEncoderBitrateAdjuster() const {
return video_config_.bitrate_adjuster;
}
bool RateControlSettings::BitrateAdjusterCanUseNetworkHeadroom() const {
return video_config_.adjuster_use_headroom;
}
} // namespace webrtc