blob: 2134dad3f26d71afd646f3b1af2dba8a5700817d [file] [log] [blame]
/*
* Copyright (c) 2016 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 "modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h"
#include <string>
#include <utility>
#include "rtc_base/checks.h"
namespace webrtc {
FecControllerPlrBased::Config::Config(
bool initial_fec_enabled,
const ThresholdCurve& fec_enabling_threshold,
const ThresholdCurve& fec_disabling_threshold,
int time_constant_ms)
: initial_fec_enabled(initial_fec_enabled),
fec_enabling_threshold(fec_enabling_threshold),
fec_disabling_threshold(fec_disabling_threshold),
time_constant_ms(time_constant_ms) {}
FecControllerPlrBased::FecControllerPlrBased(
const Config& config,
std::unique_ptr<SmoothingFilter> smoothing_filter)
: config_(config),
fec_enabled_(config.initial_fec_enabled),
packet_loss_smoother_(std::move(smoothing_filter)) {
RTC_DCHECK(config_.fec_disabling_threshold <= config_.fec_enabling_threshold);
}
FecControllerPlrBased::FecControllerPlrBased(const Config& config)
: FecControllerPlrBased(
config,
std::make_unique<SmoothingFilterImpl>(config.time_constant_ms)) {}
FecControllerPlrBased::~FecControllerPlrBased() = default;
void FecControllerPlrBased::UpdateNetworkMetrics(
const NetworkMetrics& network_metrics) {
if (network_metrics.uplink_bandwidth_bps)
uplink_bandwidth_bps_ = network_metrics.uplink_bandwidth_bps;
if (network_metrics.uplink_packet_loss_fraction) {
packet_loss_smoother_->AddSample(
*network_metrics.uplink_packet_loss_fraction);
}
}
void FecControllerPlrBased::MakeDecision(AudioEncoderRuntimeConfig* config) {
RTC_DCHECK(!config->enable_fec);
RTC_DCHECK(!config->uplink_packet_loss_fraction);
const auto& packet_loss = packet_loss_smoother_->GetAverage();
fec_enabled_ = fec_enabled_ ? !FecDisablingDecision(packet_loss)
: FecEnablingDecision(packet_loss);
config->enable_fec = fec_enabled_;
config->uplink_packet_loss_fraction = packet_loss ? *packet_loss : 0.0;
}
bool FecControllerPlrBased::FecEnablingDecision(
const absl::optional<float>& packet_loss) const {
if (!uplink_bandwidth_bps_ || !packet_loss) {
return false;
} else {
// Enable when above the curve or exactly on it.
return !config_.fec_enabling_threshold.IsBelowCurve(
{static_cast<float>(*uplink_bandwidth_bps_), *packet_loss});
}
}
bool FecControllerPlrBased::FecDisablingDecision(
const absl::optional<float>& packet_loss) const {
if (!uplink_bandwidth_bps_ || !packet_loss) {
return false;
} else {
// Disable when below the curve.
return config_.fec_disabling_threshold.IsBelowCurve(
{static_cast<float>(*uplink_bandwidth_bps_), *packet_loss});
}
}
} // namespace webrtc