webrtc/rtc_base/experiments/rate_control_settings.cc
Ying Wang 9b881abea9 Enable congestion window pushback to reduce bitrate by only drop video frames.
With current congestion window pushback, when congestion window is filling up, it will reduce bitrate directly and encoder may reduce encode quality, resolution, or framerate to adapt to the allocated bitrate, the behavior is depending on the degradation preference.
This change enable congestion window to only drop frames to reduce bitrate (when needed) instead of reduce general bitrate allocation.

Bug: webrtc:11334
Change-Id: I9cf5c20a0858c4d07d006942abe72aa5e1f7cb38
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168059
Commit-Queue: Ying Wang <yinwa@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30483}
2020-02-07 14:14:47 +00:00

237 lines
8.2 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/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 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 key_value_config->Lookup(key).find("Enabled") == 0;
}
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, //
"vp8_dynamic_rate", &vp8_dynamic_rate, //
"vp9_dynamic_rate", &vp9_dynamic_rate);
}
RateControlSettings::RateControlSettings(
const WebRtcKeyValueConfig* const key_value_config)
: congestion_window_config_(CongestionWindowConfig::Parse(
key_value_config->Lookup(CongestionWindowConfig::kKey))) {
video_config_.trust_vp8 =
IsEnabled(key_value_config, kVp8TrustedRateControllerFieldTrialName);
video_config_.trust_vp9 =
IsEnabled(key_value_config, kVp9TrustedRateControllerFieldTrialName);
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::Vp8DynamicRateSettings() const {
return video_config_.vp8_dynamic_rate;
}
bool RateControlSettings::LibvpxVp9TrustedRateController() const {
return video_config_.trust_vp9;
}
bool RateControlSettings::Vp9DynamicRateSettings() const {
return video_config_.vp9_dynamic_rate;
}
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