Removes new delay based rate controller.

Will focus on delivering model based controller instead.

Bug: webrtc:9718
Change-Id: I5df82424469c577f3c170758e0db64e3e1aa7705
Reviewed-on: https://webrtc-review.googlesource.com/c/120607
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26478}
This commit is contained in:
Sebastian Jansson 2019-01-30 18:26:32 +01:00 committed by Commit Bot
parent 8b087f36d2
commit 2d79dccfb1
8 changed files with 23 additions and 587 deletions

View File

@ -26,7 +26,6 @@ rtc_static_library("goog_cc") {
deps = [
":alr_detector",
":delay_based_bwe",
":delay_based_rate_controller",
":estimators",
":probe_controller",
":pushback_controller",
@ -134,30 +133,6 @@ rtc_source_set("estimators") {
]
}
rtc_source_set("delay_based_rate_controller") {
configs += [ ":bwe_test_logging" ]
sources = [
"delay_based_rate_controller.cc",
"delay_based_rate_controller.h",
"packet_grouping.cc",
"packet_grouping.h",
]
deps = [
":estimators",
":link_capacity_estimator",
"../../../api/transport:network_control",
"../../../api/transport:webrtc_key_value_config",
"../../../logging:rtc_event_bwe",
"../../../logging:rtc_event_log_api",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/experiments:field_trial_parser",
"../../../system_wrappers:metrics",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_source_set("delay_based_bwe") {
configs += [ ":bwe_test_logging" ]
sources = [

View File

@ -1,218 +0,0 @@
/*
* Copyright 2018 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/congestion_controller/goog_cc/delay_based_rate_controller.h"
#include <algorithm>
#include <cmath>
#include "absl/memory/memory.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
namespace webrtc {
namespace {
// Parameters for linear least squares fit of regression line to noisy data.
constexpr size_t kDefaultTrendlineWindowSize = 20;
constexpr double kDefaultTrendlineSmoothingCoeff = 0.9;
constexpr double kDefaultTrendlineThresholdGain = 4.0;
} // namespace
DelayBasedRateControllerConfig::DelayBasedRateControllerConfig(
const WebRtcKeyValueConfig* key_value_config)
: enabled("Enabled"),
no_ack_backoff_fraction("no_ack_frac", 0.8),
no_ack_backoff_interval("no_ack_int", TimeDelta::ms(1000)),
ack_backoff_fraction("ack_dec", 0.90),
probe_backoff_fraction("probe_dec", 0.85),
initial_increase_rate("probe_inc", 0.03),
increase_rate("inc", 0.01),
first_period_increase_rate("min_step", DataRate::kbps(5)),
stop_increase_after("stop", TimeDelta::ms(500)),
min_increase_interval("int", TimeDelta::ms(100)),
linear_increase_threshold("cut", DataRate::kbps(300)),
reference_duration_offset("dur_offs", TimeDelta::ms(100)) {
ParseFieldTrial(
{&enabled, &no_ack_backoff_fraction, &no_ack_backoff_interval,
&ack_backoff_fraction, &probe_backoff_fraction, &initial_increase_rate,
&increase_rate, &stop_increase_after, &min_increase_interval,
&first_period_increase_rate, &linear_increase_threshold,
&reference_duration_offset},
key_value_config->Lookup("WebRTC-Bwe-DelayBasedRateController"));
}
DelayBasedRateControllerConfig::~DelayBasedRateControllerConfig() = default;
DelayBasedRateController::DelayBasedRateController(
const WebRtcKeyValueConfig* key_value_config,
RtcEventLog* event_log,
TargetRateConstraints constraints)
: conf_(key_value_config),
event_log_(event_log),
overuse_detector_(new TrendlineEstimator(kDefaultTrendlineWindowSize,
kDefaultTrendlineSmoothingCoeff,
kDefaultTrendlineThresholdGain)),
target_rate_(constraints.starting_rate.value()) {
UpdateConstraints(constraints);
MaybeLog();
}
DelayBasedRateController::~DelayBasedRateController() = default;
void DelayBasedRateController::OnRouteChange() {
packet_grouper_.Reset();
link_capacity_.Reset();
overuse_detector_.reset(new TrendlineEstimator(
kDefaultTrendlineWindowSize, kDefaultTrendlineSmoothingCoeff,
kDefaultTrendlineThresholdGain));
logged_state_.reset();
}
void DelayBasedRateController::UpdateConstraints(TargetRateConstraints msg) {
if (msg.min_data_rate)
min_rate_ = *msg.min_data_rate;
if (msg.max_data_rate)
max_rate_ = *msg.max_data_rate;
if (msg.starting_rate)
target_rate_ = *msg.starting_rate;
target_rate_.Clamp(min_rate_, max_rate_);
}
void DelayBasedRateController::SetAcknowledgedRate(DataRate acknowledged_rate) {
acknowledged_rate_ = acknowledged_rate;
if (acknowledged_rate > link_capacity_.UpperBound())
link_capacity_.Reset();
}
void DelayBasedRateController::OnTransportPacketsFeedback(
TransportPacketsFeedback msg,
absl::optional<DataRate> probe_bitrate) {
auto packets = msg.ReceivedWithSendInfo();
last_rtt_ = msg.feedback_time - packets.back().sent_packet.send_time;
first_unacked_send_ = msg.first_unacked_send_time;
for (auto& packet : packets) {
packet_grouper_.AddPacketInfo(packet, msg.feedback_time);
}
for (auto& delta : packet_grouper_.PopDeltas()) {
overuse_detector_->Update(delta.receive.ms<double>(),
delta.send.ms<double>(), delta.receive_time.ms());
}
BandwidthUsage usage = overuse_detector_->State();
Timestamp at_time = msg.feedback_time;
last_feedback_update_ = at_time;
if (probe_bitrate) {
if (!acknowledged_rate_)
acknowledged_rate_ = *probe_bitrate;
target_rate_ = *probe_bitrate * conf_.probe_backoff_fraction;
increase_reference_ = target_rate_;
link_capacity_.OnProbeRate(*probe_bitrate);
}
if (usage == BandwidthUsage::kBwNormal) {
if (!increasing_state_) {
increasing_state_ = true;
// Offset the next increase time by one RTT to avoid increasing too soon
// after overuse.
last_increase_update_ = at_time + last_rtt_;
accumulated_duration_ = 0;
increase_reference_ = target_rate_;
}
} else if (usage == BandwidthUsage::kBwOverusing && !probe_bitrate) {
increasing_state_ = false;
if (!acknowledged_rate_ &&
at_time - last_no_ack_backoff_ >= conf_.no_ack_backoff_interval) {
// Until we recieve out first acknowledged rate, we back of from the
// target rate, but pace the backoffs to avoid dropping the rate too fast.
last_no_ack_backoff_ = at_time;
target_rate_ = target_rate_ * conf_.no_ack_backoff_fraction;
} else if (acknowledged_rate_) {
if (acknowledged_rate_ < link_capacity_.LowerBound())
link_capacity_.Reset();
link_capacity_.OnOveruseDetected(*acknowledged_rate_);
target_rate_ = acknowledged_rate_.value() * conf_.ack_backoff_fraction;
}
target_rate_.Clamp(min_rate_, max_rate_);
}
MaybeLog();
}
void DelayBasedRateController::OnFeedbackUpdate(
BandwidthUsage usage,
absl::optional<DataRate> probe_bitrate,
Timestamp at_time) {}
void DelayBasedRateController::OnTimeUpdate(Timestamp at_time) {
if (!increasing_state_ ||
at_time < last_increase_update_ + conf_.min_increase_interval)
return;
TimeDelta time_span = at_time - last_increase_update_;
last_increase_update_ = at_time;
if (at_time > last_feedback_update_ + conf_.stop_increase_after)
return;
TimeDelta rtt_lower_bound =
std::max(last_rtt_, at_time - first_unacked_send_);
TimeDelta reference_span = rtt_lower_bound + conf_.reference_duration_offset;
accumulated_duration_ += time_span / reference_span;
if (link_capacity_.has_estimate() &&
increase_reference_ > conf_.linear_increase_threshold) {
DataRate linear_increase_rate =
conf_.increase_rate.Get() * conf_.linear_increase_threshold.Get();
DataRate increase_amount = accumulated_duration_ * linear_increase_rate;
target_rate_ = increase_reference_ + increase_amount;
} else {
double increase_rate = link_capacity_.has_estimate()
? conf_.initial_increase_rate
: conf_.increase_rate;
double increase_factor = 1 + increase_rate;
double increase_amount = pow(increase_factor, accumulated_duration_);
target_rate_ = increase_reference_ * increase_amount;
}
target_rate_.Clamp(min_rate_, max_rate_);
MaybeLog();
}
void DelayBasedRateController::OnRemoteBitrateControl(RemoteBitrateReport msg) {
target_rate_ = msg.bandwidth;
increasing_state_ = false;
}
TimeDelta DelayBasedRateController::GetExpectedBandwidthPeriod() const {
double expected_overuse = 0.05;
double bandwidth_cycle_max_min_ratio =
1 / conf_.ack_backoff_fraction + expected_overuse;
TimeDelta reference_span = last_rtt_ + conf_.reference_duration_offset;
TimeDelta period = reference_span * log(bandwidth_cycle_max_min_ratio) /
log(1 + conf_.increase_rate);
return period.Clamped(TimeDelta::seconds(1), TimeDelta::seconds(20));
}
DataRate DelayBasedRateController::target_rate() const {
return target_rate_;
}
bool DelayBasedRateController::in_underuse() const {
return overuse_detector_->State() == BandwidthUsage::kBwUnderusing;
}
void DelayBasedRateController::MaybeLog() {
if (event_log_ && (logged_target_ != target_rate_ ||
logged_state_ != overuse_detector_->State())) {
event_log_->Log(absl::make_unique<RtcEventBweUpdateDelayBased>(
target_rate_.bps(), overuse_detector_->State()));
logged_state_ = overuse_detector_->State();
logged_target_ = target_rate_;
}
}
} // namespace webrtc

View File

@ -1,100 +0,0 @@
/*
* Copyright 2018 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 MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_BASED_RATE_CONTROLLER_H_
#define MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_BASED_RATE_CONTROLLER_H_
#include <memory>
#include "absl/types/optional.h"
#include "api/transport/network_types.h"
#include "api/transport/webrtc_key_value_config.h"
#include "logging/rtc_event_log/rtc_event_log.h"
#include "modules/congestion_controller/goog_cc/link_capacity_estimator.h"
#include "modules/congestion_controller/goog_cc/packet_grouping.h"
#include "modules/congestion_controller/goog_cc/trendline_estimator.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/experiments/field_trial_units.h"
namespace webrtc {
struct DelayBasedRateControllerConfig {
FieldTrialFlag enabled;
FieldTrialParameter<double> no_ack_backoff_fraction;
FieldTrialParameter<TimeDelta> no_ack_backoff_interval;
FieldTrialParameter<double> ack_backoff_fraction;
FieldTrialParameter<double> probe_backoff_fraction;
FieldTrialParameter<double> initial_increase_rate;
FieldTrialParameter<double> increase_rate;
FieldTrialParameter<DataRate> first_period_increase_rate;
FieldTrialParameter<TimeDelta> stop_increase_after;
FieldTrialParameter<TimeDelta> min_increase_interval;
FieldTrialParameter<DataRate> linear_increase_threshold;
FieldTrialParameter<TimeDelta> reference_duration_offset;
explicit DelayBasedRateControllerConfig(
const WebRtcKeyValueConfig* key_value_config);
~DelayBasedRateControllerConfig();
};
// Rate controller for GoogCC, increases the target rate based on a
// fixed increase interval and an RTT dependent increase rate.
class DelayBasedRateController {
public:
DelayBasedRateController(const WebRtcKeyValueConfig* key_value_config,
RtcEventLog* event_log,
TargetRateConstraints constraints);
~DelayBasedRateController();
void OnRouteChange();
void UpdateConstraints(TargetRateConstraints constraints);
void SetAcknowledgedRate(DataRate acknowledged_rate);
void OnTransportPacketsFeedback(TransportPacketsFeedback msg,
absl::optional<DataRate> probe_bitrate);
void OnTimeUpdate(Timestamp at_time);
void OnRemoteBitrateControl(RemoteBitrateReport msg);
TimeDelta GetExpectedBandwidthPeriod() const;
bool Enabled() const { return conf_.enabled; }
DataRate target_rate() const;
bool in_underuse() const;
private:
enum class ControllerSate { kHold, kExponentialIncrease, kLinearIncrease };
friend class GoogCcStatePrinter;
void OnFeedbackUpdate(BandwidthUsage usage,
absl::optional<DataRate> probe_bitrate,
Timestamp at_time);
void MaybeLog();
const DelayBasedRateControllerConfig conf_;
RtcEventLog* event_log_;
PacketDelayGrouper packet_grouper_;
std::unique_ptr<TrendlineEstimator> overuse_detector_;
LinkCapacityEstimator link_capacity_;
DataRate min_rate_ = DataRate::Zero();
DataRate max_rate_ = DataRate::Infinity();
absl::optional<DataRate> acknowledged_rate_;
TimeDelta last_rtt_ = TimeDelta::seconds(1);
Timestamp first_unacked_send_ = Timestamp::PlusInfinity();
Timestamp last_feedback_update_ = Timestamp::MinusInfinity();
DataRate target_rate_;
Timestamp last_no_ack_backoff_ = Timestamp::MinusInfinity();
bool increasing_state_ = false;
double accumulated_duration_ = 0;
Timestamp last_increase_update_ = Timestamp::PlusInfinity();
DataRate increase_reference_ = DataRate::PlusInfinity();
absl::optional<BandwidthUsage> logged_state_;
DataRate logged_target_ = DataRate::PlusInfinity();
};
} // namespace webrtc
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_BASED_RATE_CONTROLLER_H_

View File

@ -114,18 +114,7 @@ GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
absl::make_unique<SendSideBandwidthEstimation>(event_log_)),
alr_detector_(absl::make_unique<AlrDetector>()),
probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log)),
use_new_delay_based_controller_(
key_value_config_->Lookup("WebRTC-Bwe-DelayBasedRateController")
.find("Enabled") == 0),
delay_based_bwe_(use_new_delay_based_controller_
? nullptr
: new DelayBasedBwe(key_value_config_, event_log_)),
delay_based_controller_(
use_new_delay_based_controller_
? new DelayBasedRateController(key_value_config_,
event_log_,
config.constraints)
: nullptr),
delay_based_bwe_(new DelayBasedBwe(key_value_config_, event_log_)),
acknowledged_bitrate_estimator_(
absl::make_unique<AcknowledgedBitrateEstimator>(key_value_config_)),
initial_config_(config),
@ -188,16 +177,13 @@ NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
acknowledged_bitrate_estimator_.reset(
new AcknowledgedBitrateEstimator(key_value_config_));
probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
if (delay_based_bwe_) {
delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_));
if (msg.constraints.starting_rate)
delay_based_bwe_->SetStartBitrate(*msg.constraints.starting_rate);
// TODO(srte): Use original values instead of converted.
delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps));
} else {
delay_based_controller_->UpdateConstraints(msg.constraints);
delay_based_controller_->OnRouteChange();
}
bandwidth_estimation_->OnRouteChange();
bandwidth_estimation_->SetBitrates(
msg.constraints.starting_rate, DataRate::bps(min_bitrate_bps),
@ -237,11 +223,6 @@ NetworkControlUpdate GoogCcNetworkController::OnProcessInterval(
}
initial_config_.reset();
}
if (delay_based_controller_) {
delay_based_controller_->OnTimeUpdate(msg.at_time);
bandwidth_estimation_->UpdateDelayBasedEstimate(
msg.at_time, delay_based_controller_->target_rate());
}
if (congestion_window_pushback_controller_ && msg.pacer_queue) {
congestion_window_pushback_controller_->UpdatePacingQueue(
msg.pacer_queue->bytes());
@ -265,8 +246,6 @@ NetworkControlUpdate GoogCcNetworkController::OnRemoteBitrateReport(
RTC_LOG(LS_ERROR) << "Received REMB for packet feedback only GoogCC";
return NetworkControlUpdate();
}
if (delay_based_controller_)
delay_based_controller_->OnRemoteBitrateControl(msg);
bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time,
msg.bandwidth);
BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(),
@ -372,13 +351,9 @@ GoogCcNetworkController::UpdateBitrateConstraints(
starting_rate, DataRate::bps(min_bitrate_bps),
constraints.max_data_rate.value_or(DataRate::Infinity()),
constraints.at_time);
if (delay_based_bwe_) {
if (starting_rate)
delay_based_bwe_->SetStartBitrate(*starting_rate);
delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps));
} else {
delay_based_controller_->UpdateConstraints(constraints);
}
return probes;
}
@ -500,42 +475,27 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
NetworkControlUpdate update;
bool recovered_from_overuse = false;
bool backoff_in_alr = false;
// TODO(srte): Add support for ALR backoff trial in the new rate controller.
if (delay_based_controller_) {
if (acknowledged_bitrate)
delay_based_controller_->SetAcknowledgedRate(*acknowledged_bitrate);
bool prior_underuse = delay_based_controller_->in_underuse();
delay_based_controller_->OnTransportPacketsFeedback(report, probe_bitrate);
recovered_from_overuse =
prior_underuse && !delay_based_controller_->in_underuse();
if (probe_bitrate) {
bandwidth_estimation_->SetSendBitrate(
delay_based_controller_->target_rate(), report.feedback_time);
}
bandwidth_estimation_->UpdateDelayBasedEstimate(
report.feedback_time, delay_based_controller_->target_rate());
MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
} else {
DelayBasedBwe::Result result;
result = delay_based_bwe_->IncomingPacketFeedbackVector(
received_feedback_vector, acknowledged_bitrate, probe_bitrate,
alr_start_time.has_value(), report.feedback_time);
if (result.updated) {
if (result.probe) {
bandwidth_estimation_->SetSendBitrate(result.target_bitrate,
report.feedback_time);
}
// Since SetSendBitrate now resets the delay-based estimate, we have to
// call UpdateDelayBasedEstimate after SetSendBitrate.
bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time,
result.target_bitrate);
// Update the estimate in the ProbeController, in case we want to probe.
MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
DelayBasedBwe::Result result;
result = delay_based_bwe_->IncomingPacketFeedbackVector(
received_feedback_vector, acknowledged_bitrate, probe_bitrate,
alr_start_time.has_value(), report.feedback_time);
if (result.updated) {
if (result.probe) {
bandwidth_estimation_->SetSendBitrate(result.target_bitrate,
report.feedback_time);
}
recovered_from_overuse = result.recovered_from_overuse;
backoff_in_alr = result.backoff_in_alr;
// Since SetSendBitrate now resets the delay-based estimate, we have to
// call UpdateDelayBasedEstimate after SetSendBitrate.
bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time,
result.target_bitrate);
// Update the estimate in the ProbeController, in case we want to probe.
MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
}
recovered_from_overuse = result.recovered_from_overuse;
backoff_in_alr = result.backoff_in_alr;
if (recovered_from_overuse) {
probe_controller_->SetAlrStartTimeMs(alr_start_time);
auto probes = probe_controller_->RequestProbe(report.feedback_time.ms());
@ -592,8 +552,7 @@ NetworkControlUpdate GoogCcNetworkController::GetNetworkState(
last_estimated_fraction_loss_ / 255.0;
update.target_rate->network_estimate.round_trip_time = rtt;
update.target_rate->network_estimate.bwe_period =
delay_based_bwe_ ? delay_based_bwe_->GetExpectedBwePeriod()
: delay_based_controller_->GetExpectedBandwidthPeriod();
delay_based_bwe_->GetExpectedBwePeriod();
update.target_rate->at_time = at_time;
update.target_rate->target_rate = bandwidth;
@ -647,10 +606,7 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
? bandwidth_estimation_->GetEstimatedLinkCapacity()
: last_raw_target_rate_;
TimeDelta bwe_period =
delay_based_bwe_
? delay_based_bwe_->GetExpectedBwePeriod()
: delay_based_controller_->GetExpectedBandwidthPeriod();
TimeDelta bwe_period = delay_based_bwe_->GetExpectedBwePeriod();
TargetTransferRate target_rate_msg;
target_rate_msg.at_time = at_time;

View File

@ -30,7 +30,6 @@
#include "modules/congestion_controller/goog_cc/alr_detector.h"
#include "modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h"
#include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
#include "modules/congestion_controller/goog_cc/delay_based_rate_controller.h"
#include "modules/congestion_controller/goog_cc/probe_controller.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/experiments/field_trial_parser.h"
@ -88,9 +87,7 @@ class GoogCcNetworkController : public NetworkControllerInterface {
std::unique_ptr<SendSideBandwidthEstimation> bandwidth_estimation_;
std::unique_ptr<AlrDetector> alr_detector_;
std::unique_ptr<ProbeBitrateEstimator> probe_bitrate_estimator_;
const bool use_new_delay_based_controller_;
std::unique_ptr<DelayBasedBwe> delay_based_bwe_;
std::unique_ptr<DelayBasedRateController> delay_based_controller_;
std::unique_ptr<AcknowledgedBitrateEstimator> acknowledged_bitrate_estimator_;
absl::optional<NetworkControllerConfig> initial_config_;

View File

@ -446,11 +446,6 @@ TEST_F(GoogCcNetworkControllerTest,
UpdatesTargetRateBasedOnLinkCapacity("_loss_based");
}
TEST_F(GoogCcNetworkControllerTest, DelayBasedRateControlRegressionTest) {
ScopedFieldTrials trial("WebRTC-Bwe-DelayBasedRateController/Enabled/");
UpdatesTargetRateBasedOnLinkCapacity("_delay_based");
}
TEST_F(GoogCcNetworkControllerTest,
LossBasedControlDoesModestBackoffToHighLoss) {
ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");

View File

@ -1,111 +0,0 @@
/*
* Copyright 2018 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/congestion_controller/goog_cc/packet_grouping.h"
#include <algorithm>
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
namespace webrtc {
namespace {
constexpr TimeDelta kMaxSendTimeGroupDuration = TimeDelta::Millis<5>();
constexpr TimeDelta kMaxReceiveTimeBurstDelta = TimeDelta::Millis<5>();
constexpr TimeDelta kMaxReceiveTimeBurstDuration = TimeDelta::Millis<100>();
constexpr TimeDelta kReceiveTimeOffsetThreshold = TimeDelta::Millis<3000>();
constexpr int kReorderedResetThreshold = 3;
} // namespace
PacketDelayGroup::PacketDelayGroup(PacketResult packet, Timestamp feedback_time)
: first_send_time(packet.sent_packet.send_time),
last_send_time(packet.sent_packet.send_time),
first_receive_time(packet.receive_time),
last_receive_time(packet.receive_time),
last_feedback_time(feedback_time) {}
PacketDelayGroup::~PacketDelayGroup() = default;
PacketDelayGroup::PacketDelayGroup(const PacketDelayGroup&) = default;
void PacketDelayGroup::AddPacketInfo(PacketResult packet,
Timestamp feedback_time) {
last_send_time = std::max(last_send_time, packet.sent_packet.send_time);
first_receive_time = std::min(first_receive_time, packet.receive_time);
last_receive_time = std::max(last_receive_time, packet.receive_time);
last_feedback_time = std::max(last_feedback_time, feedback_time);
}
bool PacketDelayGroup::BelongsToGroup(PacketResult packet) const {
TimeDelta send_time_duration = packet.sent_packet.send_time - first_send_time;
return send_time_duration <= kMaxSendTimeGroupDuration;
}
bool PacketDelayGroup::BelongsToBurst(PacketResult packet) const {
TimeDelta send_time_delta = packet.sent_packet.send_time - first_send_time;
TimeDelta receive_time_delta = packet.receive_time - last_receive_time;
TimeDelta receive_time_duration = packet.receive_time - first_receive_time;
bool receiving_faster_than_sent = receive_time_delta < send_time_delta;
return receiving_faster_than_sent &&
receive_time_delta <= kMaxReceiveTimeBurstDelta &&
receive_time_duration <= kMaxReceiveTimeBurstDuration;
}
PacketDelayGrouper::PacketDelayGrouper() = default;
PacketDelayGrouper::~PacketDelayGrouper() = default;
void PacketDelayGrouper::AddPacketInfo(PacketResult packet,
Timestamp feedback_time) {
if (packet_groups_.empty()) {
packet_groups_.emplace_back(packet, feedback_time);
} else if (packet.sent_packet.send_time >=
packet_groups_.back().first_send_time) {
if (packet_groups_.back().BelongsToGroup(packet) ||
packet_groups_.back().BelongsToBurst(packet)) {
packet_groups_.back().AddPacketInfo(packet, feedback_time);
} else {
packet_groups_.emplace_back(packet, feedback_time);
}
}
}
std::vector<PacketDelayDelta> PacketDelayGrouper::PopDeltas() {
std::vector<PacketDelayDelta> deltas;
while (packet_groups_.size() >= 3) {
PacketDelayDelta delta;
delta.receive_time = packet_groups_[1].last_receive_time;
delta.send =
packet_groups_[1].last_send_time - packet_groups_[0].last_send_time;
delta.receive = packet_groups_[1].last_receive_time -
packet_groups_[0].last_receive_time;
delta.feedback = packet_groups_[1].last_feedback_time -
packet_groups_[0].last_feedback_time;
packet_groups_.pop_front();
if (delta.receive - delta.feedback >= kReceiveTimeOffsetThreshold) {
RTC_LOG(LS_WARNING) << "The receive clock offset has changed (diff = "
<< ToString(delta.receive - delta.feedback)
<< "), resetting.";
packet_groups_.pop_front();
} else if (delta.receive < TimeDelta::Zero()) {
++num_consecutive_reordered_packets_;
if (num_consecutive_reordered_packets_ >= kReorderedResetThreshold) {
RTC_LOG(LS_WARNING) << "Decreasing receive time in multiple "
"consecutive packet groups, resetting";
packet_groups_.pop_front();
}
} else {
num_consecutive_reordered_packets_ = 0;
deltas.push_back(delta);
}
}
return deltas;
}
} // namespace webrtc

View File

@ -1,58 +0,0 @@
/*
* Copyright 2018 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 MODULES_CONGESTION_CONTROLLER_GOOG_CC_PACKET_GROUPING_H_
#define MODULES_CONGESTION_CONTROLLER_GOOG_CC_PACKET_GROUPING_H_
#include <deque>
#include <vector>
#include "api/transport/network_control.h"
namespace webrtc {
struct PacketDelayGroup {
explicit PacketDelayGroup(PacketResult packet, Timestamp feedback_time);
PacketDelayGroup(const PacketDelayGroup&);
~PacketDelayGroup();
void AddPacketInfo(PacketResult packet, Timestamp feedback_time);
bool BelongsToGroup(PacketResult packet) const;
bool BelongsToBurst(PacketResult packet) const;
Timestamp first_send_time;
Timestamp last_send_time;
Timestamp first_receive_time;
Timestamp last_receive_time;
Timestamp last_feedback_time;
};
struct PacketDelayDelta {
Timestamp receive_time = Timestamp::PlusInfinity();
TimeDelta send = TimeDelta::Zero();
TimeDelta receive = TimeDelta::Zero();
TimeDelta feedback = TimeDelta::Zero();
};
class PacketDelayGrouper {
public:
PacketDelayGrouper();
~PacketDelayGrouper();
void AddPacketInfo(PacketResult packet, Timestamp feedback_time);
std::vector<PacketDelayDelta> PopDeltas();
void Reset() { packet_groups_.clear(); }
private:
std::deque<PacketDelayGroup> packet_groups_;
int num_consecutive_reordered_packets_ = 0;
};
} // namespace webrtc
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_PACKET_GROUPING_H_