Replaces redundant congestion controller components
This CL replaces components in the congestion controller module that are identical to equivalent components in the rtp and goog_cc subfolder. Some redundant components are left as they were not trivial to replace. Bug: webrtc:8415 Change-Id: I86a1f164d7b100b8ec8ba7dbc1c9bda2128a4f37 Reviewed-on: https://webrtc-review.googlesource.com/78521 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23384}
This commit is contained in:

committed by
Commit Bot

parent
ec2eb2218f
commit
172fd8536e
@ -40,7 +40,6 @@ rtc_static_library("congestion_controller") {
|
||||
|
||||
deps = [
|
||||
":delay_based_bwe",
|
||||
":estimators",
|
||||
":transport_feedback",
|
||||
"..:module_api",
|
||||
"../..:webrtc_common",
|
||||
@ -54,6 +53,7 @@ rtc_static_library("congestion_controller") {
|
||||
"../pacing",
|
||||
"../remote_bitrate_estimator",
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
"goog_cc:estimators",
|
||||
]
|
||||
|
||||
if (!build_with_mozilla) {
|
||||
@ -64,8 +64,6 @@ rtc_static_library("congestion_controller") {
|
||||
rtc_static_library("transport_feedback") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"send_time_history.cc",
|
||||
"send_time_history.h",
|
||||
"transport_feedback_adapter.cc",
|
||||
"transport_feedback_adapter.h",
|
||||
]
|
||||
@ -76,45 +74,7 @@ rtc_static_library("transport_feedback") {
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../system_wrappers:system_wrappers",
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("estimators") {
|
||||
configs += [ ":bwe_test_logging" ]
|
||||
sources = [
|
||||
"acknowledged_bitrate_estimator.cc",
|
||||
"acknowledged_bitrate_estimator.h",
|
||||
"bitrate_estimator.cc",
|
||||
"bitrate_estimator.h",
|
||||
"delay_increase_detector_interface.h",
|
||||
"median_slope_estimator.cc",
|
||||
"median_slope_estimator.h",
|
||||
"probe_bitrate_estimator.cc",
|
||||
"probe_bitrate_estimator.h",
|
||||
"trendline_estimator.cc",
|
||||
"trendline_estimator.h",
|
||||
]
|
||||
|
||||
# TODO(jschuh): Bug 1348: fix this warning.
|
||||
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
|
||||
|
||||
if (!build_with_chromium && is_clang) {
|
||||
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
|
||||
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"../../api:optional",
|
||||
"../../logging:rtc_event_bwe",
|
||||
"../../logging:rtc_event_log_api",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base:rtc_numerics",
|
||||
"../../rtc_base:safe_minmax",
|
||||
"../../system_wrappers:field_trial_api",
|
||||
"../../system_wrappers:metrics_api",
|
||||
"../remote_bitrate_estimator:remote_bitrate_estimator",
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
"rtp:transport_feedback",
|
||||
]
|
||||
}
|
||||
|
||||
@ -125,7 +85,6 @@ rtc_source_set("delay_based_bwe") {
|
||||
"delay_based_bwe.h",
|
||||
]
|
||||
deps = [
|
||||
":estimators",
|
||||
"../../:typedefs",
|
||||
"../../logging:rtc_event_bwe",
|
||||
"../../logging:rtc_event_log_api",
|
||||
@ -135,6 +94,7 @@ rtc_source_set("delay_based_bwe") {
|
||||
"../../system_wrappers:metrics_api",
|
||||
"../pacing",
|
||||
"../remote_bitrate_estimator",
|
||||
"goog_cc:estimators",
|
||||
]
|
||||
|
||||
if (!build_with_chromium && is_clang) {
|
||||
@ -148,25 +108,17 @@ if (rtc_include_tests) {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"acknowledged_bitrate_estimator_unittest.cc",
|
||||
"congestion_controller_unittests_helper.cc",
|
||||
"congestion_controller_unittests_helper.h",
|
||||
"delay_based_bwe_unittest.cc",
|
||||
"delay_based_bwe_unittest_helper.cc",
|
||||
"delay_based_bwe_unittest_helper.h",
|
||||
"median_slope_estimator_unittest.cc",
|
||||
"probe_bitrate_estimator_unittest.cc",
|
||||
"probe_controller_unittest.cc",
|
||||
"receive_side_congestion_controller_unittest.cc",
|
||||
"send_side_congestion_controller_unittest.cc",
|
||||
"send_time_history_unittest.cc",
|
||||
"transport_feedback_adapter_unittest.cc",
|
||||
"trendline_estimator_unittest.cc",
|
||||
]
|
||||
deps = [
|
||||
":congestion_controller",
|
||||
":delay_based_bwe",
|
||||
":estimators",
|
||||
":mock_congestion_controller",
|
||||
":transport_feedback",
|
||||
"../../logging:mocks",
|
||||
@ -184,6 +136,7 @@ if (rtc_include_tests) {
|
||||
"../remote_bitrate_estimator:remote_bitrate_estimator",
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
"bbr:bbr_unittests",
|
||||
"goog_cc:estimators",
|
||||
"goog_cc:goog_cc_unittests",
|
||||
"rtp:congestion_controller_unittests",
|
||||
]
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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/acknowledged_bitrate_estimator.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
#include "rtc_base/ptr_util.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
bool IsInSendTimeHistory(const PacketFeedback& packet) {
|
||||
return packet.send_time_ms != PacketFeedback::kNoSendTime;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
AcknowledgedBitrateEstimator::AcknowledgedBitrateEstimator()
|
||||
: AcknowledgedBitrateEstimator(rtc::MakeUnique<BitrateEstimator>()) {}
|
||||
|
||||
AcknowledgedBitrateEstimator::AcknowledgedBitrateEstimator(
|
||||
std::unique_ptr<BitrateEstimator> bitrate_estimator)
|
||||
: bitrate_estimator_(std::move(bitrate_estimator)) {}
|
||||
|
||||
void AcknowledgedBitrateEstimator::IncomingPacketFeedbackVector(
|
||||
const std::vector<PacketFeedback>& packet_feedback_vector) {
|
||||
RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(),
|
||||
packet_feedback_vector.end(),
|
||||
PacketFeedbackComparator()));
|
||||
for (const auto& packet : packet_feedback_vector) {
|
||||
if (IsInSendTimeHistory(packet)) {
|
||||
MaybeExpectFastRateChange(packet.send_time_ms);
|
||||
bitrate_estimator_->Update(packet.arrival_time_ms,
|
||||
rtc::dchecked_cast<int>(packet.payload_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rtc::Optional<uint32_t> AcknowledgedBitrateEstimator::bitrate_bps() const {
|
||||
return bitrate_estimator_->bitrate_bps();
|
||||
}
|
||||
|
||||
void AcknowledgedBitrateEstimator::SetAlrEndedTimeMs(
|
||||
int64_t alr_ended_time_ms) {
|
||||
alr_ended_time_ms_.emplace(alr_ended_time_ms);
|
||||
}
|
||||
|
||||
void AcknowledgedBitrateEstimator::MaybeExpectFastRateChange(
|
||||
int64_t packet_send_time_ms) {
|
||||
if (alr_ended_time_ms_ && packet_send_time_ms > *alr_ended_time_ms_) {
|
||||
bitrate_estimator_->ExpectFastRateChange();
|
||||
alr_ended_time_ms_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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_ACKNOWLEDGED_BITRATE_ESTIMATOR_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_ACKNOWLEDGED_BITRATE_ESTIMATOR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/optional.h"
|
||||
#include "modules/congestion_controller/bitrate_estimator.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct PacketFeedback;
|
||||
|
||||
class AcknowledgedBitrateEstimator {
|
||||
public:
|
||||
explicit AcknowledgedBitrateEstimator(
|
||||
std::unique_ptr<BitrateEstimator> bitrate_estimator);
|
||||
|
||||
AcknowledgedBitrateEstimator();
|
||||
|
||||
void IncomingPacketFeedbackVector(
|
||||
const std::vector<PacketFeedback>& packet_feedback_vector);
|
||||
rtc::Optional<uint32_t> bitrate_bps() const;
|
||||
void SetAlrEndedTimeMs(int64_t alr_ended_time_ms);
|
||||
|
||||
private:
|
||||
void MaybeExpectFastRateChange(int64_t packet_arrival_time_ms);
|
||||
rtc::Optional<int64_t> alr_ended_time_ms_;
|
||||
std::unique_ptr<BitrateEstimator> bitrate_estimator_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_ACKNOWLEDGED_BITRATE_ESTIMATOR_H_
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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/acknowledged_bitrate_estimator.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "rtc_base/fakeclock.h"
|
||||
#include "rtc_base/ptr_util.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
using testing::_;
|
||||
using testing::NiceMock;
|
||||
using testing::InSequence;
|
||||
using testing::Return;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int64_t kFirstArrivalTimeMs = 10;
|
||||
constexpr int64_t kFirstSendTimeMs = 10;
|
||||
constexpr uint16_t kSequenceNumber = 1;
|
||||
constexpr size_t kPayloadSize = 10;
|
||||
|
||||
class MockBitrateEstimator : public BitrateEstimator {
|
||||
public:
|
||||
MOCK_METHOD2(Update, void(int64_t now_ms, int bytes));
|
||||
MOCK_CONST_METHOD0(bitrate_bps, rtc::Optional<uint32_t>());
|
||||
MOCK_METHOD0(ExpectFastRateChange, void());
|
||||
};
|
||||
|
||||
struct AcknowledgedBitrateEstimatorTestStates {
|
||||
std::unique_ptr<AcknowledgedBitrateEstimator> acknowledged_bitrate_estimator;
|
||||
MockBitrateEstimator* mock_bitrate_estimator;
|
||||
};
|
||||
|
||||
AcknowledgedBitrateEstimatorTestStates CreateTestStates() {
|
||||
AcknowledgedBitrateEstimatorTestStates states;
|
||||
auto mock_bitrate_estimator = rtc::MakeUnique<MockBitrateEstimator>();
|
||||
states.mock_bitrate_estimator = mock_bitrate_estimator.get();
|
||||
states.acknowledged_bitrate_estimator =
|
||||
rtc::MakeUnique<AcknowledgedBitrateEstimator>(
|
||||
std::move(mock_bitrate_estimator));
|
||||
return states;
|
||||
}
|
||||
|
||||
std::vector<PacketFeedback> CreateFeedbackVector() {
|
||||
std::vector<PacketFeedback> packet_feedback_vector;
|
||||
const PacedPacketInfo pacing_info;
|
||||
packet_feedback_vector.push_back(
|
||||
PacketFeedback(kFirstArrivalTimeMs, kFirstSendTimeMs, kSequenceNumber,
|
||||
kPayloadSize, pacing_info));
|
||||
packet_feedback_vector.push_back(
|
||||
PacketFeedback(kFirstArrivalTimeMs + 10, kFirstSendTimeMs + 10,
|
||||
kSequenceNumber, kPayloadSize + 10, pacing_info));
|
||||
return packet_feedback_vector;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST(LegacyTestAcknowledgedBitrateEstimator,
|
||||
DontAddPacketsWhichAreNotInSendHistory) {
|
||||
auto states = CreateTestStates();
|
||||
std::vector<PacketFeedback> packet_feedback_vector;
|
||||
packet_feedback_vector.push_back(
|
||||
PacketFeedback(kFirstArrivalTimeMs, kSequenceNumber));
|
||||
EXPECT_CALL(*states.mock_bitrate_estimator, Update(_, _)).Times(0);
|
||||
states.acknowledged_bitrate_estimator->IncomingPacketFeedbackVector(
|
||||
packet_feedback_vector);
|
||||
}
|
||||
|
||||
TEST(LegacyTestAcknowledgedBitrateEstimator, UpdateBandwith) {
|
||||
auto states = CreateTestStates();
|
||||
auto packet_feedback_vector = CreateFeedbackVector();
|
||||
{
|
||||
InSequence dummy;
|
||||
EXPECT_CALL(
|
||||
*states.mock_bitrate_estimator,
|
||||
Update(packet_feedback_vector[0].arrival_time_ms,
|
||||
static_cast<int>(packet_feedback_vector[0].payload_size)))
|
||||
.Times(1);
|
||||
EXPECT_CALL(
|
||||
*states.mock_bitrate_estimator,
|
||||
Update(packet_feedback_vector[1].arrival_time_ms,
|
||||
static_cast<int>(packet_feedback_vector[1].payload_size)))
|
||||
.Times(1);
|
||||
}
|
||||
states.acknowledged_bitrate_estimator->IncomingPacketFeedbackVector(
|
||||
packet_feedback_vector);
|
||||
}
|
||||
|
||||
TEST(LegacyTestAcknowledgedBitrateEstimator, ExpectFastRateChangeWhenLeftAlr) {
|
||||
auto states = CreateTestStates();
|
||||
auto packet_feedback_vector = CreateFeedbackVector();
|
||||
{
|
||||
InSequence dummy;
|
||||
EXPECT_CALL(
|
||||
*states.mock_bitrate_estimator,
|
||||
Update(packet_feedback_vector[0].arrival_time_ms,
|
||||
static_cast<int>(packet_feedback_vector[0].payload_size)))
|
||||
.Times(1);
|
||||
EXPECT_CALL(*states.mock_bitrate_estimator, ExpectFastRateChange())
|
||||
.Times(1);
|
||||
EXPECT_CALL(
|
||||
*states.mock_bitrate_estimator,
|
||||
Update(packet_feedback_vector[1].arrival_time_ms,
|
||||
static_cast<int>(packet_feedback_vector[1].payload_size)))
|
||||
.Times(1);
|
||||
}
|
||||
states.acknowledged_bitrate_estimator->SetAlrEndedTimeMs(kFirstArrivalTimeMs +
|
||||
1);
|
||||
states.acknowledged_bitrate_estimator->IncomingPacketFeedbackVector(
|
||||
packet_feedback_vector);
|
||||
}
|
||||
|
||||
TEST(LegacyTestAcknowledgedBitrateEstimator, ReturnBitrate) {
|
||||
auto states = CreateTestStates();
|
||||
rtc::Optional<uint32_t> return_value(42);
|
||||
EXPECT_CALL(*states.mock_bitrate_estimator, bitrate_bps())
|
||||
.Times(1)
|
||||
.WillOnce(Return(return_value));
|
||||
EXPECT_EQ(return_value, states.acknowledged_bitrate_estimator->bitrate_bps());
|
||||
}
|
||||
|
||||
} // namespace webrtc*/
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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/bitrate_estimator.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
constexpr int kInitialRateWindowMs = 500;
|
||||
constexpr int kRateWindowMs = 150;
|
||||
} // namespace
|
||||
|
||||
BitrateEstimator::BitrateEstimator()
|
||||
: sum_(0),
|
||||
current_win_ms_(0),
|
||||
prev_time_ms_(-1),
|
||||
bitrate_estimate_(-1.0f),
|
||||
bitrate_estimate_var_(50.0f) {}
|
||||
|
||||
BitrateEstimator::~BitrateEstimator() = default;
|
||||
|
||||
void BitrateEstimator::Update(int64_t now_ms, int bytes) {
|
||||
int rate_window_ms = kRateWindowMs;
|
||||
// We use a larger window at the beginning to get a more stable sample that
|
||||
// we can use to initialize the estimate.
|
||||
if (bitrate_estimate_ < 0.f)
|
||||
rate_window_ms = kInitialRateWindowMs;
|
||||
float bitrate_sample = UpdateWindow(now_ms, bytes, rate_window_ms);
|
||||
if (bitrate_sample < 0.0f)
|
||||
return;
|
||||
if (bitrate_estimate_ < 0.0f) {
|
||||
// This is the very first sample we get. Use it to initialize the estimate.
|
||||
bitrate_estimate_ = bitrate_sample;
|
||||
return;
|
||||
}
|
||||
// Define the sample uncertainty as a function of how far away it is from the
|
||||
// current estimate.
|
||||
float sample_uncertainty =
|
||||
10.0f * std::abs(bitrate_estimate_ - bitrate_sample) / bitrate_estimate_;
|
||||
float sample_var = sample_uncertainty * sample_uncertainty;
|
||||
// Update a bayesian estimate of the rate, weighting it lower if the sample
|
||||
// uncertainty is large.
|
||||
// The bitrate estimate uncertainty is increased with each update to model
|
||||
// that the bitrate changes over time.
|
||||
float pred_bitrate_estimate_var = bitrate_estimate_var_ + 5.f;
|
||||
bitrate_estimate_ = (sample_var * bitrate_estimate_ +
|
||||
pred_bitrate_estimate_var * bitrate_sample) /
|
||||
(sample_var + pred_bitrate_estimate_var);
|
||||
bitrate_estimate_var_ = sample_var * pred_bitrate_estimate_var /
|
||||
(sample_var + pred_bitrate_estimate_var);
|
||||
BWE_TEST_LOGGING_PLOT(1, "acknowledged_bitrate", now_ms,
|
||||
bitrate_estimate_ * 1000);
|
||||
}
|
||||
|
||||
float BitrateEstimator::UpdateWindow(int64_t now_ms,
|
||||
int bytes,
|
||||
int rate_window_ms) {
|
||||
// Reset if time moves backwards.
|
||||
if (now_ms < prev_time_ms_) {
|
||||
prev_time_ms_ = -1;
|
||||
sum_ = 0;
|
||||
current_win_ms_ = 0;
|
||||
}
|
||||
if (prev_time_ms_ >= 0) {
|
||||
current_win_ms_ += now_ms - prev_time_ms_;
|
||||
// Reset if nothing has been received for more than a full window.
|
||||
if (now_ms - prev_time_ms_ > rate_window_ms) {
|
||||
sum_ = 0;
|
||||
current_win_ms_ %= rate_window_ms;
|
||||
}
|
||||
}
|
||||
prev_time_ms_ = now_ms;
|
||||
float bitrate_sample = -1.0f;
|
||||
if (current_win_ms_ >= rate_window_ms) {
|
||||
bitrate_sample = 8.0f * sum_ / static_cast<float>(rate_window_ms);
|
||||
current_win_ms_ -= rate_window_ms;
|
||||
sum_ = 0;
|
||||
}
|
||||
sum_ += bytes;
|
||||
return bitrate_sample;
|
||||
}
|
||||
|
||||
rtc::Optional<uint32_t> BitrateEstimator::bitrate_bps() const {
|
||||
if (bitrate_estimate_ < 0.f)
|
||||
return rtc::nullopt;
|
||||
return bitrate_estimate_ * 1000;
|
||||
}
|
||||
|
||||
void BitrateEstimator::ExpectFastRateChange() {
|
||||
// By setting the bitrate-estimate variance to a higher value we allow the
|
||||
// bitrate to change fast for the next few samples.
|
||||
bitrate_estimate_var_ += 200;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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_BITRATE_ESTIMATOR_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_BITRATE_ESTIMATOR_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "api/optional.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Computes a bayesian estimate of the throughput given acks containing
|
||||
// the arrival time and payload size. Samples which are far from the current
|
||||
// estimate or are based on few packets are given a smaller weight, as they
|
||||
// are considered to be more likely to have been caused by, e.g., delay spikes
|
||||
// unrelated to congestion.
|
||||
class BitrateEstimator {
|
||||
public:
|
||||
BitrateEstimator();
|
||||
virtual ~BitrateEstimator();
|
||||
virtual void Update(int64_t now_ms, int bytes);
|
||||
|
||||
virtual rtc::Optional<uint32_t> bitrate_bps() const;
|
||||
|
||||
virtual void ExpectFastRateChange();
|
||||
|
||||
private:
|
||||
float UpdateWindow(int64_t now_ms, int bytes, int rate_window_ms);
|
||||
int sum_;
|
||||
int64_t current_win_ms_;
|
||||
int64_t prev_time_ms_;
|
||||
float bitrate_estimate_;
|
||||
float bitrate_estimate_var_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_BITRATE_ESTIMATOR_H_
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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/congestion_controller_unittests_helper.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
void ComparePacketFeedbackVectors(const std::vector<PacketFeedback>& truth,
|
||||
const std::vector<PacketFeedback>& input) {
|
||||
ASSERT_EQ(truth.size(), input.size());
|
||||
size_t len = truth.size();
|
||||
// truth contains the input data for the test, and input is what will be
|
||||
// sent to the bandwidth estimator. truth.arrival_tims_ms is used to
|
||||
// populate the transport feedback messages. As these times may be changed
|
||||
// (because of resolution limits in the packets, and because of the time
|
||||
// base adjustment performed by the TransportFeedbackAdapter at the first
|
||||
// packet, the truth[x].arrival_time and input[x].arrival_time may not be
|
||||
// equal. However, the difference must be the same for all x.
|
||||
int64_t arrival_time_delta =
|
||||
truth[0].arrival_time_ms - input[0].arrival_time_ms;
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
RTC_CHECK(truth[i].arrival_time_ms != PacketFeedback::kNotReceived);
|
||||
if (input[i].arrival_time_ms != PacketFeedback::kNotReceived) {
|
||||
EXPECT_EQ(truth[i].arrival_time_ms,
|
||||
input[i].arrival_time_ms + arrival_time_delta);
|
||||
}
|
||||
EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms);
|
||||
EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number);
|
||||
EXPECT_EQ(truth[i].payload_size, input[i].payload_size);
|
||||
EXPECT_EQ(truth[i].pacing_info, input[i].pacing_info);
|
||||
}
|
||||
}
|
||||
} // namespace webrtc
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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_CONGESTION_CONTROLLER_UNITTESTS_HELPER_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_CONGESTION_CONTROLLER_UNITTESTS_HELPER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
|
||||
namespace webrtc {
|
||||
void ComparePacketFeedbackVectors(const std::vector<PacketFeedback>& truth,
|
||||
const std::vector<PacketFeedback>& input);
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_CONGESTION_CONTROLLER_UNITTESTS_HELPER_H_
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
|
||||
#include "logging/rtc_event_log/rtc_event_log.h"
|
||||
#include "modules/congestion_controller/trendline_estimator.h"
|
||||
#include "modules/congestion_controller/goog_cc/trendline_estimator.h"
|
||||
#include "modules/pacing/paced_sender.h"
|
||||
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/congestion_controller/delay_increase_detector_interface.h"
|
||||
#include "modules/congestion_controller/probe_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/goog_cc/delay_increase_detector_interface.h"
|
||||
#include "modules/congestion_controller/goog_cc/probe_bitrate_estimator.h"
|
||||
#include "modules/remote_bitrate_estimator/aimd_rate_control.h"
|
||||
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "modules/remote_bitrate_estimator/inter_arrival.h"
|
||||
|
@ -17,8 +17,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/congestion_controller/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/delay_based_bwe.h"
|
||||
#include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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_DELAY_INCREASE_DETECTOR_INTERFACE_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_DELAY_INCREASE_DETECTOR_INTERFACE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class DelayIncreaseDetectorInterface {
|
||||
public:
|
||||
DelayIncreaseDetectorInterface() {}
|
||||
virtual ~DelayIncreaseDetectorInterface() {}
|
||||
|
||||
// Update the detector with a new sample. The deltas should represent deltas
|
||||
// between timestamp groups as defined by the InterArrival class.
|
||||
virtual void Update(double recv_delta_ms,
|
||||
double send_delta_ms,
|
||||
int64_t arrival_time_ms) = 0;
|
||||
|
||||
virtual BandwidthUsage State() const = 0;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(DelayIncreaseDetectorInterface);
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_DELAY_INCREASE_DETECTOR_INTERFACE_H_
|
@ -17,7 +17,6 @@
|
||||
#include "rtc_base/ptr_util.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
namespace {
|
||||
bool IsInSendTimeHistory(const PacketFeedback& packet) {
|
||||
@ -65,5 +64,4 @@ void AcknowledgedBitrateEstimator::MaybeExpectFastRateChange(
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -21,8 +21,6 @@ namespace webrtc {
|
||||
|
||||
struct PacketFeedback;
|
||||
|
||||
namespace webrtc_cc {
|
||||
|
||||
class AcknowledgedBitrateEstimator {
|
||||
public:
|
||||
explicit AcknowledgedBitrateEstimator(
|
||||
@ -42,7 +40,6 @@ class AcknowledgedBitrateEstimator {
|
||||
std::unique_ptr<BitrateEstimator> bitrate_estimator_;
|
||||
};
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_ACKNOWLEDGED_BITRATE_ESTIMATOR_H_
|
||||
|
@ -24,7 +24,6 @@ using testing::InSequence;
|
||||
using testing::Return;
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
namespace {
|
||||
|
||||
@ -132,5 +131,4 @@ TEST(TestAcknowledgedBitrateEstimator, ReturnBitrate) {
|
||||
EXPECT_EQ(return_value, states.acknowledged_bitrate_estimator->bitrate_bps());
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc*/
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
namespace {
|
||||
constexpr int kInitialRateWindowMs = 500;
|
||||
@ -105,5 +104,4 @@ void BitrateEstimator::ExpectFastRateChange() {
|
||||
bitrate_estimate_var_ += 200;
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "api/optional.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
// Computes a bayesian estimate of the throughput given acks containing
|
||||
// the arrival time and payload size. Samples which are far from the current
|
||||
@ -42,7 +41,6 @@ class BitrateEstimator {
|
||||
float bitrate_estimate_var_;
|
||||
};
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_BITRATE_ESTIMATOR_H_
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
class DelayIncreaseDetectorInterface {
|
||||
public:
|
||||
@ -33,7 +32,7 @@ class DelayIncreaseDetectorInterface {
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(DelayIncreaseDetectorInterface);
|
||||
};
|
||||
} // namespace webrtc_cc
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_INCREASE_DETECTOR_INTERFACE_H_
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
constexpr unsigned int kDeltaCounterMax = 1000;
|
||||
|
||||
@ -91,5 +90,4 @@ void MedianSlopeEstimator::Update(double recv_delta_ms,
|
||||
BWE_TEST_LOGGING_PLOT(1, "trendline_slope", arrival_time_ms, trendline_);
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "rtc_base/numerics/percentile_filter.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
class MedianSlopeEstimator {
|
||||
public:
|
||||
@ -68,7 +67,7 @@ class MedianSlopeEstimator {
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(MedianSlopeEstimator);
|
||||
};
|
||||
} // namespace webrtc_cc
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_MEDIAN_SLOPE_ESTIMATOR_H_
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
namespace {
|
||||
constexpr size_t kWindowSize = 20;
|
||||
@ -70,5 +69,4 @@ TEST(MedianSlopeEstimator, JitteryLineSlopeZero) {
|
||||
TestEstimator(0, kAvgTimeBetweenPackets / 3.0, 0.02);
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -53,7 +53,6 @@ constexpr int kMaxProbeIntervalMs = 1000;
|
||||
} // namespace
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
ProbeBitrateEstimator::ProbeBitrateEstimator(RtcEventLog* event_log)
|
||||
: event_log_(event_log) {}
|
||||
@ -187,5 +186,4 @@ void ProbeBitrateEstimator::EraseOldClusters(int64_t timestamp_ms) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
class RtcEventLog;
|
||||
namespace webrtc_cc {
|
||||
|
||||
class ProbeBitrateEstimator {
|
||||
public:
|
||||
@ -51,7 +50,6 @@ class ProbeBitrateEstimator {
|
||||
rtc::Optional<int> estimated_bitrate_bps_;
|
||||
};
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_PROBE_BITRATE_ESTIMATOR_H_
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
namespace {
|
||||
constexpr int kInvalidBitrate = -1;
|
||||
@ -219,5 +218,4 @@ TEST_F(TestProbeBitrateEstimator, FetchLastEstimatedBitrateBps) {
|
||||
EXPECT_FALSE(probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps());
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "rtc_base/numerics/safe_minmax.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
namespace {
|
||||
rtc::Optional<double> LinearFitSlope(
|
||||
@ -181,5 +180,4 @@ void TrendlineEstimator::UpdateThreshold(double modified_offset,
|
||||
last_update_ms_ = now_ms;
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
class TrendlineEstimator : public DelayIncreaseDetectorInterface {
|
||||
public:
|
||||
@ -88,7 +87,6 @@ class TrendlineEstimator : public DelayIncreaseDetectorInterface {
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(TrendlineEstimator);
|
||||
};
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_TRENDLINE_ESTIMATOR_H_
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
namespace {
|
||||
constexpr size_t kWindowSize = 20;
|
||||
@ -71,5 +70,4 @@ TEST(TrendlineEstimator, JitteryLineSlopeZero) {
|
||||
TestEstimator(0, kAvgTimeBetweenPackets / 3.0, 0.02);
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* 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/congestion_controller/median_slope_estimator.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
constexpr unsigned int kDeltaCounterMax = 1000;
|
||||
|
||||
MedianSlopeEstimator::MedianSlopeEstimator(size_t window_size,
|
||||
double threshold_gain)
|
||||
: window_size_(window_size),
|
||||
threshold_gain_(threshold_gain),
|
||||
num_of_deltas_(0),
|
||||
accumulated_delay_(0),
|
||||
delay_hist_(),
|
||||
median_filter_(0.5),
|
||||
trendline_(0) {}
|
||||
|
||||
MedianSlopeEstimator::~MedianSlopeEstimator() {}
|
||||
|
||||
MedianSlopeEstimator::DelayInfo::DelayInfo(int64_t time,
|
||||
double delay,
|
||||
size_t slope_count)
|
||||
: time(time), delay(delay) {
|
||||
slopes.reserve(slope_count);
|
||||
}
|
||||
|
||||
MedianSlopeEstimator::DelayInfo::~DelayInfo() = default;
|
||||
|
||||
void MedianSlopeEstimator::Update(double recv_delta_ms,
|
||||
double send_delta_ms,
|
||||
int64_t arrival_time_ms) {
|
||||
const double delta_ms = recv_delta_ms - send_delta_ms;
|
||||
++num_of_deltas_;
|
||||
if (num_of_deltas_ > kDeltaCounterMax)
|
||||
num_of_deltas_ = kDeltaCounterMax;
|
||||
|
||||
accumulated_delay_ += delta_ms;
|
||||
BWE_TEST_LOGGING_PLOT(1, "accumulated_delay_ms", arrival_time_ms,
|
||||
accumulated_delay_);
|
||||
|
||||
// If the window is full, remove the |window_size_| - 1 slopes that belong to
|
||||
// the oldest point.
|
||||
if (delay_hist_.size() == window_size_) {
|
||||
for (double slope : delay_hist_.front().slopes) {
|
||||
const bool success = median_filter_.Erase(slope);
|
||||
RTC_CHECK(success);
|
||||
}
|
||||
delay_hist_.pop_front();
|
||||
}
|
||||
// Add |window_size_| - 1 new slopes.
|
||||
for (auto& old_delay : delay_hist_) {
|
||||
if (arrival_time_ms - old_delay.time != 0) {
|
||||
// The C99 standard explicitly states that casts and assignments must
|
||||
// perform the associated conversions. This means that |slope| will be
|
||||
// a 64-bit double even if the division is computed using, e.g., 80-bit
|
||||
// extended precision. I believe this also holds in C++ even though the
|
||||
// C++11 standard isn't as explicit. Furthermore, there are good reasons
|
||||
// to believe that compilers couldn't perform optimizations that break
|
||||
// this assumption even if they wanted to.
|
||||
double slope = (accumulated_delay_ - old_delay.delay) /
|
||||
static_cast<double>(arrival_time_ms - old_delay.time);
|
||||
median_filter_.Insert(slope);
|
||||
// We want to avoid issues with different rounding mode / precision
|
||||
// which we might get if we recomputed the slope when we remove it.
|
||||
old_delay.slopes.push_back(slope);
|
||||
}
|
||||
}
|
||||
delay_hist_.emplace_back(arrival_time_ms, accumulated_delay_,
|
||||
window_size_ - 1);
|
||||
// Recompute the median slope.
|
||||
if (delay_hist_.size() == window_size_)
|
||||
trendline_ = median_filter_.GetPercentileValue();
|
||||
|
||||
BWE_TEST_LOGGING_PLOT(1, "trendline_slope", arrival_time_ms, trendline_);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_MEDIAN_SLOPE_ESTIMATOR_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_MEDIAN_SLOPE_ESTIMATOR_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/numerics/percentile_filter.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class MedianSlopeEstimator {
|
||||
public:
|
||||
// |window_size| is the number of points required to compute a trend line.
|
||||
// |threshold_gain| is used to scale the trendline slope for comparison to
|
||||
// the old threshold. Once the old estimator has been removed (or the
|
||||
// thresholds been merged into the estimators), we can just set the
|
||||
// threshold instead of setting a gain.
|
||||
MedianSlopeEstimator(size_t window_size, double threshold_gain);
|
||||
~MedianSlopeEstimator();
|
||||
|
||||
// Update the estimator with a new sample. The deltas should represent deltas
|
||||
// between timestamp groups as defined by the InterArrival class.
|
||||
void Update(double recv_delta_ms,
|
||||
double send_delta_ms,
|
||||
int64_t arrival_time_ms);
|
||||
|
||||
// Returns the estimated trend k multiplied by some gain.
|
||||
// 0 < k < 1 -> the delay increases, queues are filling up
|
||||
// k == 0 -> the delay does not change
|
||||
// k < 0 -> the delay decreases, queues are being emptied
|
||||
double trendline_slope() const { return trendline_ * threshold_gain_; }
|
||||
|
||||
// Returns the number of deltas which the current estimator state is based on.
|
||||
unsigned int num_of_deltas() const { return num_of_deltas_; }
|
||||
|
||||
private:
|
||||
struct DelayInfo {
|
||||
DelayInfo(int64_t time, double delay, size_t slope_count);
|
||||
~DelayInfo();
|
||||
int64_t time;
|
||||
double delay;
|
||||
std::vector<double> slopes;
|
||||
};
|
||||
// Parameters.
|
||||
const size_t window_size_;
|
||||
const double threshold_gain_;
|
||||
// Used by the existing threshold.
|
||||
unsigned int num_of_deltas_;
|
||||
// Theil-Sen robust line fitting
|
||||
double accumulated_delay_;
|
||||
std::deque<DelayInfo> delay_hist_;
|
||||
PercentileFilter<double> median_filter_;
|
||||
double trendline_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(MedianSlopeEstimator);
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_MEDIAN_SLOPE_ESTIMATOR_H_
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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/congestion_controller/median_slope_estimator.h"
|
||||
#include "rtc_base/random.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
constexpr size_t kWindowSize = 20;
|
||||
constexpr double kGain = 1;
|
||||
constexpr int64_t kAvgTimeBetweenPackets = 10;
|
||||
constexpr size_t kPacketCount = 2 * kWindowSize + 1;
|
||||
|
||||
void TestEstimator(double slope, double jitter_stddev, double tolerance) {
|
||||
MedianSlopeEstimator estimator(kWindowSize, kGain);
|
||||
Random random(0x1234567);
|
||||
int64_t send_times[kPacketCount];
|
||||
int64_t recv_times[kPacketCount];
|
||||
int64_t send_start_time = random.Rand(1000000);
|
||||
int64_t recv_start_time = random.Rand(1000000);
|
||||
for (size_t i = 0; i < kPacketCount; ++i) {
|
||||
send_times[i] = send_start_time + i * kAvgTimeBetweenPackets;
|
||||
double latency = i * kAvgTimeBetweenPackets / (1 - slope);
|
||||
double jitter = random.Gaussian(0, jitter_stddev);
|
||||
recv_times[i] = recv_start_time + latency + jitter;
|
||||
}
|
||||
for (size_t i = 1; i < kPacketCount; ++i) {
|
||||
double recv_delta = recv_times[i] - recv_times[i - 1];
|
||||
double send_delta = send_times[i] - send_times[i - 1];
|
||||
estimator.Update(recv_delta, send_delta, recv_times[i]);
|
||||
if (i < kWindowSize)
|
||||
EXPECT_NEAR(estimator.trendline_slope(), 0, 0.001);
|
||||
else
|
||||
EXPECT_NEAR(estimator.trendline_slope(), slope, tolerance);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(DeprecatedMedianSlopeEstimator, PerfectLineSlopeOneHalf) {
|
||||
TestEstimator(0.5, 0, 0.001);
|
||||
}
|
||||
|
||||
TEST(DeprecatedMedianSlopeEstimator, PerfectLineSlopeMinusOne) {
|
||||
TestEstimator(-1, 0, 0.001);
|
||||
}
|
||||
|
||||
TEST(DeprecatedMedianSlopeEstimator, PerfectLineSlopeZero) {
|
||||
TestEstimator(0, 0, 0.001);
|
||||
}
|
||||
|
||||
TEST(DeprecatedMedianSlopeEstimator, JitteryLineSlopeOneHalf) {
|
||||
TestEstimator(0.5, kAvgTimeBetweenPackets / 3.0, 0.01);
|
||||
}
|
||||
|
||||
TEST(DeprecatedMedianSlopeEstimator, JitteryLineSlopeMinusOne) {
|
||||
TestEstimator(-1, kAvgTimeBetweenPackets / 3.0, 0.05);
|
||||
}
|
||||
|
||||
TEST(DeprecatedMedianSlopeEstimator, JitteryLineSlopeZero) {
|
||||
TestEstimator(0, kAvgTimeBetweenPackets / 3.0, 0.02);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,189 +0,0 @@
|
||||
/*
|
||||
* 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/congestion_controller/probe_bitrate_estimator.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
|
||||
#include "logging/rtc_event_log/rtc_event_log.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
#include "rtc_base/ptr_util.h"
|
||||
|
||||
namespace {
|
||||
// The minumum number of probes we need to receive feedback about in percent
|
||||
// in order to have a valid estimate.
|
||||
constexpr int kMinReceivedProbesPercent = 80;
|
||||
|
||||
// The minumum number of bytes we need to receive feedback about in percent
|
||||
// in order to have a valid estimate.
|
||||
constexpr int kMinReceivedBytesPercent = 80;
|
||||
|
||||
// The maximum |receive rate| / |send rate| ratio for a valid estimate.
|
||||
constexpr float kMaxValidRatio = 2.0f;
|
||||
|
||||
// The minimum |receive rate| / |send rate| ratio assuming that the link is
|
||||
// not saturated, i.e. we assume that we will receive at least
|
||||
// kMinRatioForUnsaturatedLink * |send rate| if |send rate| is less than the
|
||||
// link capacity.
|
||||
constexpr float kMinRatioForUnsaturatedLink = 0.9f;
|
||||
|
||||
// The target utilization of the link. If we know true link capacity
|
||||
// we'd like to send at 95% of that rate.
|
||||
constexpr float kTargetUtilizationFraction = 0.95f;
|
||||
|
||||
// The maximum time period over which the cluster history is retained.
|
||||
// This is also the maximum time period beyond which a probing burst is not
|
||||
// expected to last.
|
||||
constexpr int kMaxClusterHistoryMs = 1000;
|
||||
|
||||
// The maximum time interval between first and the last probe on a cluster
|
||||
// on the sender side as well as the receive side.
|
||||
constexpr int kMaxProbeIntervalMs = 1000;
|
||||
} // namespace
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
ProbeBitrateEstimator::ProbeBitrateEstimator(RtcEventLog* event_log)
|
||||
: event_log_(event_log) {}
|
||||
|
||||
ProbeBitrateEstimator::~ProbeBitrateEstimator() = default;
|
||||
|
||||
int ProbeBitrateEstimator::HandleProbeAndEstimateBitrate(
|
||||
const PacketFeedback& packet_feedback) {
|
||||
int cluster_id = packet_feedback.pacing_info.probe_cluster_id;
|
||||
RTC_DCHECK_NE(cluster_id, PacedPacketInfo::kNotAProbe);
|
||||
|
||||
EraseOldClusters(packet_feedback.arrival_time_ms - kMaxClusterHistoryMs);
|
||||
|
||||
int payload_size_bits = rtc::dchecked_cast<int>(
|
||||
packet_feedback.payload_size * 8);
|
||||
AggregatedCluster* cluster = &clusters_[cluster_id];
|
||||
|
||||
if (packet_feedback.send_time_ms < cluster->first_send_ms) {
|
||||
cluster->first_send_ms = packet_feedback.send_time_ms;
|
||||
}
|
||||
if (packet_feedback.send_time_ms > cluster->last_send_ms) {
|
||||
cluster->last_send_ms = packet_feedback.send_time_ms;
|
||||
cluster->size_last_send = payload_size_bits;
|
||||
}
|
||||
if (packet_feedback.arrival_time_ms < cluster->first_receive_ms) {
|
||||
cluster->first_receive_ms = packet_feedback.arrival_time_ms;
|
||||
cluster->size_first_receive = payload_size_bits;
|
||||
}
|
||||
if (packet_feedback.arrival_time_ms > cluster->last_receive_ms) {
|
||||
cluster->last_receive_ms = packet_feedback.arrival_time_ms;
|
||||
}
|
||||
cluster->size_total += payload_size_bits;
|
||||
cluster->num_probes += 1;
|
||||
|
||||
RTC_DCHECK_GT(packet_feedback.pacing_info.probe_cluster_min_probes, 0);
|
||||
RTC_DCHECK_GT(packet_feedback.pacing_info.probe_cluster_min_bytes, 0);
|
||||
|
||||
int min_probes = packet_feedback.pacing_info.probe_cluster_min_probes *
|
||||
kMinReceivedProbesPercent / 100;
|
||||
int min_bytes = packet_feedback.pacing_info.probe_cluster_min_bytes *
|
||||
kMinReceivedBytesPercent / 100;
|
||||
if (cluster->num_probes < min_probes || cluster->size_total < min_bytes * 8)
|
||||
return -1;
|
||||
|
||||
float send_interval_ms = cluster->last_send_ms - cluster->first_send_ms;
|
||||
float receive_interval_ms =
|
||||
cluster->last_receive_ms - cluster->first_receive_ms;
|
||||
|
||||
if (send_interval_ms <= 0 || send_interval_ms > kMaxProbeIntervalMs ||
|
||||
receive_interval_ms <= 0 || receive_interval_ms > kMaxProbeIntervalMs) {
|
||||
RTC_LOG(LS_INFO) << "Probing unsuccessful, invalid send/receive interval"
|
||||
<< " [cluster id: " << cluster_id
|
||||
<< "] [send interval: " << send_interval_ms << " ms]"
|
||||
<< " [receive interval: " << receive_interval_ms << " ms]";
|
||||
if (event_log_) {
|
||||
event_log_->Log(rtc::MakeUnique<RtcEventProbeResultFailure>(
|
||||
cluster_id, ProbeFailureReason::kInvalidSendReceiveInterval));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
// Since the |send_interval_ms| does not include the time it takes to actually
|
||||
// send the last packet the size of the last sent packet should not be
|
||||
// included when calculating the send bitrate.
|
||||
RTC_DCHECK_GT(cluster->size_total, cluster->size_last_send);
|
||||
float send_size = cluster->size_total - cluster->size_last_send;
|
||||
float send_bps = send_size / send_interval_ms * 1000;
|
||||
|
||||
// Since the |receive_interval_ms| does not include the time it takes to
|
||||
// actually receive the first packet the size of the first received packet
|
||||
// should not be included when calculating the receive bitrate.
|
||||
RTC_DCHECK_GT(cluster->size_total, cluster->size_first_receive);
|
||||
float receive_size = cluster->size_total - cluster->size_first_receive;
|
||||
float receive_bps = receive_size / receive_interval_ms * 1000;
|
||||
|
||||
float ratio = receive_bps / send_bps;
|
||||
if (ratio > kMaxValidRatio) {
|
||||
RTC_LOG(LS_INFO) << "Probing unsuccessful, receive/send ratio too high"
|
||||
<< " [cluster id: " << cluster_id
|
||||
<< "] [send: " << send_size << " bytes / "
|
||||
<< send_interval_ms << " ms = " << send_bps / 1000
|
||||
<< " kb/s]"
|
||||
<< " [receive: " << receive_size << " bytes / "
|
||||
<< receive_interval_ms << " ms = " << receive_bps / 1000
|
||||
<< " kb/s]"
|
||||
<< " [ratio: " << receive_bps / 1000 << " / "
|
||||
<< send_bps / 1000 << " = " << ratio
|
||||
<< " > kMaxValidRatio (" << kMaxValidRatio << ")]";
|
||||
if (event_log_) {
|
||||
event_log_->Log(rtc::MakeUnique<RtcEventProbeResultFailure>(
|
||||
cluster_id, ProbeFailureReason::kInvalidSendReceiveRatio));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
RTC_LOG(LS_INFO) << "Probing successful"
|
||||
<< " [cluster id: " << cluster_id << "] [send: " << send_size
|
||||
<< " bytes / " << send_interval_ms
|
||||
<< " ms = " << send_bps / 1000 << " kb/s]"
|
||||
<< " [receive: " << receive_size << " bytes / "
|
||||
<< receive_interval_ms << " ms = " << receive_bps / 1000
|
||||
<< " kb/s]";
|
||||
|
||||
float res = std::min(send_bps, receive_bps);
|
||||
// If we're receiving at significantly lower bitrate than we were sending at,
|
||||
// it suggests that we've found the true capacity of the link. In this case,
|
||||
// set the target bitrate slightly lower to not immediately overuse.
|
||||
if (receive_bps < kMinRatioForUnsaturatedLink * send_bps) {
|
||||
RTC_DCHECK_GT(send_bps, receive_bps);
|
||||
res = kTargetUtilizationFraction * receive_bps;
|
||||
}
|
||||
if (event_log_) {
|
||||
event_log_->Log(
|
||||
rtc::MakeUnique<RtcEventProbeResultSuccess>(cluster_id, res));
|
||||
}
|
||||
estimated_bitrate_bps_ = res;
|
||||
return *estimated_bitrate_bps_;
|
||||
}
|
||||
|
||||
rtc::Optional<int>
|
||||
ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrateBps() {
|
||||
rtc::Optional<int> estimated_bitrate_bps = estimated_bitrate_bps_;
|
||||
estimated_bitrate_bps_.reset();
|
||||
return estimated_bitrate_bps;
|
||||
}
|
||||
|
||||
void ProbeBitrateEstimator::EraseOldClusters(int64_t timestamp_ms) {
|
||||
for (auto it = clusters_.begin(); it != clusters_.end();) {
|
||||
if (it->second.last_receive_ms < timestamp_ms) {
|
||||
it = clusters_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace webrtc
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_PROBE_BITRATE_ESTIMATOR_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_PROBE_BITRATE_ESTIMATOR_H_
|
||||
|
||||
#include <map>
|
||||
#include <limits>
|
||||
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
|
||||
namespace webrtc {
|
||||
class RtcEventLog;
|
||||
|
||||
class ProbeBitrateEstimator {
|
||||
public:
|
||||
explicit ProbeBitrateEstimator(RtcEventLog* event_log);
|
||||
~ProbeBitrateEstimator();
|
||||
|
||||
// Should be called for every probe packet we receive feedback about.
|
||||
// Returns the estimated bitrate if the probe completes a valid cluster.
|
||||
int HandleProbeAndEstimateBitrate(const PacketFeedback& packet_feedback);
|
||||
|
||||
rtc::Optional<int> FetchAndResetLastEstimatedBitrateBps();
|
||||
|
||||
private:
|
||||
struct AggregatedCluster {
|
||||
int num_probes = 0;
|
||||
int64_t first_send_ms = std::numeric_limits<int64_t>::max();
|
||||
int64_t last_send_ms = 0;
|
||||
int64_t first_receive_ms = std::numeric_limits<int64_t>::max();
|
||||
int64_t last_receive_ms = 0;
|
||||
int size_last_send = 0;
|
||||
int size_first_receive = 0;
|
||||
int size_total = 0;
|
||||
};
|
||||
|
||||
// Erases old cluster data that was seen before |timestamp_ms|.
|
||||
void EraseOldClusters(int64_t timestamp_ms);
|
||||
|
||||
std::map<int, AggregatedCluster> clusters_;
|
||||
RtcEventLog* const event_log_;
|
||||
rtc::Optional<int> estimated_bitrate_bps_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_PROBE_BITRATE_ESTIMATOR_H_
|
@ -1,221 +0,0 @@
|
||||
/*
|
||||
* 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/congestion_controller/probe_bitrate_estimator.h"
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "modules/remote_bitrate_estimator/aimd_rate_control.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
constexpr int kInvalidBitrate = -1;
|
||||
constexpr int kDefaultMinProbes = 5;
|
||||
constexpr int kDefaultMinBytes = 5000;
|
||||
constexpr float kTargetUtilizationFraction = 0.95f;
|
||||
} // anonymous namespace
|
||||
|
||||
class LegacyTestProbeBitrateEstimator : public ::testing::Test {
|
||||
public:
|
||||
LegacyTestProbeBitrateEstimator() : probe_bitrate_estimator_(nullptr) {}
|
||||
|
||||
// TODO(philipel): Use PacedPacketInfo when ProbeBitrateEstimator is rewritten
|
||||
// to use that information.
|
||||
void AddPacketFeedback(int probe_cluster_id,
|
||||
size_t size_bytes,
|
||||
int64_t send_time_ms,
|
||||
int64_t arrival_time_ms,
|
||||
int min_probes = kDefaultMinProbes,
|
||||
int min_bytes = kDefaultMinBytes) {
|
||||
PacedPacketInfo pacing_info(probe_cluster_id, min_probes, min_bytes);
|
||||
PacketFeedback packet_feedback(arrival_time_ms, send_time_ms, 0, size_bytes,
|
||||
pacing_info);
|
||||
measured_bps_ =
|
||||
probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback);
|
||||
}
|
||||
|
||||
protected:
|
||||
int measured_bps_ = kInvalidBitrate;
|
||||
ProbeBitrateEstimator probe_bitrate_estimator_;
|
||||
};
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, OneCluster) {
|
||||
AddPacketFeedback(0, 1000, 0, 10);
|
||||
AddPacketFeedback(0, 1000, 10, 20);
|
||||
AddPacketFeedback(0, 1000, 20, 30);
|
||||
AddPacketFeedback(0, 1000, 30, 40);
|
||||
|
||||
EXPECT_NEAR(measured_bps_, 800000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, OneClusterTooFewProbes) {
|
||||
AddPacketFeedback(0, 2000, 0, 10);
|
||||
AddPacketFeedback(0, 2000, 10, 20);
|
||||
AddPacketFeedback(0, 2000, 20, 30);
|
||||
|
||||
EXPECT_EQ(kInvalidBitrate, measured_bps_);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, OneClusterTooFewBytes) {
|
||||
const int kMinBytes = 6000;
|
||||
AddPacketFeedback(0, 800, 0, 10, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 800, 10, 20, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 800, 20, 30, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 800, 30, 40, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 800, 40, 50, kDefaultMinProbes, kMinBytes);
|
||||
|
||||
EXPECT_EQ(kInvalidBitrate, measured_bps_);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, SmallCluster) {
|
||||
const int kMinBytes = 1000;
|
||||
AddPacketFeedback(0, 150, 0, 10, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 150, 10, 20, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 150, 20, 30, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 150, 30, 40, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 150, 40, 50, kDefaultMinProbes, kMinBytes);
|
||||
AddPacketFeedback(0, 150, 50, 60, kDefaultMinProbes, kMinBytes);
|
||||
EXPECT_NEAR(measured_bps_, 120000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, LargeCluster) {
|
||||
const int kMinProbes = 30;
|
||||
const int kMinBytes = 312500;
|
||||
|
||||
int64_t send_time = 0;
|
||||
int64_t receive_time = 5;
|
||||
for (int i = 0; i < 25; ++i) {
|
||||
AddPacketFeedback(0, 12500, send_time, receive_time, kMinProbes, kMinBytes);
|
||||
++send_time;
|
||||
++receive_time;
|
||||
}
|
||||
EXPECT_NEAR(measured_bps_, 100000000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, FastReceive) {
|
||||
AddPacketFeedback(0, 1000, 0, 15);
|
||||
AddPacketFeedback(0, 1000, 10, 30);
|
||||
AddPacketFeedback(0, 1000, 20, 35);
|
||||
AddPacketFeedback(0, 1000, 30, 40);
|
||||
|
||||
EXPECT_NEAR(measured_bps_, 800000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, TooFastReceive) {
|
||||
AddPacketFeedback(0, 1000, 0, 19);
|
||||
AddPacketFeedback(0, 1000, 10, 22);
|
||||
AddPacketFeedback(0, 1000, 20, 25);
|
||||
AddPacketFeedback(0, 1000, 40, 27);
|
||||
|
||||
EXPECT_EQ(measured_bps_, kInvalidBitrate);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, SlowReceive) {
|
||||
AddPacketFeedback(0, 1000, 0, 10);
|
||||
AddPacketFeedback(0, 1000, 10, 40);
|
||||
AddPacketFeedback(0, 1000, 20, 70);
|
||||
AddPacketFeedback(0, 1000, 30, 85);
|
||||
// Expected send rate = 800 kbps, expected receive rate = 320 kbps.
|
||||
|
||||
EXPECT_NEAR(measured_bps_, kTargetUtilizationFraction * 320000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, BurstReceive) {
|
||||
AddPacketFeedback(0, 1000, 0, 50);
|
||||
AddPacketFeedback(0, 1000, 10, 50);
|
||||
AddPacketFeedback(0, 1000, 20, 50);
|
||||
AddPacketFeedback(0, 1000, 40, 50);
|
||||
|
||||
EXPECT_EQ(measured_bps_, kInvalidBitrate);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, MultipleClusters) {
|
||||
AddPacketFeedback(0, 1000, 0, 10);
|
||||
AddPacketFeedback(0, 1000, 10, 20);
|
||||
AddPacketFeedback(0, 1000, 20, 30);
|
||||
AddPacketFeedback(0, 1000, 40, 60);
|
||||
// Expected send rate = 600 kbps, expected receive rate = 480 kbps.
|
||||
EXPECT_NEAR(measured_bps_, kTargetUtilizationFraction * 480000, 10);
|
||||
|
||||
AddPacketFeedback(0, 1000, 50, 60);
|
||||
// Expected send rate = 640 kbps, expected receive rate = 640 kbps.
|
||||
EXPECT_NEAR(measured_bps_, 640000, 10);
|
||||
|
||||
AddPacketFeedback(1, 1000, 60, 70);
|
||||
AddPacketFeedback(1, 1000, 65, 77);
|
||||
AddPacketFeedback(1, 1000, 70, 84);
|
||||
AddPacketFeedback(1, 1000, 75, 90);
|
||||
// Expected send rate = 1600 kbps, expected receive rate = 1200 kbps.
|
||||
|
||||
EXPECT_NEAR(measured_bps_, kTargetUtilizationFraction * 1200000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, IgnoreOldClusters) {
|
||||
AddPacketFeedback(0, 1000, 0, 10);
|
||||
AddPacketFeedback(0, 1000, 10, 20);
|
||||
AddPacketFeedback(0, 1000, 20, 30);
|
||||
|
||||
AddPacketFeedback(1, 1000, 60, 70);
|
||||
AddPacketFeedback(1, 1000, 65, 77);
|
||||
AddPacketFeedback(1, 1000, 70, 84);
|
||||
AddPacketFeedback(1, 1000, 75, 90);
|
||||
// Expected send rate = 1600 kbps, expected receive rate = 1200 kbps.
|
||||
|
||||
EXPECT_NEAR(measured_bps_, kTargetUtilizationFraction * 1200000, 10);
|
||||
|
||||
// Coming in 6s later
|
||||
AddPacketFeedback(0, 1000, 40 + 6000, 60 + 6000);
|
||||
|
||||
EXPECT_EQ(measured_bps_, kInvalidBitrate);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, IgnoreSizeLastSendPacket) {
|
||||
AddPacketFeedback(0, 1000, 0, 10);
|
||||
AddPacketFeedback(0, 1000, 10, 20);
|
||||
AddPacketFeedback(0, 1000, 20, 30);
|
||||
AddPacketFeedback(0, 1000, 30, 40);
|
||||
AddPacketFeedback(0, 1500, 40, 50);
|
||||
// Expected send rate = 800 kbps, expected receive rate = 900 kbps.
|
||||
|
||||
EXPECT_NEAR(measured_bps_, 800000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, IgnoreSizeFirstReceivePacket) {
|
||||
AddPacketFeedback(0, 1500, 0, 10);
|
||||
AddPacketFeedback(0, 1000, 10, 20);
|
||||
AddPacketFeedback(0, 1000, 20, 30);
|
||||
AddPacketFeedback(0, 1000, 30, 40);
|
||||
// Expected send rate = 933 kbps, expected receive rate = 800 kbps.
|
||||
|
||||
EXPECT_NEAR(measured_bps_, kTargetUtilizationFraction * 800000, 10);
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, NoLastEstimatedBitrateBps) {
|
||||
EXPECT_FALSE(probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps());
|
||||
}
|
||||
|
||||
TEST_F(LegacyTestProbeBitrateEstimator, FetchLastEstimatedBitrateBps) {
|
||||
AddPacketFeedback(0, 1000, 0, 10);
|
||||
AddPacketFeedback(0, 1000, 10, 20);
|
||||
AddPacketFeedback(0, 1000, 20, 30);
|
||||
AddPacketFeedback(0, 1000, 30, 40);
|
||||
|
||||
auto estimated_bitrate_bps =
|
||||
probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps();
|
||||
EXPECT_TRUE(estimated_bitrate_bps);
|
||||
EXPECT_NEAR(*estimated_bitrate_bps, 800000, 10);
|
||||
EXPECT_FALSE(probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -14,7 +14,6 @@
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
void ComparePacketFeedbackVectors(const std::vector<PacketFeedback>& truth,
|
||||
const std::vector<PacketFeedback>& input) {
|
||||
ASSERT_EQ(truth.size(), input.size());
|
||||
@ -40,5 +39,4 @@ void ComparePacketFeedbackVectors(const std::vector<PacketFeedback>& truth,
|
||||
EXPECT_EQ(truth[i].pacing_info, input[i].pacing_info);
|
||||
}
|
||||
}
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -16,10 +16,8 @@
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
void ComparePacketFeedbackVectors(const std::vector<PacketFeedback>& truth,
|
||||
const std::vector<PacketFeedback>& input);
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_RTP_CONGESTION_CONTROLLER_UNITTESTS_HELPER_H_
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc_cc {
|
||||
|
||||
SendTimeHistory::SendTimeHistory(const Clock* clock,
|
||||
int64_t packet_age_limit_ms)
|
||||
@ -103,5 +102,4 @@ size_t SendTimeHistory::GetOutstandingBytes(uint16_t local_net_id,
|
||||
return outstanding_bytes;
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
@ -19,7 +19,6 @@
|
||||
namespace webrtc {
|
||||
class Clock;
|
||||
struct PacketFeedback;
|
||||
namespace webrtc_cc {
|
||||
|
||||
class SendTimeHistory {
|
||||
public:
|
||||
@ -54,6 +53,5 @@ class SendTimeHistory {
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SendTimeHistory);
|
||||
};
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_RTP_SEND_TIME_HISTORY_H_
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "modules/bitrate_controller/include/bitrate_controller.h"
|
||||
#include "modules/congestion_controller/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/probe_controller.h"
|
||||
#include "modules/pacing/alr_detector.h"
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
|
@ -8,11 +8,11 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
|
||||
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "modules/bitrate_controller/include/bitrate_controller.h"
|
||||
#include "modules/congestion_controller/congestion_controller_unittests_helper.h"
|
||||
#include "modules/congestion_controller/include/mock/mock_congestion_observer.h"
|
||||
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
|
||||
#include "modules/congestion_controller/rtp/congestion_controller_unittests_helper.h"
|
||||
#include "modules/pacing/mock/mock_paced_sender.h"
|
||||
#include "modules/pacing/packet_router.h"
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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/send_time_history.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
SendTimeHistory::SendTimeHistory(const Clock* clock,
|
||||
int64_t packet_age_limit_ms)
|
||||
: clock_(clock), packet_age_limit_ms_(packet_age_limit_ms) {}
|
||||
|
||||
SendTimeHistory::~SendTimeHistory() {}
|
||||
|
||||
void SendTimeHistory::AddAndRemoveOld(const PacketFeedback& packet) {
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
// Remove old.
|
||||
while (!history_.empty() &&
|
||||
now_ms - history_.begin()->second.creation_time_ms >
|
||||
packet_age_limit_ms_) {
|
||||
// TODO(sprang): Warn if erasing (too many) old items?
|
||||
history_.erase(history_.begin());
|
||||
}
|
||||
|
||||
// Add new.
|
||||
int64_t unwrapped_seq_num = seq_num_unwrapper_.Unwrap(packet.sequence_number);
|
||||
history_.insert(std::make_pair(unwrapped_seq_num, packet));
|
||||
}
|
||||
|
||||
bool SendTimeHistory::OnSentPacket(uint16_t sequence_number,
|
||||
int64_t send_time_ms) {
|
||||
int64_t unwrapped_seq_num = seq_num_unwrapper_.Unwrap(sequence_number);
|
||||
auto it = history_.find(unwrapped_seq_num);
|
||||
if (it == history_.end())
|
||||
return false;
|
||||
it->second.send_time_ms = send_time_ms;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SendTimeHistory::GetFeedback(PacketFeedback* packet_feedback,
|
||||
bool remove) {
|
||||
RTC_DCHECK(packet_feedback);
|
||||
int64_t unwrapped_seq_num =
|
||||
seq_num_unwrapper_.Unwrap(packet_feedback->sequence_number);
|
||||
latest_acked_seq_num_.emplace(
|
||||
std::max(unwrapped_seq_num, latest_acked_seq_num_.value_or(0)));
|
||||
RTC_DCHECK_GE(*latest_acked_seq_num_, 0);
|
||||
auto it = history_.find(unwrapped_seq_num);
|
||||
if (it == history_.end())
|
||||
return false;
|
||||
|
||||
// Save arrival_time not to overwrite it.
|
||||
int64_t arrival_time_ms = packet_feedback->arrival_time_ms;
|
||||
*packet_feedback = it->second;
|
||||
packet_feedback->arrival_time_ms = arrival_time_ms;
|
||||
|
||||
if (remove)
|
||||
history_.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t SendTimeHistory::GetOutstandingBytes(uint16_t local_net_id,
|
||||
uint16_t remote_net_id) const {
|
||||
size_t outstanding_bytes = 0;
|
||||
auto unacked_it = history_.begin();
|
||||
if (latest_acked_seq_num_) {
|
||||
unacked_it = history_.lower_bound(*latest_acked_seq_num_);
|
||||
}
|
||||
for (; unacked_it != history_.end(); ++unacked_it) {
|
||||
if (unacked_it->second.local_net_id == local_net_id &&
|
||||
unacked_it->second.remote_net_id == remote_net_id &&
|
||||
unacked_it->second.send_time_ms >= 0) {
|
||||
outstanding_bytes += unacked_it->second.payload_size;
|
||||
}
|
||||
}
|
||||
return outstanding_bytes;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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_SEND_TIME_HISTORY_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_SEND_TIME_HISTORY_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "modules/include/module_common_types.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
class Clock;
|
||||
struct PacketFeedback;
|
||||
|
||||
class SendTimeHistory {
|
||||
public:
|
||||
SendTimeHistory(const Clock* clock, int64_t packet_age_limit_ms);
|
||||
~SendTimeHistory();
|
||||
|
||||
// Cleanup old entries, then add new packet info with provided parameters.
|
||||
void AddAndRemoveOld(const PacketFeedback& packet);
|
||||
|
||||
// Updates packet info identified by |sequence_number| with |send_time_ms|.
|
||||
// Return false if not found.
|
||||
bool OnSentPacket(uint16_t sequence_number, int64_t send_time_ms);
|
||||
|
||||
// Look up PacketFeedback for a sent packet, based on the sequence number, and
|
||||
// populate all fields except for arrival_time. The packet parameter must
|
||||
// thus be non-null and have the sequence_number field set.
|
||||
bool GetFeedback(PacketFeedback* packet_feedback, bool remove);
|
||||
|
||||
size_t GetOutstandingBytes(uint16_t local_net_id,
|
||||
uint16_t remote_net_id) const;
|
||||
|
||||
private:
|
||||
const Clock* const clock_;
|
||||
const int64_t packet_age_limit_ms_;
|
||||
SequenceNumberUnwrapper seq_num_unwrapper_;
|
||||
std::map<int64_t, PacketFeedback> history_;
|
||||
rtc::Optional<int64_t> latest_acked_seq_num_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SendTimeHistory);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_SEND_TIME_HISTORY_H_
|
@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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 <algorithm>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/congestion_controller/send_time_history.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
static const int kDefaultHistoryLengthMs = 1000;
|
||||
|
||||
class LegacySendTimeHistoryTest : public ::testing::Test {
|
||||
protected:
|
||||
LegacySendTimeHistoryTest()
|
||||
: clock_(0), history_(&clock_, kDefaultHistoryLengthMs) {}
|
||||
~LegacySendTimeHistoryTest() {}
|
||||
|
||||
virtual void SetUp() {}
|
||||
|
||||
virtual void TearDown() {}
|
||||
|
||||
void AddPacketWithSendTime(uint16_t sequence_number,
|
||||
size_t length,
|
||||
int64_t send_time_ms,
|
||||
const PacedPacketInfo& pacing_info) {
|
||||
PacketFeedback packet(clock_.TimeInMilliseconds(), sequence_number, length,
|
||||
0, 0, pacing_info);
|
||||
history_.AddAndRemoveOld(packet);
|
||||
history_.OnSentPacket(sequence_number, send_time_ms);
|
||||
}
|
||||
|
||||
webrtc::SimulatedClock clock_;
|
||||
SendTimeHistory history_;
|
||||
};
|
||||
|
||||
TEST_F(LegacySendTimeHistoryTest, SaveAndRestoreNetworkId) {
|
||||
const PacedPacketInfo kPacingInfo(0, 5, 1200);
|
||||
uint16_t sequence_number = 0;
|
||||
int64_t now_ms = clock_.TimeInMilliseconds();
|
||||
for (int i = 1; i < 5; ++i) {
|
||||
PacketFeedback packet(now_ms, sequence_number, 1000, i, i - 1,
|
||||
kPacingInfo);
|
||||
history_.AddAndRemoveOld(packet);
|
||||
history_.OnSentPacket(sequence_number, now_ms);
|
||||
PacketFeedback restored(now_ms, sequence_number);
|
||||
EXPECT_TRUE(history_.GetFeedback(&restored, sequence_number++));
|
||||
EXPECT_EQ(packet.local_net_id, restored.local_net_id);
|
||||
EXPECT_EQ(packet.remote_net_id, restored.remote_net_id);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(LegacySendTimeHistoryTest, AddRemoveOne) {
|
||||
const uint16_t kSeqNo = 10;
|
||||
// TODO(philipel): Fix PacedPacketInfo constructor?
|
||||
const PacedPacketInfo kPacingInfo(0, 5, 1200);
|
||||
const PacketFeedback kSentPacket(0, 1, kSeqNo, 1, kPacingInfo);
|
||||
AddPacketWithSendTime(kSeqNo, 1, 1, kPacingInfo);
|
||||
|
||||
PacketFeedback received_packet(0, 0, kSeqNo, 0, kPacingInfo);
|
||||
EXPECT_TRUE(history_.GetFeedback(&received_packet, false));
|
||||
EXPECT_EQ(kSentPacket, received_packet);
|
||||
|
||||
PacketFeedback received_packet2(0, 0, kSeqNo, 0, kPacingInfo);
|
||||
EXPECT_TRUE(history_.GetFeedback(&received_packet2, true));
|
||||
EXPECT_EQ(kSentPacket, received_packet2);
|
||||
|
||||
PacketFeedback received_packet3(0, 0, kSeqNo, 0, kPacingInfo);
|
||||
EXPECT_FALSE(history_.GetFeedback(&received_packet3, true));
|
||||
}
|
||||
|
||||
TEST_F(LegacySendTimeHistoryTest, PopulatesExpectedFields) {
|
||||
const uint16_t kSeqNo = 10;
|
||||
const int64_t kSendTime = 1000;
|
||||
const int64_t kReceiveTime = 2000;
|
||||
const size_t kPayloadSize = 42;
|
||||
const PacedPacketInfo kPacingInfo(3, 10, 1212);
|
||||
|
||||
AddPacketWithSendTime(kSeqNo, kPayloadSize, kSendTime, kPacingInfo);
|
||||
|
||||
PacketFeedback packet_feedback(kReceiveTime, kSeqNo);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet_feedback, true));
|
||||
EXPECT_EQ(kReceiveTime, packet_feedback.arrival_time_ms);
|
||||
EXPECT_EQ(kSendTime, packet_feedback.send_time_ms);
|
||||
EXPECT_EQ(kSeqNo, packet_feedback.sequence_number);
|
||||
EXPECT_EQ(kPayloadSize, packet_feedback.payload_size);
|
||||
EXPECT_EQ(kPacingInfo, packet_feedback.pacing_info);
|
||||
}
|
||||
|
||||
TEST_F(LegacySendTimeHistoryTest, AddThenRemoveOutOfOrder) {
|
||||
std::vector<PacketFeedback> sent_packets;
|
||||
std::vector<PacketFeedback> received_packets;
|
||||
const size_t num_items = 100;
|
||||
const size_t kPacketSize = 400;
|
||||
const size_t kTransmissionTime = 1234;
|
||||
const PacedPacketInfo kPacingInfo(1, 2, 200);
|
||||
for (size_t i = 0; i < num_items; ++i) {
|
||||
sent_packets.push_back(PacketFeedback(0, static_cast<int64_t>(i),
|
||||
static_cast<uint16_t>(i), kPacketSize,
|
||||
kPacingInfo));
|
||||
received_packets.push_back(PacketFeedback(
|
||||
static_cast<int64_t>(i) + kTransmissionTime, 0,
|
||||
static_cast<uint16_t>(i), kPacketSize, PacedPacketInfo()));
|
||||
}
|
||||
for (size_t i = 0; i < num_items; ++i) {
|
||||
PacketFeedback packet = sent_packets[i];
|
||||
packet.arrival_time_ms = PacketFeedback::kNotReceived;
|
||||
packet.send_time_ms = PacketFeedback::kNoSendTime;
|
||||
history_.AddAndRemoveOld(packet);
|
||||
}
|
||||
for (size_t i = 0; i < num_items; ++i)
|
||||
history_.OnSentPacket(sent_packets[i].sequence_number,
|
||||
sent_packets[i].send_time_ms);
|
||||
std::shuffle(received_packets.begin(), received_packets.end(),
|
||||
std::mt19937(std::random_device()()));
|
||||
for (size_t i = 0; i < num_items; ++i) {
|
||||
PacketFeedback packet = received_packets[i];
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet, false));
|
||||
PacketFeedback sent_packet = sent_packets[packet.sequence_number];
|
||||
sent_packet.arrival_time_ms = packet.arrival_time_ms;
|
||||
EXPECT_EQ(sent_packet, packet);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet, true));
|
||||
}
|
||||
for (PacketFeedback packet : sent_packets)
|
||||
EXPECT_FALSE(history_.GetFeedback(&packet, false));
|
||||
}
|
||||
|
||||
TEST_F(LegacySendTimeHistoryTest, HistorySize) {
|
||||
const int kItems = kDefaultHistoryLengthMs / 100;
|
||||
for (int i = 0; i < kItems; ++i) {
|
||||
clock_.AdvanceTimeMilliseconds(100);
|
||||
AddPacketWithSendTime(i, 0, i * 100, PacedPacketInfo());
|
||||
}
|
||||
for (int i = 0; i < kItems; ++i) {
|
||||
PacketFeedback packet(0, 0, static_cast<uint16_t>(i), 0, PacedPacketInfo());
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet, false));
|
||||
EXPECT_EQ(i * 100, packet.send_time_ms);
|
||||
}
|
||||
clock_.AdvanceTimeMilliseconds(101);
|
||||
AddPacketWithSendTime(kItems, 0, kItems * 101, PacedPacketInfo());
|
||||
PacketFeedback packet(0, 0, 0, 0, PacedPacketInfo());
|
||||
EXPECT_FALSE(history_.GetFeedback(&packet, false));
|
||||
for (int i = 1; i < (kItems + 1); ++i) {
|
||||
PacketFeedback packet2(0, 0, static_cast<uint16_t>(i), 0,
|
||||
PacedPacketInfo());
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet2, false));
|
||||
int64_t expected_time_ms = (i == kItems) ? i * 101 : i * 100;
|
||||
EXPECT_EQ(expected_time_ms, packet2.send_time_ms);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(LegacySendTimeHistoryTest, HistorySizeWithWraparound) {
|
||||
const uint16_t kMaxSeqNo = std::numeric_limits<uint16_t>::max();
|
||||
AddPacketWithSendTime(kMaxSeqNo - 2, 0, 0, PacedPacketInfo());
|
||||
|
||||
clock_.AdvanceTimeMilliseconds(100);
|
||||
AddPacketWithSendTime(kMaxSeqNo - 1, 1, 100, PacedPacketInfo());
|
||||
|
||||
clock_.AdvanceTimeMilliseconds(100);
|
||||
AddPacketWithSendTime(kMaxSeqNo, 0, 200, PacedPacketInfo());
|
||||
|
||||
clock_.AdvanceTimeMilliseconds(kDefaultHistoryLengthMs - 200 + 1);
|
||||
AddPacketWithSendTime(0, 0, kDefaultHistoryLengthMs, PacedPacketInfo());
|
||||
|
||||
PacketFeedback packet(0, static_cast<uint16_t>(kMaxSeqNo - 2));
|
||||
EXPECT_FALSE(history_.GetFeedback(&packet, false));
|
||||
PacketFeedback packet2(0, static_cast<uint16_t>(kMaxSeqNo - 1));
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet2, false));
|
||||
PacketFeedback packet3(0, static_cast<uint16_t>(kMaxSeqNo));
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet3, false));
|
||||
PacketFeedback packet4(0, 0);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet4, false));
|
||||
|
||||
// Create a gap (kMaxSeqNo - 1) -> 0.
|
||||
PacketFeedback packet5(0, kMaxSeqNo);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet5, true));
|
||||
|
||||
clock_.AdvanceTimeMilliseconds(100);
|
||||
AddPacketWithSendTime(1, 0, 1100, PacedPacketInfo());
|
||||
|
||||
PacketFeedback packet6(0, static_cast<uint16_t>(kMaxSeqNo - 2));
|
||||
EXPECT_FALSE(history_.GetFeedback(&packet6, false));
|
||||
PacketFeedback packet7(0, static_cast<uint16_t>(kMaxSeqNo - 1));
|
||||
EXPECT_FALSE(history_.GetFeedback(&packet7, false));
|
||||
PacketFeedback packet8(0, kMaxSeqNo);
|
||||
EXPECT_FALSE(history_.GetFeedback(&packet8, false));
|
||||
PacketFeedback packet9(0, 0);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet9, false));
|
||||
PacketFeedback packet10(0, 1);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet10, false));
|
||||
}
|
||||
|
||||
TEST_F(LegacySendTimeHistoryTest, InterlievedGetAndRemove) {
|
||||
const uint16_t kSeqNo = 1;
|
||||
const int64_t kTimestamp = 2;
|
||||
const PacedPacketInfo kPacingInfo1(1, 1, 100);
|
||||
const PacedPacketInfo kPacingInfo2(2, 2, 200);
|
||||
const PacedPacketInfo kPacingInfo3(3, 3, 300);
|
||||
PacketFeedback packets[3] = {
|
||||
{0, kTimestamp, kSeqNo, 0, kPacingInfo1},
|
||||
{0, kTimestamp + 1, kSeqNo + 1, 0, kPacingInfo2},
|
||||
{0, kTimestamp + 2, kSeqNo + 2, 0, kPacingInfo3}};
|
||||
|
||||
AddPacketWithSendTime(packets[0].sequence_number, packets[0].payload_size,
|
||||
packets[0].send_time_ms, packets[0].pacing_info);
|
||||
AddPacketWithSendTime(packets[1].sequence_number, packets[1].payload_size,
|
||||
packets[1].send_time_ms, packets[1].pacing_info);
|
||||
PacketFeedback packet(0, 0, packets[0].sequence_number, 0, PacedPacketInfo());
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet, true));
|
||||
EXPECT_EQ(packets[0], packet);
|
||||
|
||||
AddPacketWithSendTime(packets[2].sequence_number, packets[2].payload_size,
|
||||
packets[2].send_time_ms, packets[2].pacing_info);
|
||||
|
||||
PacketFeedback packet2(0, 0, packets[1].sequence_number, 0, kPacingInfo1);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet2, true));
|
||||
EXPECT_EQ(packets[1], packet2);
|
||||
|
||||
PacketFeedback packet3(0, 0, packets[2].sequence_number, 0, kPacingInfo2);
|
||||
EXPECT_TRUE(history_.GetFeedback(&packet3, true));
|
||||
EXPECT_EQ(packets[2], packet3);
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -14,7 +14,7 @@
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/congestion_controller/send_time_history.h"
|
||||
#include "modules/congestion_controller/rtp/send_time_history.h"
|
||||
#include "rtc_base/criticalsection.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
#include "rtc_base/thread_checker.h"
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
|
||||
#include "modules/congestion_controller/congestion_controller_unittests_helper.h"
|
||||
#include "modules/congestion_controller/rtp/congestion_controller_unittests_helper.h"
|
||||
#include "modules/congestion_controller/transport_feedback_adapter.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
|
||||
|
@ -1,183 +0,0 @@
|
||||
/*
|
||||
* 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/congestion_controller/trendline_estimator.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "api/optional.h"
|
||||
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/numerics/safe_minmax.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
rtc::Optional<double> LinearFitSlope(
|
||||
const std::deque<std::pair<double, double>>& points) {
|
||||
RTC_DCHECK(points.size() >= 2);
|
||||
// Compute the "center of mass".
|
||||
double sum_x = 0;
|
||||
double sum_y = 0;
|
||||
for (const auto& point : points) {
|
||||
sum_x += point.first;
|
||||
sum_y += point.second;
|
||||
}
|
||||
double x_avg = sum_x / points.size();
|
||||
double y_avg = sum_y / points.size();
|
||||
// Compute the slope k = \sum (x_i-x_avg)(y_i-y_avg) / \sum (x_i-x_avg)^2
|
||||
double numerator = 0;
|
||||
double denominator = 0;
|
||||
for (const auto& point : points) {
|
||||
numerator += (point.first - x_avg) * (point.second - y_avg);
|
||||
denominator += (point.first - x_avg) * (point.first - x_avg);
|
||||
}
|
||||
if (denominator == 0)
|
||||
return rtc::nullopt;
|
||||
return numerator / denominator;
|
||||
}
|
||||
|
||||
constexpr double kMaxAdaptOffsetMs = 15.0;
|
||||
constexpr double kOverUsingTimeThreshold = 10;
|
||||
constexpr int kMinNumDeltas = 60;
|
||||
|
||||
} // namespace
|
||||
|
||||
enum { kDeltaCounterMax = 1000 };
|
||||
|
||||
TrendlineEstimator::TrendlineEstimator(size_t window_size,
|
||||
double smoothing_coef,
|
||||
double threshold_gain)
|
||||
: window_size_(window_size),
|
||||
smoothing_coef_(smoothing_coef),
|
||||
threshold_gain_(threshold_gain),
|
||||
num_of_deltas_(0),
|
||||
first_arrival_time_ms_(-1),
|
||||
accumulated_delay_(0),
|
||||
smoothed_delay_(0),
|
||||
delay_hist_(),
|
||||
trendline_(0),
|
||||
k_up_(0.0087),
|
||||
k_down_(0.039),
|
||||
overusing_time_threshold_(kOverUsingTimeThreshold),
|
||||
threshold_(12.5),
|
||||
last_update_ms_(-1),
|
||||
prev_offset_(0.0),
|
||||
time_over_using_(-1),
|
||||
overuse_counter_(0),
|
||||
hypothesis_(BandwidthUsage::kBwNormal) {}
|
||||
|
||||
TrendlineEstimator::~TrendlineEstimator() {}
|
||||
|
||||
void TrendlineEstimator::Update(double recv_delta_ms,
|
||||
double send_delta_ms,
|
||||
int64_t arrival_time_ms) {
|
||||
const double delta_ms = recv_delta_ms - send_delta_ms;
|
||||
++num_of_deltas_;
|
||||
if (num_of_deltas_ > kDeltaCounterMax)
|
||||
num_of_deltas_ = kDeltaCounterMax;
|
||||
if (first_arrival_time_ms_ == -1)
|
||||
first_arrival_time_ms_ = arrival_time_ms;
|
||||
|
||||
// Exponential backoff filter.
|
||||
accumulated_delay_ += delta_ms;
|
||||
BWE_TEST_LOGGING_PLOT(1, "accumulated_delay_ms", arrival_time_ms,
|
||||
accumulated_delay_);
|
||||
smoothed_delay_ = smoothing_coef_ * smoothed_delay_ +
|
||||
(1 - smoothing_coef_) * accumulated_delay_;
|
||||
BWE_TEST_LOGGING_PLOT(1, "smoothed_delay_ms", arrival_time_ms,
|
||||
smoothed_delay_);
|
||||
|
||||
// Simple linear regression.
|
||||
delay_hist_.push_back(std::make_pair(
|
||||
static_cast<double>(arrival_time_ms - first_arrival_time_ms_),
|
||||
smoothed_delay_));
|
||||
if (delay_hist_.size() > window_size_)
|
||||
delay_hist_.pop_front();
|
||||
if (delay_hist_.size() == window_size_) {
|
||||
// Only update trendline_ if it is possible to fit a line to the data.
|
||||
trendline_ = LinearFitSlope(delay_hist_).value_or(trendline_);
|
||||
}
|
||||
|
||||
BWE_TEST_LOGGING_PLOT(1, "trendline_slope", arrival_time_ms, trendline_);
|
||||
|
||||
Detect(trendline_slope(), send_delta_ms, num_of_deltas(), arrival_time_ms);
|
||||
}
|
||||
|
||||
BandwidthUsage TrendlineEstimator::State() const {
|
||||
return hypothesis_;
|
||||
}
|
||||
|
||||
void TrendlineEstimator::Detect(double offset,
|
||||
double ts_delta,
|
||||
int num_of_deltas,
|
||||
int64_t now_ms) {
|
||||
if (num_of_deltas < 2) {
|
||||
hypothesis_ = BandwidthUsage::kBwNormal;
|
||||
return;
|
||||
}
|
||||
const double T = std::min(num_of_deltas, kMinNumDeltas) * offset;
|
||||
BWE_TEST_LOGGING_PLOT(1, "T", now_ms, T);
|
||||
BWE_TEST_LOGGING_PLOT(1, "threshold", now_ms, threshold_);
|
||||
if (T > threshold_) {
|
||||
if (time_over_using_ == -1) {
|
||||
// Initialize the timer. Assume that we've been
|
||||
// over-using half of the time since the previous
|
||||
// sample.
|
||||
time_over_using_ = ts_delta / 2;
|
||||
} else {
|
||||
// Increment timer
|
||||
time_over_using_ += ts_delta;
|
||||
}
|
||||
overuse_counter_++;
|
||||
if (time_over_using_ > overusing_time_threshold_ && overuse_counter_ > 1) {
|
||||
if (offset >= prev_offset_) {
|
||||
time_over_using_ = 0;
|
||||
overuse_counter_ = 0;
|
||||
hypothesis_ = BandwidthUsage::kBwOverusing;
|
||||
}
|
||||
}
|
||||
} else if (T < -threshold_) {
|
||||
time_over_using_ = -1;
|
||||
overuse_counter_ = 0;
|
||||
hypothesis_ = BandwidthUsage::kBwUnderusing;
|
||||
} else {
|
||||
time_over_using_ = -1;
|
||||
overuse_counter_ = 0;
|
||||
hypothesis_ = BandwidthUsage::kBwNormal;
|
||||
}
|
||||
prev_offset_ = offset;
|
||||
|
||||
UpdateThreshold(T, now_ms);
|
||||
}
|
||||
|
||||
void TrendlineEstimator::UpdateThreshold(double modified_offset,
|
||||
int64_t now_ms) {
|
||||
if (last_update_ms_ == -1)
|
||||
last_update_ms_ = now_ms;
|
||||
|
||||
if (fabs(modified_offset) > threshold_ + kMaxAdaptOffsetMs) {
|
||||
// Avoid adapting the threshold to big latency spikes, caused e.g.,
|
||||
// by a sudden capacity drop.
|
||||
last_update_ms_ = now_ms;
|
||||
return;
|
||||
}
|
||||
|
||||
const double k = fabs(modified_offset) < threshold_ ? k_down_ : k_up_;
|
||||
const int64_t kMaxTimeDeltaMs = 100;
|
||||
int64_t time_delta_ms = std::min(now_ms - last_update_ms_, kMaxTimeDeltaMs);
|
||||
threshold_ += k * (fabs(modified_offset) - threshold_) * time_delta_ms;
|
||||
threshold_ = rtc::SafeClamp(threshold_, 6.f, 600.f);
|
||||
last_update_ms_ = now_ms;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_TRENDLINE_ESTIMATOR_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_TRENDLINE_ESTIMATOR_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <deque>
|
||||
#include <utility>
|
||||
|
||||
#include "modules/congestion_controller/delay_increase_detector_interface.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class TrendlineEstimator : public DelayIncreaseDetectorInterface {
|
||||
public:
|
||||
// |window_size| is the number of points required to compute a trend line.
|
||||
// |smoothing_coef| controls how much we smooth out the delay before fitting
|
||||
// the trend line. |threshold_gain| is used to scale the trendline slope for
|
||||
// comparison to the old threshold. Once the old estimator has been removed
|
||||
// (or the thresholds been merged into the estimators), we can just set the
|
||||
// threshold instead of setting a gain.
|
||||
TrendlineEstimator(size_t window_size,
|
||||
double smoothing_coef,
|
||||
double threshold_gain);
|
||||
|
||||
~TrendlineEstimator() override;
|
||||
|
||||
// Update the estimator with a new sample. The deltas should represent deltas
|
||||
// between timestamp groups as defined by the InterArrival class.
|
||||
void Update(double recv_delta_ms,
|
||||
double send_delta_ms,
|
||||
int64_t arrival_time_ms) override;
|
||||
|
||||
BandwidthUsage State() const override;
|
||||
|
||||
// Returns the estimated trend k multiplied by some gain.
|
||||
// 0 < k < 1 -> the delay increases, queues are filling up
|
||||
// k == 0 -> the delay does not change
|
||||
// k < 0 -> the delay decreases, queues are being emptied
|
||||
double trendline_slope() const { return trendline_ * threshold_gain_; }
|
||||
|
||||
// Returns the number of deltas which the current estimator state is based on.
|
||||
unsigned int num_of_deltas() const { return num_of_deltas_; }
|
||||
|
||||
private:
|
||||
void Detect(double offset,
|
||||
double ts_delta,
|
||||
int num_of_deltas,
|
||||
int64_t now_ms);
|
||||
|
||||
void UpdateThreshold(double modified_offset, int64_t now_ms);
|
||||
|
||||
// Parameters.
|
||||
const size_t window_size_;
|
||||
const double smoothing_coef_;
|
||||
const double threshold_gain_;
|
||||
// Used by the existing threshold.
|
||||
unsigned int num_of_deltas_;
|
||||
// Keep the arrival times small by using the change from the first packet.
|
||||
int64_t first_arrival_time_ms_;
|
||||
// Exponential backoff filtering.
|
||||
double accumulated_delay_;
|
||||
double smoothed_delay_;
|
||||
// Linear least squares regression.
|
||||
std::deque<std::pair<double, double>> delay_hist_;
|
||||
double trendline_;
|
||||
|
||||
const double k_up_;
|
||||
const double k_down_;
|
||||
double overusing_time_threshold_;
|
||||
double threshold_;
|
||||
int64_t last_update_ms_;
|
||||
double prev_offset_;
|
||||
double time_over_using_;
|
||||
int overuse_counter_;
|
||||
BandwidthUsage hypothesis_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(TrendlineEstimator);
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_TRENDLINE_ESTIMATOR_H_
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* 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/congestion_controller/trendline_estimator.h"
|
||||
#include "rtc_base/random.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
constexpr size_t kWindowSize = 20;
|
||||
constexpr double kSmoothing = 0.0;
|
||||
constexpr double kGain = 1;
|
||||
constexpr int64_t kAvgTimeBetweenPackets = 10;
|
||||
constexpr size_t kPacketCount = 2 * kWindowSize + 1;
|
||||
|
||||
void TestEstimator(double slope, double jitter_stddev, double tolerance) {
|
||||
TrendlineEstimator estimator(kWindowSize, kSmoothing, kGain);
|
||||
Random random(0x1234567);
|
||||
int64_t send_times[kPacketCount];
|
||||
int64_t recv_times[kPacketCount];
|
||||
int64_t send_start_time = random.Rand(1000000);
|
||||
int64_t recv_start_time = random.Rand(1000000);
|
||||
for (size_t i = 0; i < kPacketCount; ++i) {
|
||||
send_times[i] = send_start_time + i * kAvgTimeBetweenPackets;
|
||||
double latency = i * kAvgTimeBetweenPackets / (1 - slope);
|
||||
double jitter = random.Gaussian(0, jitter_stddev);
|
||||
recv_times[i] = recv_start_time + latency + jitter;
|
||||
}
|
||||
for (size_t i = 1; i < kPacketCount; ++i) {
|
||||
double recv_delta = recv_times[i] - recv_times[i - 1];
|
||||
double send_delta = send_times[i] - send_times[i - 1];
|
||||
estimator.Update(recv_delta, send_delta, recv_times[i]);
|
||||
if (i < kWindowSize)
|
||||
EXPECT_NEAR(estimator.trendline_slope(), 0, 0.001);
|
||||
else
|
||||
EXPECT_NEAR(estimator.trendline_slope(), slope, tolerance);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(LegacyTrendlineEstimator, PerfectLineSlopeOneHalf) {
|
||||
TestEstimator(0.5, 0, 0.001);
|
||||
}
|
||||
|
||||
TEST(LegacyTrendlineEstimator, PerfectLineSlopeMinusOne) {
|
||||
TestEstimator(-1, 0, 0.001);
|
||||
}
|
||||
|
||||
TEST(LegacyTrendlineEstimator, PerfectLineSlopeZero) {
|
||||
TestEstimator(0, 0, 0.001);
|
||||
}
|
||||
|
||||
TEST(LegacyTrendlineEstimator, JitteryLineSlopeOneHalf) {
|
||||
TestEstimator(0.5, kAvgTimeBetweenPackets / 3.0, 0.01);
|
||||
}
|
||||
|
||||
TEST(LegacyTrendlineEstimator, JitteryLineSlopeMinusOne) {
|
||||
TestEstimator(-1, kAvgTimeBetweenPackets / 3.0, 0.075);
|
||||
}
|
||||
|
||||
TEST(LegacyTrendlineEstimator, JitteryLineSlopeZero) {
|
||||
TestEstimator(0, kAvgTimeBetweenPackets / 3.0, 0.02);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -153,8 +153,9 @@ if (rtc_include_tests) {
|
||||
"../bitrate_controller",
|
||||
"../congestion_controller",
|
||||
"../congestion_controller:delay_based_bwe",
|
||||
"../congestion_controller:estimators",
|
||||
"../congestion_controller:transport_feedback",
|
||||
"../congestion_controller/goog_cc:estimators",
|
||||
"../congestion_controller/rtp:transport_feedback",
|
||||
"../pacing",
|
||||
"../rtp_rtcp",
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "modules/congestion_controller/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/send_time_history.h"
|
||||
#include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/rtp/send_time_history.h"
|
||||
#include "modules/remote_bitrate_estimator/test/bwe.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -243,7 +243,7 @@ if (!build_with_chromium) {
|
||||
"../api/audio_codecs:audio_codecs_api",
|
||||
"../modules/congestion_controller",
|
||||
"../modules/congestion_controller:delay_based_bwe",
|
||||
"../modules/congestion_controller:estimators",
|
||||
"../modules/congestion_controller/goog_cc:estimators",
|
||||
"../modules/pacing",
|
||||
"../modules/rtp_rtcp",
|
||||
"../system_wrappers:system_wrappers_default",
|
||||
|
@ -31,9 +31,9 @@
|
||||
#include "modules/audio_coding/neteq/tools/neteq_replacement_input.h"
|
||||
#include "modules/audio_coding/neteq/tools/neteq_test.h"
|
||||
#include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
|
||||
#include "modules/congestion_controller/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/delay_based_bwe.h"
|
||||
#include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/goog_cc/bitrate_estimator.h"
|
||||
#include "modules/congestion_controller/include/receive_side_congestion_controller.h"
|
||||
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
|
||||
#include "modules/include/module_common_types.h"
|
||||
|
Reference in New Issue
Block a user