Removes redundant delay based bwe.
This removes the legacy DelayBasedBwe to reduce code redundancy and avoid the risk of applying changes on only one version. Bug: webrtc:8415 Change-Id: I88aba03adbb77ee0ff0a97a8b3be6ddf028af48a Reviewed-on: https://webrtc-review.googlesource.com/85364 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23798}
This commit is contained in:
committed by
Commit Bot
parent
e0eda662ef
commit
04b18cb365
@ -37,7 +37,7 @@ rtc_static_library("bitrate_controller") {
|
|||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
"../../system_wrappers:field_trial_api",
|
"../../system_wrappers:field_trial_api",
|
||||||
"../../system_wrappers:metrics_api",
|
"../../system_wrappers:metrics_api",
|
||||||
"../congestion_controller:delay_based_bwe",
|
"../congestion_controller/goog_cc:delay_based_bwe",
|
||||||
"../pacing",
|
"../pacing",
|
||||||
"../remote_bitrate_estimator:remote_bitrate_estimator",
|
"../remote_bitrate_estimator:remote_bitrate_estimator",
|
||||||
"../rtp_rtcp",
|
"../rtp_rtcp",
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "modules/congestion_controller/delay_based_bwe.h"
|
#include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
|
||||||
#include "modules/include/module.h"
|
#include "modules/include/module.h"
|
||||||
#include "modules/pacing/paced_sender.h"
|
#include "modules/pacing/paced_sender.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
|
|||||||
@ -36,7 +36,6 @@ rtc_static_library("congestion_controller") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":delay_based_bwe",
|
|
||||||
":transport_feedback",
|
":transport_feedback",
|
||||||
"..:module_api",
|
"..:module_api",
|
||||||
"../..:webrtc_common",
|
"../..:webrtc_common",
|
||||||
@ -50,6 +49,7 @@ rtc_static_library("congestion_controller") {
|
|||||||
"../pacing",
|
"../pacing",
|
||||||
"../remote_bitrate_estimator",
|
"../remote_bitrate_estimator",
|
||||||
"../rtp_rtcp:rtp_rtcp_format",
|
"../rtp_rtcp:rtp_rtcp_format",
|
||||||
|
"goog_cc:delay_based_bwe",
|
||||||
"goog_cc:estimators",
|
"goog_cc:estimators",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -75,39 +75,11 @@ rtc_static_library("transport_feedback") {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_source_set("delay_based_bwe") {
|
|
||||||
configs += [ ":bwe_test_logging" ]
|
|
||||||
sources = [
|
|
||||||
"delay_based_bwe.cc",
|
|
||||||
"delay_based_bwe.h",
|
|
||||||
]
|
|
||||||
deps = [
|
|
||||||
"../../:typedefs",
|
|
||||||
"../../logging:rtc_event_bwe",
|
|
||||||
"../../logging:rtc_event_log_api",
|
|
||||||
"../../rtc_base:checks",
|
|
||||||
"../../rtc_base:rtc_base_approved",
|
|
||||||
"../../system_wrappers:field_trial_api",
|
|
||||||
"../../system_wrappers:metrics_api",
|
|
||||||
"../pacing",
|
|
||||||
"../remote_bitrate_estimator",
|
|
||||||
"goog_cc:estimators",
|
|
||||||
]
|
|
||||||
|
|
||||||
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" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rtc_include_tests) {
|
if (rtc_include_tests) {
|
||||||
rtc_source_set("congestion_controller_unittests") {
|
rtc_source_set("congestion_controller_unittests") {
|
||||||
testonly = true
|
testonly = true
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
"delay_based_bwe_unittest.cc",
|
|
||||||
"delay_based_bwe_unittest_helper.cc",
|
|
||||||
"delay_based_bwe_unittest_helper.h",
|
|
||||||
"probe_controller_unittest.cc",
|
"probe_controller_unittest.cc",
|
||||||
"receive_side_congestion_controller_unittest.cc",
|
"receive_side_congestion_controller_unittest.cc",
|
||||||
"send_side_congestion_controller_unittest.cc",
|
"send_side_congestion_controller_unittest.cc",
|
||||||
@ -115,7 +87,6 @@ if (rtc_include_tests) {
|
|||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
":congestion_controller",
|
":congestion_controller",
|
||||||
":delay_based_bwe",
|
|
||||||
":mock_congestion_controller",
|
":mock_congestion_controller",
|
||||||
":transport_feedback",
|
":transport_feedback",
|
||||||
"../../logging:mocks",
|
"../../logging:mocks",
|
||||||
|
|||||||
@ -1,324 +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/delay_based_bwe.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#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/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"
|
|
||||||
#include "rtc_base/checks.h"
|
|
||||||
#include "rtc_base/constructormagic.h"
|
|
||||||
#include "rtc_base/logging.h"
|
|
||||||
#include "rtc_base/ptr_util.h"
|
|
||||||
#include "rtc_base/thread_annotations.h"
|
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
#include "system_wrappers/include/metrics.h"
|
|
||||||
#include "typedefs.h" // NOLINT(build/include)
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
constexpr int kTimestampGroupLengthMs = 5;
|
|
||||||
constexpr int kAbsSendTimeFraction = 18;
|
|
||||||
constexpr int kAbsSendTimeInterArrivalUpshift = 8;
|
|
||||||
constexpr int kInterArrivalShift =
|
|
||||||
kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift;
|
|
||||||
constexpr double kTimestampToMs =
|
|
||||||
1000.0 / static_cast<double>(1 << kInterArrivalShift);
|
|
||||||
// This ssrc is used to fulfill the current API but will be removed
|
|
||||||
// after the API has been changed.
|
|
||||||
constexpr uint32_t kFixedSsrc = 0;
|
|
||||||
|
|
||||||
// Parameters for linear least squares fit of regression line to noisy data.
|
|
||||||
constexpr size_t kDefaultTrendlineWindowSize = 20;
|
|
||||||
constexpr double kDefaultTrendlineSmoothingCoeff = 0.9;
|
|
||||||
constexpr double kDefaultTrendlineThresholdGain = 4.0;
|
|
||||||
|
|
||||||
constexpr int kMaxConsecutiveFailedLookups = 5;
|
|
||||||
|
|
||||||
const char kBweWindowSizeInPacketsExperiment[] =
|
|
||||||
"WebRTC-BweWindowSizeInPackets";
|
|
||||||
|
|
||||||
size_t ReadTrendlineFilterWindowSize() {
|
|
||||||
std::string experiment_string =
|
|
||||||
webrtc::field_trial::FindFullName(kBweWindowSizeInPacketsExperiment);
|
|
||||||
size_t window_size;
|
|
||||||
int parsed_values =
|
|
||||||
sscanf(experiment_string.c_str(), "Enabled-%zu", &window_size);
|
|
||||||
if (parsed_values == 1) {
|
|
||||||
if (window_size > 1)
|
|
||||||
return window_size;
|
|
||||||
RTC_LOG(WARNING) << "Window size must be greater than 1.";
|
|
||||||
}
|
|
||||||
RTC_LOG(LS_WARNING) << "Failed to parse parameters for BweTrendlineFilter "
|
|
||||||
"experiment from field trial string. Using default.";
|
|
||||||
return kDefaultTrendlineWindowSize;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
DelayBasedBwe::Result::Result()
|
|
||||||
: updated(false),
|
|
||||||
probe(false),
|
|
||||||
target_bitrate_bps(0),
|
|
||||||
recovered_from_overuse(false) {}
|
|
||||||
|
|
||||||
DelayBasedBwe::Result::Result(bool probe, uint32_t target_bitrate_bps)
|
|
||||||
: updated(true),
|
|
||||||
probe(probe),
|
|
||||||
target_bitrate_bps(target_bitrate_bps),
|
|
||||||
recovered_from_overuse(false) {}
|
|
||||||
|
|
||||||
DelayBasedBwe::Result::~Result() {}
|
|
||||||
|
|
||||||
DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock)
|
|
||||||
: event_log_(event_log),
|
|
||||||
clock_(clock),
|
|
||||||
inter_arrival_(),
|
|
||||||
delay_detector_(),
|
|
||||||
last_seen_packet_ms_(-1),
|
|
||||||
uma_recorded_(false),
|
|
||||||
probe_bitrate_estimator_(event_log),
|
|
||||||
trendline_window_size_(
|
|
||||||
webrtc::field_trial::IsEnabled(kBweWindowSizeInPacketsExperiment)
|
|
||||||
? ReadTrendlineFilterWindowSize()
|
|
||||||
: kDefaultTrendlineWindowSize),
|
|
||||||
trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff),
|
|
||||||
trendline_threshold_gain_(kDefaultTrendlineThresholdGain),
|
|
||||||
consecutive_delayed_feedbacks_(0),
|
|
||||||
prev_bitrate_(0),
|
|
||||||
prev_state_(BandwidthUsage::kBwNormal) {
|
|
||||||
RTC_LOG(LS_INFO)
|
|
||||||
<< "Using Trendline filter for delay change estimation with window size "
|
|
||||||
<< trendline_window_size_;
|
|
||||||
delay_detector_.reset(new TrendlineEstimator(trendline_window_size_,
|
|
||||||
trendline_smoothing_coeff_,
|
|
||||||
trendline_threshold_gain_));
|
|
||||||
}
|
|
||||||
|
|
||||||
DelayBasedBwe::~DelayBasedBwe() {}
|
|
||||||
|
|
||||||
DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
|
|
||||||
const std::vector<PacketFeedback>& packet_feedback_vector,
|
|
||||||
absl::optional<uint32_t> acked_bitrate_bps) {
|
|
||||||
RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(),
|
|
||||||
packet_feedback_vector.end(),
|
|
||||||
PacketFeedbackComparator()));
|
|
||||||
RTC_DCHECK_RUNS_SERIALIZED(&network_race_);
|
|
||||||
|
|
||||||
// TOOD(holmer): An empty feedback vector here likely means that
|
|
||||||
// all acks were too late and that the send time history had
|
|
||||||
// timed out. We should reduce the rate when this occurs.
|
|
||||||
if (packet_feedback_vector.empty()) {
|
|
||||||
RTC_LOG(LS_WARNING) << "Very late feedback received.";
|
|
||||||
return DelayBasedBwe::Result();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uma_recorded_) {
|
|
||||||
RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
|
|
||||||
BweNames::kSendSideTransportSeqNum,
|
|
||||||
BweNames::kBweNamesMax);
|
|
||||||
uma_recorded_ = true;
|
|
||||||
}
|
|
||||||
bool delayed_feedback = true;
|
|
||||||
bool recovered_from_overuse = false;
|
|
||||||
BandwidthUsage prev_detector_state = delay_detector_->State();
|
|
||||||
for (const auto& packet_feedback : packet_feedback_vector) {
|
|
||||||
if (packet_feedback.send_time_ms < 0)
|
|
||||||
continue;
|
|
||||||
delayed_feedback = false;
|
|
||||||
IncomingPacketFeedback(packet_feedback);
|
|
||||||
if (prev_detector_state == BandwidthUsage::kBwUnderusing &&
|
|
||||||
delay_detector_->State() == BandwidthUsage::kBwNormal) {
|
|
||||||
recovered_from_overuse = true;
|
|
||||||
}
|
|
||||||
prev_detector_state = delay_detector_->State();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delayed_feedback) {
|
|
||||||
++consecutive_delayed_feedbacks_;
|
|
||||||
if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) {
|
|
||||||
consecutive_delayed_feedbacks_ = 0;
|
|
||||||
return OnLongFeedbackDelay(packet_feedback_vector.back().arrival_time_ms);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
consecutive_delayed_feedbacks_ = 0;
|
|
||||||
return MaybeUpdateEstimate(acked_bitrate_bps, recovered_from_overuse);
|
|
||||||
}
|
|
||||||
return Result();
|
|
||||||
}
|
|
||||||
|
|
||||||
DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay(
|
|
||||||
int64_t arrival_time_ms) {
|
|
||||||
// Estimate should always be valid since a start bitrate always is set in the
|
|
||||||
// Call constructor. An alternative would be to return an empty Result here,
|
|
||||||
// or to estimate the throughput based on the feedback we received.
|
|
||||||
RTC_DCHECK(rate_control_.ValidEstimate());
|
|
||||||
rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2,
|
|
||||||
arrival_time_ms);
|
|
||||||
Result result;
|
|
||||||
result.updated = true;
|
|
||||||
result.probe = false;
|
|
||||||
result.target_bitrate_bps = rate_control_.LatestEstimate();
|
|
||||||
RTC_LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to "
|
|
||||||
<< result.target_bitrate_bps;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayBasedBwe::IncomingPacketFeedback(
|
|
||||||
const PacketFeedback& packet_feedback) {
|
|
||||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
|
||||||
// Reset if the stream has timed out.
|
|
||||||
if (last_seen_packet_ms_ == -1 ||
|
|
||||||
now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) {
|
|
||||||
inter_arrival_.reset(
|
|
||||||
new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
|
|
||||||
kTimestampToMs, true));
|
|
||||||
delay_detector_.reset(new TrendlineEstimator(trendline_window_size_,
|
|
||||||
trendline_smoothing_coeff_,
|
|
||||||
trendline_threshold_gain_));
|
|
||||||
}
|
|
||||||
last_seen_packet_ms_ = now_ms;
|
|
||||||
|
|
||||||
uint32_t send_time_24bits =
|
|
||||||
static_cast<uint32_t>(
|
|
||||||
((static_cast<uint64_t>(packet_feedback.send_time_ms)
|
|
||||||
<< kAbsSendTimeFraction) +
|
|
||||||
500) /
|
|
||||||
1000) &
|
|
||||||
0x00FFFFFF;
|
|
||||||
// Shift up send time to use the full 32 bits that inter_arrival works with,
|
|
||||||
// so wrapping works properly.
|
|
||||||
uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
|
|
||||||
|
|
||||||
uint32_t ts_delta = 0;
|
|
||||||
int64_t t_delta = 0;
|
|
||||||
int size_delta = 0;
|
|
||||||
if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms,
|
|
||||||
now_ms, packet_feedback.payload_size,
|
|
||||||
&ts_delta, &t_delta, &size_delta)) {
|
|
||||||
double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
|
|
||||||
delay_detector_->Update(t_delta, ts_delta_ms,
|
|
||||||
packet_feedback.arrival_time_ms);
|
|
||||||
}
|
|
||||||
if (packet_feedback.pacing_info.probe_cluster_id !=
|
|
||||||
PacedPacketInfo::kNotAProbe) {
|
|
||||||
probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
|
|
||||||
absl::optional<uint32_t> acked_bitrate_bps,
|
|
||||||
bool recovered_from_overuse) {
|
|
||||||
Result result;
|
|
||||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
|
||||||
|
|
||||||
absl::optional<int> probe_bitrate_bps =
|
|
||||||
probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps();
|
|
||||||
// Currently overusing the bandwidth.
|
|
||||||
if (delay_detector_->State() == BandwidthUsage::kBwOverusing) {
|
|
||||||
if (acked_bitrate_bps &&
|
|
||||||
rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) {
|
|
||||||
result.updated =
|
|
||||||
UpdateEstimate(now_ms, acked_bitrate_bps, &result.target_bitrate_bps);
|
|
||||||
} else if (!acked_bitrate_bps && rate_control_.ValidEstimate() &&
|
|
||||||
rate_control_.TimeToReduceFurther(
|
|
||||||
now_ms, rate_control_.LatestEstimate() / 2 - 1)) {
|
|
||||||
// Overusing before we have a measured acknowledged bitrate. We check
|
|
||||||
// TimeToReduceFurther (with a fake acknowledged bitrate) to avoid
|
|
||||||
// reducing too often.
|
|
||||||
// TODO(tschumim): Improve this and/or the acknowledged bitrate estimator
|
|
||||||
// so that we (almost) always have a bitrate estimate.
|
|
||||||
rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, now_ms);
|
|
||||||
result.updated = true;
|
|
||||||
result.probe = false;
|
|
||||||
result.target_bitrate_bps = rate_control_.LatestEstimate();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (probe_bitrate_bps) {
|
|
||||||
result.probe = true;
|
|
||||||
result.updated = true;
|
|
||||||
result.target_bitrate_bps = *probe_bitrate_bps;
|
|
||||||
rate_control_.SetEstimate(*probe_bitrate_bps, now_ms);
|
|
||||||
} else {
|
|
||||||
result.updated =
|
|
||||||
UpdateEstimate(now_ms, acked_bitrate_bps, &result.target_bitrate_bps);
|
|
||||||
result.recovered_from_overuse = recovered_from_overuse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BandwidthUsage detector_state = delay_detector_->State();
|
|
||||||
if ((result.updated && prev_bitrate_ != result.target_bitrate_bps) ||
|
|
||||||
detector_state != prev_state_) {
|
|
||||||
uint32_t bitrate_bps =
|
|
||||||
result.updated ? result.target_bitrate_bps : prev_bitrate_;
|
|
||||||
|
|
||||||
BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, bitrate_bps);
|
|
||||||
|
|
||||||
if (event_log_) {
|
|
||||||
event_log_->Log(rtc::MakeUnique<RtcEventBweUpdateDelayBased>(
|
|
||||||
bitrate_bps, detector_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_bitrate_ = bitrate_bps;
|
|
||||||
prev_state_ = detector_state;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DelayBasedBwe::UpdateEstimate(int64_t now_ms,
|
|
||||||
absl::optional<uint32_t> acked_bitrate_bps,
|
|
||||||
uint32_t* target_bitrate_bps) {
|
|
||||||
const RateControlInput input(delay_detector_->State(), acked_bitrate_bps);
|
|
||||||
*target_bitrate_bps = rate_control_.Update(&input, now_ms);
|
|
||||||
return rate_control_.ValidEstimate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
|
|
||||||
rate_control_.SetRtt(avg_rtt_ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
|
|
||||||
uint32_t* bitrate_bps) const {
|
|
||||||
// Currently accessed from both the process thread (see
|
|
||||||
// ModuleRtpRtcpImpl::Process()) and the configuration thread (see
|
|
||||||
// Call::GetStats()). Should in the future only be accessed from a single
|
|
||||||
// thread.
|
|
||||||
RTC_DCHECK(ssrcs);
|
|
||||||
RTC_DCHECK(bitrate_bps);
|
|
||||||
if (!rate_control_.ValidEstimate())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*ssrcs = {kFixedSsrc};
|
|
||||||
*bitrate_bps = rate_control_.LatestEstimate();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayBasedBwe::SetStartBitrate(int start_bitrate_bps) {
|
|
||||||
RTC_LOG(LS_INFO) << "BWE Setting start bitrate to: " << start_bitrate_bps;
|
|
||||||
rate_control_.SetStartBitrate(start_bitrate_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
|
|
||||||
// Called from both the configuration thread and the network thread. Shouldn't
|
|
||||||
// be called from the network thread in the future.
|
|
||||||
rate_control_.SetMinBitrate(min_bitrate_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t DelayBasedBwe::GetExpectedBwePeriodMs() const {
|
|
||||||
return rate_control_.GetExpectedBandwidthPeriodMs();
|
|
||||||
}
|
|
||||||
} // namespace webrtc
|
|
||||||
@ -1,90 +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_DELAY_BASED_BWE_H_
|
|
||||||
#define MODULES_CONGESTION_CONTROLLER_DELAY_BASED_BWE_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#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"
|
|
||||||
#include "rtc_base/checks.h"
|
|
||||||
#include "rtc_base/constructormagic.h"
|
|
||||||
#include "rtc_base/race_checker.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
class RtcEventLog;
|
|
||||||
|
|
||||||
class DelayBasedBwe {
|
|
||||||
public:
|
|
||||||
static const int64_t kStreamTimeOutMs = 2000;
|
|
||||||
|
|
||||||
struct Result {
|
|
||||||
Result();
|
|
||||||
Result(bool probe, uint32_t target_bitrate_bps);
|
|
||||||
~Result();
|
|
||||||
bool updated;
|
|
||||||
bool probe;
|
|
||||||
uint32_t target_bitrate_bps;
|
|
||||||
bool recovered_from_overuse;
|
|
||||||
};
|
|
||||||
|
|
||||||
DelayBasedBwe(RtcEventLog* event_log, const Clock* clock);
|
|
||||||
virtual ~DelayBasedBwe();
|
|
||||||
|
|
||||||
Result IncomingPacketFeedbackVector(
|
|
||||||
const std::vector<PacketFeedback>& packet_feedback_vector,
|
|
||||||
absl::optional<uint32_t> acked_bitrate_bps);
|
|
||||||
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms);
|
|
||||||
bool LatestEstimate(std::vector<uint32_t>* ssrcs,
|
|
||||||
uint32_t* bitrate_bps) const;
|
|
||||||
void SetStartBitrate(int start_bitrate_bps);
|
|
||||||
void SetMinBitrate(int min_bitrate_bps);
|
|
||||||
int64_t GetExpectedBwePeriodMs() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void IncomingPacketFeedback(const PacketFeedback& packet_feedback);
|
|
||||||
Result OnLongFeedbackDelay(int64_t arrival_time_ms);
|
|
||||||
Result MaybeUpdateEstimate(absl::optional<uint32_t> acked_bitrate_bps,
|
|
||||||
bool request_probe);
|
|
||||||
// Updates the current remote rate estimate and returns true if a valid
|
|
||||||
// estimate exists.
|
|
||||||
bool UpdateEstimate(int64_t now_ms,
|
|
||||||
absl::optional<uint32_t> acked_bitrate_bps,
|
|
||||||
uint32_t* target_bitrate_bps);
|
|
||||||
|
|
||||||
rtc::RaceChecker network_race_;
|
|
||||||
RtcEventLog* const event_log_;
|
|
||||||
const Clock* const clock_;
|
|
||||||
std::unique_ptr<InterArrival> inter_arrival_;
|
|
||||||
std::unique_ptr<DelayIncreaseDetectorInterface> delay_detector_;
|
|
||||||
int64_t last_seen_packet_ms_;
|
|
||||||
bool uma_recorded_;
|
|
||||||
AimdRateControl rate_control_;
|
|
||||||
ProbeBitrateEstimator probe_bitrate_estimator_;
|
|
||||||
size_t trendline_window_size_;
|
|
||||||
double trendline_smoothing_coeff_;
|
|
||||||
double trendline_threshold_gain_;
|
|
||||||
int consecutive_delayed_feedbacks_;
|
|
||||||
uint32_t prev_bitrate_;
|
|
||||||
BandwidthUsage prev_state_;
|
|
||||||
|
|
||||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // MODULES_CONGESTION_CONTROLLER_DELAY_BASED_BWE_H_
|
|
||||||
@ -1,236 +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/delay_based_bwe.h"
|
|
||||||
#include "modules/congestion_controller/delay_based_bwe_unittest_helper.h"
|
|
||||||
#include "modules/pacing/paced_sender.h"
|
|
||||||
#include "rtc_base/constructormagic.h"
|
|
||||||
#include "system_wrappers/include/clock.h"
|
|
||||||
#include "test/field_trial.h"
|
|
||||||
#include "test/gtest.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
constexpr int kNumProbesCluster0 = 5;
|
|
||||||
constexpr int kNumProbesCluster1 = 8;
|
|
||||||
const PacedPacketInfo kPacingInfo0(0, kNumProbesCluster0, 2000);
|
|
||||||
const PacedPacketInfo kPacingInfo1(1, kNumProbesCluster1, 4000);
|
|
||||||
constexpr float kTargetUtilizationFraction = 0.95f;
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, NoCrashEmptyFeedback) {
|
|
||||||
std::vector<PacketFeedback> packet_feedback_vector;
|
|
||||||
bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector,
|
|
||||||
absl::nullopt);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, NoCrashOnlyLostFeedback) {
|
|
||||||
std::vector<PacketFeedback> packet_feedback_vector;
|
|
||||||
packet_feedback_vector.push_back(PacketFeedback(PacketFeedback::kNotReceived,
|
|
||||||
PacketFeedback::kNoSendTime,
|
|
||||||
0, 1500, PacedPacketInfo()));
|
|
||||||
packet_feedback_vector.push_back(PacketFeedback(PacketFeedback::kNotReceived,
|
|
||||||
PacketFeedback::kNoSendTime,
|
|
||||||
1, 1500, PacedPacketInfo()));
|
|
||||||
bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector,
|
|
||||||
absl::nullopt);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, ProbeDetection) {
|
|
||||||
int64_t now_ms = clock_.TimeInMilliseconds();
|
|
||||||
uint16_t seq_num = 0;
|
|
||||||
|
|
||||||
// First burst sent at 8 * 1000 / 10 = 800 kbps.
|
|
||||||
for (int i = 0; i < kNumProbesCluster0; ++i) {
|
|
||||||
clock_.AdvanceTimeMilliseconds(10);
|
|
||||||
now_ms = clock_.TimeInMilliseconds();
|
|
||||||
IncomingFeedback(now_ms, now_ms, seq_num++, 1000, kPacingInfo0);
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
|
|
||||||
// Second burst sent at 8 * 1000 / 5 = 1600 kbps.
|
|
||||||
for (int i = 0; i < kNumProbesCluster1; ++i) {
|
|
||||||
clock_.AdvanceTimeMilliseconds(5);
|
|
||||||
now_ms = clock_.TimeInMilliseconds();
|
|
||||||
IncomingFeedback(now_ms, now_ms, seq_num++, 1000, kPacingInfo1);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_GT(bitrate_observer_.latest_bitrate(), 1500000u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, ProbeDetectionNonPacedPackets) {
|
|
||||||
int64_t now_ms = clock_.TimeInMilliseconds();
|
|
||||||
uint16_t seq_num = 0;
|
|
||||||
// First burst sent at 8 * 1000 / 10 = 800 kbps, but with every other packet
|
|
||||||
// not being paced which could mess things up.
|
|
||||||
for (int i = 0; i < kNumProbesCluster0; ++i) {
|
|
||||||
clock_.AdvanceTimeMilliseconds(5);
|
|
||||||
now_ms = clock_.TimeInMilliseconds();
|
|
||||||
IncomingFeedback(now_ms, now_ms, seq_num++, 1000, kPacingInfo0);
|
|
||||||
// Non-paced packet, arriving 5 ms after.
|
|
||||||
clock_.AdvanceTimeMilliseconds(5);
|
|
||||||
IncomingFeedback(now_ms, now_ms, seq_num++, 100, PacedPacketInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_GT(bitrate_observer_.latest_bitrate(), 800000u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, ProbeDetectionFasterArrival) {
|
|
||||||
int64_t now_ms = clock_.TimeInMilliseconds();
|
|
||||||
uint16_t seq_num = 0;
|
|
||||||
// First burst sent at 8 * 1000 / 10 = 800 kbps.
|
|
||||||
// Arriving at 8 * 1000 / 5 = 1600 kbps.
|
|
||||||
int64_t send_time_ms = 0;
|
|
||||||
for (int i = 0; i < kNumProbesCluster0; ++i) {
|
|
||||||
clock_.AdvanceTimeMilliseconds(1);
|
|
||||||
send_time_ms += 10;
|
|
||||||
now_ms = clock_.TimeInMilliseconds();
|
|
||||||
IncomingFeedback(now_ms, send_time_ms, seq_num++, 1000, kPacingInfo0);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_FALSE(bitrate_observer_.updated());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, ProbeDetectionSlowerArrival) {
|
|
||||||
int64_t now_ms = clock_.TimeInMilliseconds();
|
|
||||||
uint16_t seq_num = 0;
|
|
||||||
// First burst sent at 8 * 1000 / 5 = 1600 kbps.
|
|
||||||
// Arriving at 8 * 1000 / 7 = 1142 kbps.
|
|
||||||
// Since the receive rate is significantly below the send rate, we expect to
|
|
||||||
// use 95% of the estimated capacity.
|
|
||||||
int64_t send_time_ms = 0;
|
|
||||||
for (int i = 0; i < kNumProbesCluster1; ++i) {
|
|
||||||
clock_.AdvanceTimeMilliseconds(7);
|
|
||||||
send_time_ms += 5;
|
|
||||||
now_ms = clock_.TimeInMilliseconds();
|
|
||||||
IncomingFeedback(now_ms, send_time_ms, seq_num++, 1000, kPacingInfo1);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_NEAR(bitrate_observer_.latest_bitrate(),
|
|
||||||
kTargetUtilizationFraction * 1140000u, 10000u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, ProbeDetectionSlowerArrivalHighBitrate) {
|
|
||||||
int64_t now_ms = clock_.TimeInMilliseconds();
|
|
||||||
uint16_t seq_num = 0;
|
|
||||||
// Burst sent at 8 * 1000 / 1 = 8000 kbps.
|
|
||||||
// Arriving at 8 * 1000 / 2 = 4000 kbps.
|
|
||||||
// Since the receive rate is significantly below the send rate, we expect to
|
|
||||||
// use 95% of the estimated capacity.
|
|
||||||
int64_t send_time_ms = 0;
|
|
||||||
for (int i = 0; i < kNumProbesCluster1; ++i) {
|
|
||||||
clock_.AdvanceTimeMilliseconds(2);
|
|
||||||
send_time_ms += 1;
|
|
||||||
now_ms = clock_.TimeInMilliseconds();
|
|
||||||
IncomingFeedback(now_ms, send_time_ms, seq_num++, 1000, kPacingInfo1);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_NEAR(bitrate_observer_.latest_bitrate(),
|
|
||||||
kTargetUtilizationFraction * 4000000u, 10000u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, GetExpectedBwePeriodMs) {
|
|
||||||
int64_t default_interval_ms = bitrate_estimator_->GetExpectedBwePeriodMs();
|
|
||||||
EXPECT_GT(default_interval_ms, 0);
|
|
||||||
CapacityDropTestHelper(1, true, 333, 0);
|
|
||||||
int64_t interval_ms = bitrate_estimator_->GetExpectedBwePeriodMs();
|
|
||||||
EXPECT_GT(interval_ms, 0);
|
|
||||||
EXPECT_NE(interval_ms, default_interval_ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, InitialBehavior) {
|
|
||||||
InitialBehaviorTestHelper(730000);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, RateIncreaseReordering) {
|
|
||||||
RateIncreaseReorderingTestHelper(730000);
|
|
||||||
}
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, RateIncreaseRtpTimestamps) {
|
|
||||||
RateIncreaseRtpTimestampsTestHelper(627);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, CapacityDropOneStream) {
|
|
||||||
CapacityDropTestHelper(1, false, 300, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, CapacityDropPosOffsetChange) {
|
|
||||||
CapacityDropTestHelper(1, false, 867, 30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, CapacityDropNegOffsetChange) {
|
|
||||||
CapacityDropTestHelper(1, false, 933, -30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, CapacityDropOneStreamWrap) {
|
|
||||||
CapacityDropTestHelper(1, true, 333, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, TestTimestampGrouping) {
|
|
||||||
TestTimestampGroupingTestHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, TestShortTimeoutAndWrap) {
|
|
||||||
// Simulate a client leaving and rejoining the call after 35 seconds. This
|
|
||||||
// will make abs send time wrap, so if streams aren't timed out properly
|
|
||||||
// the next 30 seconds of packets will be out of order.
|
|
||||||
TestWrappingHelper(35);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, TestLongTimeoutAndWrap) {
|
|
||||||
// Simulate a client leaving and rejoining the call after some multiple of
|
|
||||||
// 64 seconds later. This will cause a zero difference in abs send times due
|
|
||||||
// to the wrap, but a big difference in arrival time, if streams aren't
|
|
||||||
// properly timed out.
|
|
||||||
TestWrappingHelper(10 * 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(LegacyDelayBasedBweTest, TestInitialOveruse) {
|
|
||||||
const uint32_t kStartBitrate = 300e3;
|
|
||||||
const uint32_t kInitialCapacityBps = 200e3;
|
|
||||||
const uint32_t kDummySsrc = 0;
|
|
||||||
// High FPS to ensure that we send a lot of packets in a short time.
|
|
||||||
const int kFps = 90;
|
|
||||||
|
|
||||||
stream_generator_->AddStream(new test::RtpStream(kFps, kStartBitrate));
|
|
||||||
stream_generator_->set_capacity_bps(kInitialCapacityBps);
|
|
||||||
|
|
||||||
// Needed to initialize the AimdRateControl.
|
|
||||||
bitrate_estimator_->SetStartBitrate(kStartBitrate);
|
|
||||||
|
|
||||||
// Produce 30 frames (in 1/3 second) and give them to the estimator.
|
|
||||||
uint32_t bitrate_bps = kStartBitrate;
|
|
||||||
bool seen_overuse = false;
|
|
||||||
for (int i = 0; i < 30; ++i) {
|
|
||||||
bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps);
|
|
||||||
// The purpose of this test is to ensure that we back down even if we don't
|
|
||||||
// have any acknowledged bitrate estimate yet. Hence, if the test works
|
|
||||||
// as expected, we should not have a measured bitrate yet.
|
|
||||||
EXPECT_FALSE(acknowledged_bitrate_estimator_->bitrate_bps().has_value());
|
|
||||||
if (overuse) {
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000);
|
|
||||||
bitrate_bps = bitrate_observer_.latest_bitrate();
|
|
||||||
seen_overuse = true;
|
|
||||||
break;
|
|
||||||
} else if (bitrate_observer_.updated()) {
|
|
||||||
bitrate_bps = bitrate_observer_.latest_bitrate();
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(seen_overuse);
|
|
||||||
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
||||||
@ -1,514 +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/delay_based_bwe_unittest_helper.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <limits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "modules/congestion_controller/delay_based_bwe.h"
|
|
||||||
#include "rtc_base/checks.h"
|
|
||||||
#include "rtc_base/ptr_util.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
constexpr size_t kMtu = 1200;
|
|
||||||
constexpr uint32_t kAcceptedBitrateErrorBps = 50000;
|
|
||||||
|
|
||||||
// Number of packets needed before we have a valid estimate.
|
|
||||||
constexpr int kNumInitialPackets = 2;
|
|
||||||
|
|
||||||
constexpr int kInitialProbingPackets = 5;
|
|
||||||
|
|
||||||
namespace test {
|
|
||||||
|
|
||||||
void TestBitrateObserver::OnReceiveBitrateChanged(
|
|
||||||
const std::vector<uint32_t>& ssrcs,
|
|
||||||
uint32_t bitrate) {
|
|
||||||
latest_bitrate_ = bitrate;
|
|
||||||
updated_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtpStream::RtpStream(int fps, int bitrate_bps)
|
|
||||||
: fps_(fps),
|
|
||||||
bitrate_bps_(bitrate_bps),
|
|
||||||
next_rtp_time_(0),
|
|
||||||
sequence_number_(0) {
|
|
||||||
RTC_CHECK_GT(fps_, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a new frame for this stream. If called too soon after the
|
|
||||||
// previous frame, no frame will be generated. The frame is split into
|
|
||||||
// packets.
|
|
||||||
int64_t RtpStream::GenerateFrame(int64_t time_now_us,
|
|
||||||
std::vector<PacketFeedback>* packets) {
|
|
||||||
if (time_now_us < next_rtp_time_) {
|
|
||||||
return next_rtp_time_;
|
|
||||||
}
|
|
||||||
RTC_CHECK(packets != NULL);
|
|
||||||
size_t bits_per_frame = (bitrate_bps_ + fps_ / 2) / fps_;
|
|
||||||
size_t n_packets =
|
|
||||||
std::max<size_t>((bits_per_frame + 4 * kMtu) / (8 * kMtu), 1u);
|
|
||||||
size_t payload_size = (bits_per_frame + 4 * n_packets) / (8 * n_packets);
|
|
||||||
for (size_t i = 0; i < n_packets; ++i) {
|
|
||||||
PacketFeedback packet(-1, sequence_number_++);
|
|
||||||
packet.send_time_ms = (time_now_us + kSendSideOffsetUs) / 1000;
|
|
||||||
packet.payload_size = payload_size;
|
|
||||||
packets->push_back(packet);
|
|
||||||
}
|
|
||||||
next_rtp_time_ = time_now_us + (1000000 + fps_ / 2) / fps_;
|
|
||||||
return next_rtp_time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The send-side time when the next frame can be generated.
|
|
||||||
int64_t RtpStream::next_rtp_time() const {
|
|
||||||
return next_rtp_time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtpStream::set_bitrate_bps(int bitrate_bps) {
|
|
||||||
ASSERT_GE(bitrate_bps, 0);
|
|
||||||
bitrate_bps_ = bitrate_bps;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RtpStream::bitrate_bps() const {
|
|
||||||
return bitrate_bps_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RtpStream::Compare(const std::unique_ptr<RtpStream>& lhs,
|
|
||||||
const std::unique_ptr<RtpStream>& rhs) {
|
|
||||||
return lhs->next_rtp_time_ < rhs->next_rtp_time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamGenerator::StreamGenerator(int capacity, int64_t time_now)
|
|
||||||
: capacity_(capacity), prev_arrival_time_us_(time_now) {}
|
|
||||||
|
|
||||||
// Add a new stream.
|
|
||||||
void StreamGenerator::AddStream(RtpStream* stream) {
|
|
||||||
streams_.push_back(std::unique_ptr<RtpStream>(stream));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the link capacity.
|
|
||||||
void StreamGenerator::set_capacity_bps(int capacity_bps) {
|
|
||||||
ASSERT_GT(capacity_bps, 0);
|
|
||||||
capacity_ = capacity_bps;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Divides |bitrate_bps| among all streams. The allocated bitrate per stream
|
|
||||||
// is decided by the current allocation ratios.
|
|
||||||
void StreamGenerator::SetBitrateBps(int bitrate_bps) {
|
|
||||||
ASSERT_GE(streams_.size(), 0u);
|
|
||||||
int total_bitrate_before = 0;
|
|
||||||
for (const auto& stream : streams_) {
|
|
||||||
total_bitrate_before += stream->bitrate_bps();
|
|
||||||
}
|
|
||||||
int64_t bitrate_before = 0;
|
|
||||||
int total_bitrate_after = 0;
|
|
||||||
for (const auto& stream : streams_) {
|
|
||||||
bitrate_before += stream->bitrate_bps();
|
|
||||||
int64_t bitrate_after =
|
|
||||||
(bitrate_before * bitrate_bps + total_bitrate_before / 2) /
|
|
||||||
total_bitrate_before;
|
|
||||||
stream->set_bitrate_bps(bitrate_after - total_bitrate_after);
|
|
||||||
total_bitrate_after += stream->bitrate_bps();
|
|
||||||
}
|
|
||||||
ASSERT_EQ(bitrate_before, total_bitrate_before);
|
|
||||||
EXPECT_EQ(total_bitrate_after, bitrate_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(holmer): Break out the channel simulation part from this class to make
|
|
||||||
// it possible to simulate different types of channels.
|
|
||||||
int64_t StreamGenerator::GenerateFrame(std::vector<PacketFeedback>* packets,
|
|
||||||
int64_t time_now_us) {
|
|
||||||
RTC_CHECK(packets != NULL);
|
|
||||||
RTC_CHECK(packets->empty());
|
|
||||||
RTC_CHECK_GT(capacity_, 0);
|
|
||||||
auto it =
|
|
||||||
std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
|
|
||||||
(*it)->GenerateFrame(time_now_us, packets);
|
|
||||||
int i = 0;
|
|
||||||
for (PacketFeedback& packet : *packets) {
|
|
||||||
int capacity_bpus = capacity_ / 1000;
|
|
||||||
int64_t required_network_time_us =
|
|
||||||
(8 * 1000 * packet.payload_size + capacity_bpus / 2) / capacity_bpus;
|
|
||||||
prev_arrival_time_us_ =
|
|
||||||
std::max(time_now_us + required_network_time_us,
|
|
||||||
prev_arrival_time_us_ + required_network_time_us);
|
|
||||||
packet.arrival_time_ms = prev_arrival_time_us_ / 1000;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
it = std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
|
|
||||||
return std::max((*it)->next_rtp_time(), time_now_us);
|
|
||||||
}
|
|
||||||
} // namespace test
|
|
||||||
|
|
||||||
LegacyDelayBasedBweTest::LegacyDelayBasedBweTest()
|
|
||||||
: clock_(100000000),
|
|
||||||
acknowledged_bitrate_estimator_(
|
|
||||||
rtc::MakeUnique<AcknowledgedBitrateEstimator>()),
|
|
||||||
bitrate_estimator_(new DelayBasedBwe(nullptr, &clock_)),
|
|
||||||
stream_generator_(new test::StreamGenerator(1e6, // Capacity.
|
|
||||||
clock_.TimeInMicroseconds())),
|
|
||||||
arrival_time_offset_ms_(0),
|
|
||||||
first_update_(true) {}
|
|
||||||
|
|
||||||
LegacyDelayBasedBweTest::~LegacyDelayBasedBweTest() {}
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::AddDefaultStream() {
|
|
||||||
stream_generator_->AddStream(new test::RtpStream(30, 3e5));
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t LegacyDelayBasedBweTest::kDefaultSsrc = 0;
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms,
|
|
||||||
int64_t send_time_ms,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
size_t payload_size) {
|
|
||||||
IncomingFeedback(arrival_time_ms, send_time_ms, sequence_number, payload_size,
|
|
||||||
PacedPacketInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::IncomingFeedback(
|
|
||||||
int64_t arrival_time_ms,
|
|
||||||
int64_t send_time_ms,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
size_t payload_size,
|
|
||||||
const PacedPacketInfo& pacing_info) {
|
|
||||||
RTC_CHECK_GE(arrival_time_ms + arrival_time_offset_ms_, 0);
|
|
||||||
PacketFeedback packet(arrival_time_ms + arrival_time_offset_ms_, send_time_ms,
|
|
||||||
sequence_number, payload_size, pacing_info);
|
|
||||||
std::vector<PacketFeedback> packets;
|
|
||||||
packets.push_back(packet);
|
|
||||||
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets);
|
|
||||||
DelayBasedBwe::Result result =
|
|
||||||
bitrate_estimator_->IncomingPacketFeedbackVector(
|
|
||||||
packets, acknowledged_bitrate_estimator_->bitrate_bps());
|
|
||||||
const uint32_t kDummySsrc = 0;
|
|
||||||
if (result.updated) {
|
|
||||||
bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc},
|
|
||||||
result.target_bitrate_bps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a frame of packets belonging to a stream at a given bitrate and
|
|
||||||
// with a given ssrc. The stream is pushed through a very simple simulated
|
|
||||||
// network, and is then given to the receive-side bandwidth estimator.
|
|
||||||
// Returns true if an over-use was seen, false otherwise.
|
|
||||||
// The StreamGenerator::updated() should be used to check for any changes in
|
|
||||||
// target bitrate after the call to this function.
|
|
||||||
bool LegacyDelayBasedBweTest::GenerateAndProcessFrame(uint32_t ssrc,
|
|
||||||
uint32_t bitrate_bps) {
|
|
||||||
stream_generator_->SetBitrateBps(bitrate_bps);
|
|
||||||
std::vector<PacketFeedback> packets;
|
|
||||||
int64_t next_time_us =
|
|
||||||
stream_generator_->GenerateFrame(&packets, clock_.TimeInMicroseconds());
|
|
||||||
if (packets.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool overuse = false;
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
clock_.AdvanceTimeMicroseconds(1000 * packets.back().arrival_time_ms -
|
|
||||||
clock_.TimeInMicroseconds());
|
|
||||||
for (auto& packet : packets) {
|
|
||||||
RTC_CHECK_GE(packet.arrival_time_ms + arrival_time_offset_ms_, 0);
|
|
||||||
packet.arrival_time_ms += arrival_time_offset_ms_;
|
|
||||||
}
|
|
||||||
|
|
||||||
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets);
|
|
||||||
DelayBasedBwe::Result result =
|
|
||||||
bitrate_estimator_->IncomingPacketFeedbackVector(
|
|
||||||
packets, acknowledged_bitrate_estimator_->bitrate_bps());
|
|
||||||
const uint32_t kDummySsrc = 0;
|
|
||||||
if (result.updated) {
|
|
||||||
bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc},
|
|
||||||
result.target_bitrate_bps);
|
|
||||||
if (!first_update_ && result.target_bitrate_bps < bitrate_bps)
|
|
||||||
overuse = true;
|
|
||||||
first_update_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
clock_.AdvanceTimeMicroseconds(next_time_us - clock_.TimeInMicroseconds());
|
|
||||||
return overuse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the bandwidth estimator with a stream of |number_of_frames| frames, or
|
|
||||||
// until it reaches |target_bitrate|.
|
|
||||||
// Can for instance be used to run the estimator for some time to get it
|
|
||||||
// into a steady state.
|
|
||||||
uint32_t LegacyDelayBasedBweTest::SteadyStateRun(uint32_t ssrc,
|
|
||||||
int max_number_of_frames,
|
|
||||||
uint32_t start_bitrate,
|
|
||||||
uint32_t min_bitrate,
|
|
||||||
uint32_t max_bitrate,
|
|
||||||
uint32_t target_bitrate) {
|
|
||||||
uint32_t bitrate_bps = start_bitrate;
|
|
||||||
bool bitrate_update_seen = false;
|
|
||||||
// Produce |number_of_frames| frames and give them to the estimator.
|
|
||||||
for (int i = 0; i < max_number_of_frames; ++i) {
|
|
||||||
bool overuse = GenerateAndProcessFrame(ssrc, bitrate_bps);
|
|
||||||
if (overuse) {
|
|
||||||
EXPECT_LT(bitrate_observer_.latest_bitrate(), max_bitrate);
|
|
||||||
EXPECT_GT(bitrate_observer_.latest_bitrate(), min_bitrate);
|
|
||||||
bitrate_bps = bitrate_observer_.latest_bitrate();
|
|
||||||
bitrate_update_seen = true;
|
|
||||||
} else if (bitrate_observer_.updated()) {
|
|
||||||
bitrate_bps = bitrate_observer_.latest_bitrate();
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
}
|
|
||||||
if (bitrate_update_seen && bitrate_bps > target_bitrate) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(bitrate_update_seen);
|
|
||||||
return bitrate_bps;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::InitialBehaviorTestHelper(
|
|
||||||
uint32_t expected_converge_bitrate) {
|
|
||||||
const int kFramerate = 50; // 50 fps to avoid rounding errors.
|
|
||||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
|
||||||
const PacedPacketInfo kPacingInfo(0, 5, 5000);
|
|
||||||
uint32_t bitrate_bps = 0;
|
|
||||||
int64_t send_time_ms = 0;
|
|
||||||
uint16_t sequence_number = 0;
|
|
||||||
std::vector<uint32_t> ssrcs;
|
|
||||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
|
||||||
EXPECT_EQ(0u, ssrcs.size());
|
|
||||||
clock_.AdvanceTimeMilliseconds(1000);
|
|
||||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
|
||||||
EXPECT_FALSE(bitrate_observer_.updated());
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
clock_.AdvanceTimeMilliseconds(1000);
|
|
||||||
// Inserting packets for 5 seconds to get a valid estimate.
|
|
||||||
for (int i = 0; i < 5 * kFramerate + 1 + kNumInitialPackets; ++i) {
|
|
||||||
// NOTE!!! If the following line is moved under the if case then this test
|
|
||||||
// wont work on windows realease bots.
|
|
||||||
PacedPacketInfo pacing_info =
|
|
||||||
i < kInitialProbingPackets ? kPacingInfo : PacedPacketInfo();
|
|
||||||
|
|
||||||
if (i == kNumInitialPackets) {
|
|
||||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
|
||||||
EXPECT_EQ(0u, ssrcs.size());
|
|
||||||
EXPECT_FALSE(bitrate_observer_.updated());
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
}
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
|
|
||||||
sequence_number++, kMtu, pacing_info);
|
|
||||||
clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
|
|
||||||
send_time_ms += kFrameIntervalMs;
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
|
||||||
ASSERT_EQ(1u, ssrcs.size());
|
|
||||||
EXPECT_EQ(kDefaultSsrc, ssrcs.front());
|
|
||||||
EXPECT_NEAR(expected_converge_bitrate, bitrate_bps, kAcceptedBitrateErrorBps);
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
EXPECT_EQ(bitrate_observer_.latest_bitrate(), bitrate_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::RateIncreaseReorderingTestHelper(
|
|
||||||
uint32_t expected_bitrate_bps) {
|
|
||||||
const int kFramerate = 50; // 50 fps to avoid rounding errors.
|
|
||||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
|
||||||
const PacedPacketInfo kPacingInfo(0, 5, 5000);
|
|
||||||
int64_t send_time_ms = 0;
|
|
||||||
uint16_t sequence_number = 0;
|
|
||||||
// Inserting packets for five seconds to get a valid estimate.
|
|
||||||
for (int i = 0; i < 5 * kFramerate + 1 + kNumInitialPackets; ++i) {
|
|
||||||
// NOTE!!! If the following line is moved under the if case then this test
|
|
||||||
// wont work on windows realease bots.
|
|
||||||
PacedPacketInfo pacing_info =
|
|
||||||
i < kInitialProbingPackets ? kPacingInfo : PacedPacketInfo();
|
|
||||||
|
|
||||||
// TODO(sprang): Remove this hack once the single stream estimator is gone,
|
|
||||||
// as it doesn't do anything in Process().
|
|
||||||
if (i == kNumInitialPackets) {
|
|
||||||
// Process after we have enough frames to get a valid input rate estimate.
|
|
||||||
|
|
||||||
EXPECT_FALSE(bitrate_observer_.updated()); // No valid estimate.
|
|
||||||
}
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
|
|
||||||
sequence_number++, kMtu, pacing_info);
|
|
||||||
clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
|
||||||
send_time_ms += kFrameIntervalMs;
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_NEAR(expected_bitrate_bps, bitrate_observer_.latest_bitrate(),
|
|
||||||
kAcceptedBitrateErrorBps);
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
|
|
||||||
send_time_ms += 2 * kFrameIntervalMs;
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
|
|
||||||
sequence_number + 2, 1000);
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(),
|
|
||||||
send_time_ms - kFrameIntervalMs, sequence_number + 1,
|
|
||||||
1000);
|
|
||||||
sequence_number += 2;
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_NEAR(expected_bitrate_bps, bitrate_observer_.latest_bitrate(),
|
|
||||||
kAcceptedBitrateErrorBps);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we initially increase the bitrate as expected.
|
|
||||||
void LegacyDelayBasedBweTest::RateIncreaseRtpTimestampsTestHelper(
|
|
||||||
int expected_iterations) {
|
|
||||||
// This threshold corresponds approximately to increasing linearly with
|
|
||||||
// bitrate(i) = 1.04 * bitrate(i-1) + 1000
|
|
||||||
// until bitrate(i) > 500000, with bitrate(1) ~= 30000.
|
|
||||||
uint32_t bitrate_bps = 30000;
|
|
||||||
int iterations = 0;
|
|
||||||
AddDefaultStream();
|
|
||||||
// Feed the estimator with a stream of packets and verify that it reaches
|
|
||||||
// 500 kbps at the expected time.
|
|
||||||
while (bitrate_bps < 5e5) {
|
|
||||||
bool overuse = GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
|
||||||
if (overuse) {
|
|
||||||
EXPECT_GT(bitrate_observer_.latest_bitrate(), bitrate_bps);
|
|
||||||
bitrate_bps = bitrate_observer_.latest_bitrate();
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
} else if (bitrate_observer_.updated()) {
|
|
||||||
bitrate_bps = bitrate_observer_.latest_bitrate();
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
}
|
|
||||||
++iterations;
|
|
||||||
}
|
|
||||||
ASSERT_EQ(expected_iterations, iterations);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::CapacityDropTestHelper(
|
|
||||||
int number_of_streams,
|
|
||||||
bool wrap_time_stamp,
|
|
||||||
uint32_t expected_bitrate_drop_delta,
|
|
||||||
int64_t receiver_clock_offset_change_ms) {
|
|
||||||
const int kFramerate = 30;
|
|
||||||
const int kStartBitrate = 900e3;
|
|
||||||
const int kMinExpectedBitrate = 800e3;
|
|
||||||
const int kMaxExpectedBitrate = 1100e3;
|
|
||||||
const uint32_t kInitialCapacityBps = 1000e3;
|
|
||||||
const uint32_t kReducedCapacityBps = 500e3;
|
|
||||||
|
|
||||||
int steady_state_time = 0;
|
|
||||||
if (number_of_streams <= 1) {
|
|
||||||
steady_state_time = 10;
|
|
||||||
AddDefaultStream();
|
|
||||||
} else {
|
|
||||||
steady_state_time = 10 * number_of_streams;
|
|
||||||
int bitrate_sum = 0;
|
|
||||||
int kBitrateDenom = number_of_streams * (number_of_streams - 1);
|
|
||||||
for (int i = 0; i < number_of_streams; i++) {
|
|
||||||
// First stream gets half available bitrate, while the rest share the
|
|
||||||
// remaining half i.e.: 1/2 = Sum[n/(N*(N-1))] for n=1..N-1 (rounded up)
|
|
||||||
int bitrate = kStartBitrate / 2;
|
|
||||||
if (i > 0) {
|
|
||||||
bitrate = (kStartBitrate * i + kBitrateDenom / 2) / kBitrateDenom;
|
|
||||||
}
|
|
||||||
stream_generator_->AddStream(new test::RtpStream(kFramerate, bitrate));
|
|
||||||
bitrate_sum += bitrate;
|
|
||||||
}
|
|
||||||
ASSERT_EQ(bitrate_sum, kStartBitrate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run in steady state to make the estimator converge.
|
|
||||||
stream_generator_->set_capacity_bps(kInitialCapacityBps);
|
|
||||||
uint32_t bitrate_bps = SteadyStateRun(
|
|
||||||
kDefaultSsrc, steady_state_time * kFramerate, kStartBitrate,
|
|
||||||
kMinExpectedBitrate, kMaxExpectedBitrate, kInitialCapacityBps);
|
|
||||||
EXPECT_NEAR(kInitialCapacityBps, bitrate_bps, 180000u);
|
|
||||||
bitrate_observer_.Reset();
|
|
||||||
|
|
||||||
// Add an offset to make sure the BWE can handle it.
|
|
||||||
arrival_time_offset_ms_ += receiver_clock_offset_change_ms;
|
|
||||||
|
|
||||||
// Reduce the capacity and verify the decrease time.
|
|
||||||
stream_generator_->set_capacity_bps(kReducedCapacityBps);
|
|
||||||
int64_t overuse_start_time = clock_.TimeInMilliseconds();
|
|
||||||
int64_t bitrate_drop_time = -1;
|
|
||||||
for (int i = 0; i < 100 * number_of_streams; ++i) {
|
|
||||||
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
|
||||||
if (bitrate_drop_time == -1 &&
|
|
||||||
bitrate_observer_.latest_bitrate() <= kReducedCapacityBps) {
|
|
||||||
bitrate_drop_time = clock_.TimeInMilliseconds();
|
|
||||||
}
|
|
||||||
if (bitrate_observer_.updated())
|
|
||||||
bitrate_bps = bitrate_observer_.latest_bitrate();
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_NEAR(expected_bitrate_drop_delta,
|
|
||||||
bitrate_drop_time - overuse_start_time, 33);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::TestTimestampGroupingTestHelper() {
|
|
||||||
const int kFramerate = 50; // 50 fps to avoid rounding errors.
|
|
||||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
|
||||||
int64_t send_time_ms = 0;
|
|
||||||
uint16_t sequence_number = 0;
|
|
||||||
// Initial set of frames to increase the bitrate. 6 seconds to have enough
|
|
||||||
// time for the first estimate to be generated and for Process() to be called.
|
|
||||||
for (int i = 0; i <= 6 * kFramerate; ++i) {
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
|
|
||||||
sequence_number++, 1000);
|
|
||||||
|
|
||||||
clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
|
||||||
send_time_ms += kFrameIntervalMs;
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
EXPECT_GE(bitrate_observer_.latest_bitrate(), 400000u);
|
|
||||||
|
|
||||||
// Insert batches of frames which were sent very close in time. Also simulate
|
|
||||||
// capacity over-use to see that we back off correctly.
|
|
||||||
const int kTimestampGroupLength = 15;
|
|
||||||
for (int i = 0; i < 100; ++i) {
|
|
||||||
for (int j = 0; j < kTimestampGroupLength; ++j) {
|
|
||||||
// Insert |kTimestampGroupLength| frames with just 1 timestamp ticks in
|
|
||||||
// between. Should be treated as part of the same group by the estimator.
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
|
|
||||||
sequence_number++, 100);
|
|
||||||
clock_.AdvanceTimeMilliseconds(kFrameIntervalMs / kTimestampGroupLength);
|
|
||||||
send_time_ms += 1;
|
|
||||||
}
|
|
||||||
// Increase time until next batch to simulate over-use.
|
|
||||||
clock_.AdvanceTimeMilliseconds(10);
|
|
||||||
send_time_ms += kFrameIntervalMs - kTimestampGroupLength;
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(bitrate_observer_.updated());
|
|
||||||
// Should have reduced the estimate.
|
|
||||||
EXPECT_LT(bitrate_observer_.latest_bitrate(), 400000u);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LegacyDelayBasedBweTest::TestWrappingHelper(int silence_time_s) {
|
|
||||||
const int kFramerate = 100;
|
|
||||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
|
||||||
int64_t send_time_ms = 0;
|
|
||||||
uint16_t sequence_number = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < 3000; ++i) {
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
|
|
||||||
sequence_number++, 1000);
|
|
||||||
clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
|
||||||
send_time_ms += kFrameIntervalMs;
|
|
||||||
}
|
|
||||||
uint32_t bitrate_before = 0;
|
|
||||||
std::vector<uint32_t> ssrcs;
|
|
||||||
bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_before);
|
|
||||||
|
|
||||||
clock_.AdvanceTimeMilliseconds(silence_time_s * 1000);
|
|
||||||
send_time_ms += silence_time_s * 1000;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < 24; ++i) {
|
|
||||||
IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
|
|
||||||
sequence_number++, 1000);
|
|
||||||
clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
|
|
||||||
send_time_ms += kFrameIntervalMs;
|
|
||||||
}
|
|
||||||
uint32_t bitrate_after = 0;
|
|
||||||
bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_after);
|
|
||||||
EXPECT_LT(bitrate_after, bitrate_before);
|
|
||||||
}
|
|
||||||
} // namespace webrtc
|
|
||||||
@ -1,178 +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_DELAY_BASED_BWE_UNITTEST_HELPER_H_
|
|
||||||
#define MODULES_CONGESTION_CONTROLLER_DELAY_BASED_BWE_UNITTEST_HELPER_H_
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#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"
|
|
||||||
#include "test/gtest.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
namespace test {
|
|
||||||
|
|
||||||
class TestBitrateObserver : public RemoteBitrateObserver {
|
|
||||||
public:
|
|
||||||
TestBitrateObserver() : updated_(false), latest_bitrate_(0) {}
|
|
||||||
virtual ~TestBitrateObserver() {}
|
|
||||||
|
|
||||||
void OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
|
|
||||||
uint32_t bitrate) override;
|
|
||||||
|
|
||||||
void Reset() { updated_ = false; }
|
|
||||||
|
|
||||||
bool updated() const { return updated_; }
|
|
||||||
|
|
||||||
uint32_t latest_bitrate() const { return latest_bitrate_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool updated_;
|
|
||||||
uint32_t latest_bitrate_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RtpStream {
|
|
||||||
public:
|
|
||||||
enum { kSendSideOffsetUs = 1000000 };
|
|
||||||
|
|
||||||
RtpStream(int fps, int bitrate_bps);
|
|
||||||
|
|
||||||
// Generates a new frame for this stream. If called too soon after the
|
|
||||||
// previous frame, no frame will be generated. The frame is split into
|
|
||||||
// packets.
|
|
||||||
int64_t GenerateFrame(int64_t time_now_us,
|
|
||||||
std::vector<PacketFeedback>* packets);
|
|
||||||
|
|
||||||
// The send-side time when the next frame can be generated.
|
|
||||||
int64_t next_rtp_time() const;
|
|
||||||
|
|
||||||
void set_bitrate_bps(int bitrate_bps);
|
|
||||||
|
|
||||||
int bitrate_bps() const;
|
|
||||||
|
|
||||||
static bool Compare(const std::unique_ptr<RtpStream>& lhs,
|
|
||||||
const std::unique_ptr<RtpStream>& rhs);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int fps_;
|
|
||||||
int bitrate_bps_;
|
|
||||||
int64_t next_rtp_time_;
|
|
||||||
uint16_t sequence_number_;
|
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(RtpStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
class StreamGenerator {
|
|
||||||
public:
|
|
||||||
StreamGenerator(int capacity, int64_t time_now);
|
|
||||||
|
|
||||||
// Add a new stream.
|
|
||||||
void AddStream(RtpStream* stream);
|
|
||||||
|
|
||||||
// Set the link capacity.
|
|
||||||
void set_capacity_bps(int capacity_bps);
|
|
||||||
|
|
||||||
// Divides |bitrate_bps| among all streams. The allocated bitrate per stream
|
|
||||||
// is decided by the initial allocation ratios.
|
|
||||||
void SetBitrateBps(int bitrate_bps);
|
|
||||||
|
|
||||||
// Set the RTP timestamp offset for the stream identified by |ssrc|.
|
|
||||||
void set_rtp_timestamp_offset(uint32_t ssrc, uint32_t offset);
|
|
||||||
|
|
||||||
// TODO(holmer): Break out the channel simulation part from this class to make
|
|
||||||
// it possible to simulate different types of channels.
|
|
||||||
int64_t GenerateFrame(std::vector<PacketFeedback>* packets,
|
|
||||||
int64_t time_now_us);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Capacity of the simulated channel in bits per second.
|
|
||||||
int capacity_;
|
|
||||||
// The time when the last packet arrived.
|
|
||||||
int64_t prev_arrival_time_us_;
|
|
||||||
// All streams being transmitted on this simulated channel.
|
|
||||||
std::vector<std::unique_ptr<RtpStream>> streams_;
|
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(StreamGenerator);
|
|
||||||
};
|
|
||||||
} // namespace test
|
|
||||||
|
|
||||||
class LegacyDelayBasedBweTest : public ::testing::Test {
|
|
||||||
public:
|
|
||||||
LegacyDelayBasedBweTest();
|
|
||||||
virtual ~LegacyDelayBasedBweTest();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void AddDefaultStream();
|
|
||||||
|
|
||||||
// Helpers to insert a single packet into the delay-based BWE.
|
|
||||||
void IncomingFeedback(int64_t arrival_time_ms,
|
|
||||||
int64_t send_time_ms,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
size_t payload_size);
|
|
||||||
void IncomingFeedback(int64_t arrival_time_ms,
|
|
||||||
int64_t send_time_ms,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
size_t payload_size,
|
|
||||||
const PacedPacketInfo& pacing_info);
|
|
||||||
|
|
||||||
// Generates a frame of packets belonging to a stream at a given bitrate and
|
|
||||||
// with a given ssrc. The stream is pushed through a very simple simulated
|
|
||||||
// network, and is then given to the receive-side bandwidth estimator.
|
|
||||||
// Returns true if an over-use was seen, false otherwise.
|
|
||||||
// The StreamGenerator::updated() should be used to check for any changes in
|
|
||||||
// target bitrate after the call to this function.
|
|
||||||
bool GenerateAndProcessFrame(uint32_t ssrc, uint32_t bitrate_bps);
|
|
||||||
|
|
||||||
// Run the bandwidth estimator with a stream of |number_of_frames| frames, or
|
|
||||||
// until it reaches |target_bitrate|.
|
|
||||||
// Can for instance be used to run the estimator for some time to get it
|
|
||||||
// into a steady state.
|
|
||||||
uint32_t SteadyStateRun(uint32_t ssrc,
|
|
||||||
int number_of_frames,
|
|
||||||
uint32_t start_bitrate,
|
|
||||||
uint32_t min_bitrate,
|
|
||||||
uint32_t max_bitrate,
|
|
||||||
uint32_t target_bitrate);
|
|
||||||
|
|
||||||
void TestTimestampGroupingTestHelper();
|
|
||||||
|
|
||||||
void TestWrappingHelper(int silence_time_s);
|
|
||||||
|
|
||||||
void InitialBehaviorTestHelper(uint32_t expected_converge_bitrate);
|
|
||||||
void RateIncreaseReorderingTestHelper(uint32_t expected_bitrate);
|
|
||||||
void RateIncreaseRtpTimestampsTestHelper(int expected_iterations);
|
|
||||||
void CapacityDropTestHelper(int number_of_streams,
|
|
||||||
bool wrap_time_stamp,
|
|
||||||
uint32_t expected_bitrate_drop_delta,
|
|
||||||
int64_t receiver_clock_offset_change_ms);
|
|
||||||
|
|
||||||
static const uint32_t kDefaultSsrc;
|
|
||||||
|
|
||||||
SimulatedClock clock_; // Time at the receiver.
|
|
||||||
test::TestBitrateObserver bitrate_observer_;
|
|
||||||
std::unique_ptr<AcknowledgedBitrateEstimator> acknowledged_bitrate_estimator_;
|
|
||||||
std::unique_ptr<DelayBasedBwe> bitrate_estimator_;
|
|
||||||
std::unique_ptr<test::StreamGenerator> stream_generator_;
|
|
||||||
int64_t arrival_time_offset_ms_;
|
|
||||||
bool first_update_;
|
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(LegacyDelayBasedBweTest);
|
|
||||||
};
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // MODULES_CONGESTION_CONTROLLER_DELAY_BASED_BWE_UNITTEST_HELPER_H_
|
|
||||||
@ -70,7 +70,6 @@ size_t ReadTrendlineFilterWindowSize() {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace webrtc_cc {
|
|
||||||
|
|
||||||
DelayBasedBwe::Result::Result()
|
DelayBasedBwe::Result::Result()
|
||||||
: updated(false),
|
: updated(false),
|
||||||
@ -312,7 +311,7 @@ bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DelayBasedBwe::SetStartBitrate(int start_bitrate_bps) {
|
void DelayBasedBwe::SetStartBitrate(int start_bitrate_bps) {
|
||||||
RTC_LOG(LS_WARNING) << "BWE Setting start bitrate to: " << start_bitrate_bps;
|
RTC_LOG(LS_INFO) << "BWE Setting start bitrate to: " << start_bitrate_bps;
|
||||||
rate_control_.SetStartBitrate(start_bitrate_bps);
|
rate_control_.SetStartBitrate(start_bitrate_bps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,5 +324,4 @@ void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
|
|||||||
int64_t DelayBasedBwe::GetExpectedBwePeriodMs() const {
|
int64_t DelayBasedBwe::GetExpectedBwePeriodMs() const {
|
||||||
return rate_control_.GetExpectedBandwidthPeriodMs();
|
return rate_control_.GetExpectedBandwidthPeriodMs();
|
||||||
}
|
}
|
||||||
} // namespace webrtc_cc
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -27,8 +27,6 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class RtcEventLog;
|
class RtcEventLog;
|
||||||
|
|
||||||
namespace webrtc_cc {
|
|
||||||
|
|
||||||
class DelayBasedBwe {
|
class DelayBasedBwe {
|
||||||
public:
|
public:
|
||||||
static const int64_t kStreamTimeOutMs = 2000;
|
static const int64_t kStreamTimeOutMs = 2000;
|
||||||
@ -88,7 +86,6 @@ class DelayBasedBwe {
|
|||||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe);
|
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc_cc
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_BASED_BWE_H_
|
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_BASED_BWE_H_
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace webrtc_cc {
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int kNumProbesCluster0 = 5;
|
constexpr int kNumProbesCluster0 = 5;
|
||||||
@ -235,5 +234,4 @@ TEST_F(DelayBasedBweTest, TestInitialOveruse) {
|
|||||||
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000);
|
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc_cc
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -18,8 +18,6 @@
|
|||||||
#include "rtc_base/ptr_util.h"
|
#include "rtc_base/ptr_util.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace webrtc_cc {
|
|
||||||
|
|
||||||
constexpr size_t kMtu = 1200;
|
constexpr size_t kMtu = 1200;
|
||||||
constexpr uint32_t kAcceptedBitrateErrorBps = 50000;
|
constexpr uint32_t kAcceptedBitrateErrorBps = 50000;
|
||||||
|
|
||||||
@ -513,5 +511,4 @@ void DelayBasedBweTest::TestWrappingHelper(int silence_time_s) {
|
|||||||
bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_after);
|
bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_after);
|
||||||
EXPECT_LT(bitrate_after, bitrate_before);
|
EXPECT_LT(bitrate_after, bitrate_before);
|
||||||
}
|
}
|
||||||
} // namespace webrtc_cc
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace webrtc_cc {
|
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
class TestBitrateObserver : public RemoteBitrateObserver {
|
class TestBitrateObserver : public RemoteBitrateObserver {
|
||||||
@ -174,7 +173,6 @@ class DelayBasedBweTest : public ::testing::Test {
|
|||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(DelayBasedBweTest);
|
RTC_DISALLOW_COPY_AND_ASSIGN(DelayBasedBweTest);
|
||||||
};
|
};
|
||||||
} // namespace webrtc_cc
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_BASED_BWE_UNITTEST_HELPER_H_
|
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_DELAY_BASED_BWE_UNITTEST_HELPER_H_
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common_types.h" // NOLINT(build/include)
|
#include "common_types.h" // NOLINT(build/include)
|
||||||
#include "modules/congestion_controller/delay_based_bwe.h"
|
#include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
|
||||||
#include "modules/congestion_controller/include/network_changed_observer.h"
|
#include "modules/congestion_controller/include/network_changed_observer.h"
|
||||||
#include "modules/congestion_controller/include/send_side_congestion_controller_interface.h"
|
#include "modules/congestion_controller/include/send_side_congestion_controller_interface.h"
|
||||||
#include "modules/congestion_controller/transport_feedback_adapter.h"
|
#include "modules/congestion_controller/transport_feedback_adapter.h"
|
||||||
|
|||||||
@ -128,7 +128,7 @@ SendSideCongestionController::SendSideCongestionController(
|
|||||||
pause_pacer_(false),
|
pause_pacer_(false),
|
||||||
pacer_paused_(false),
|
pacer_paused_(false),
|
||||||
min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
|
min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
|
||||||
delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)),
|
delay_based_bwe_(new DelayBasedBwe(event_log_)),
|
||||||
in_cwnd_experiment_(CwndExperimentEnabled()),
|
in_cwnd_experiment_(CwndExperimentEnabled()),
|
||||||
accepted_queue_ms_(kDefaultAcceptedQueueMs),
|
accepted_queue_ms_(kDefaultAcceptedQueueMs),
|
||||||
was_in_alr_(false),
|
was_in_alr_(false),
|
||||||
@ -217,7 +217,7 @@ void SendSideCongestionController::OnNetworkRouteChanged(
|
|||||||
rtc::CritScope cs(&bwe_lock_);
|
rtc::CritScope cs(&bwe_lock_);
|
||||||
transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
|
transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
|
||||||
min_bitrate_bps_ = min_bitrate_bps;
|
min_bitrate_bps_ = min_bitrate_bps;
|
||||||
delay_based_bwe_.reset(new DelayBasedBwe(event_log_, clock_));
|
delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
|
||||||
acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
|
acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
|
||||||
delay_based_bwe_->SetStartBitrate(bitrate_bps);
|
delay_based_bwe_->SetStartBitrate(bitrate_bps);
|
||||||
delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
|
delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
|
||||||
@ -304,7 +304,7 @@ void SendSideCongestionController::OnSentPacket(
|
|||||||
void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
|
void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
|
||||||
int64_t max_rtt_ms) {
|
int64_t max_rtt_ms) {
|
||||||
rtc::CritScope cs(&bwe_lock_);
|
rtc::CritScope cs(&bwe_lock_);
|
||||||
delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
|
delay_based_bwe_->OnRttUpdate(avg_rtt_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SendSideCongestionController::TimeUntilNextProcess() {
|
int64_t SendSideCongestionController::TimeUntilNextProcess() {
|
||||||
@ -367,7 +367,8 @@ void SendSideCongestionController::OnTransportFeedback(
|
|||||||
{
|
{
|
||||||
rtc::CritScope cs(&bwe_lock_);
|
rtc::CritScope cs(&bwe_lock_);
|
||||||
result = delay_based_bwe_->IncomingPacketFeedbackVector(
|
result = delay_based_bwe_->IncomingPacketFeedbackVector(
|
||||||
feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps());
|
feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps(),
|
||||||
|
clock_->TimeInMilliseconds());
|
||||||
}
|
}
|
||||||
if (result.updated) {
|
if (result.updated) {
|
||||||
bitrate_controller_->OnDelayBasedBweResult(result);
|
bitrate_controller_->OnDelayBasedBweResult(result);
|
||||||
|
|||||||
@ -151,8 +151,8 @@ if (rtc_include_tests) {
|
|||||||
"../../test:test_support",
|
"../../test:test_support",
|
||||||
"../bitrate_controller",
|
"../bitrate_controller",
|
||||||
"../congestion_controller",
|
"../congestion_controller",
|
||||||
"../congestion_controller:delay_based_bwe",
|
|
||||||
"../congestion_controller:transport_feedback",
|
"../congestion_controller:transport_feedback",
|
||||||
|
"../congestion_controller/goog_cc:delay_based_bwe",
|
||||||
"../congestion_controller/goog_cc:estimators",
|
"../congestion_controller/goog_cc:estimators",
|
||||||
"../congestion_controller/rtp:transport_feedback",
|
"../congestion_controller/rtp:transport_feedback",
|
||||||
"../pacing",
|
"../pacing",
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "modules/congestion_controller/delay_based_bwe.h"
|
#include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
|
||||||
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/ptr_util.h"
|
#include "rtc_base/ptr_util.h"
|
||||||
@ -32,7 +32,7 @@ SendSideBweSender::SendSideBweSender(int kbps,
|
|||||||
&event_log_)),
|
&event_log_)),
|
||||||
acknowledged_bitrate_estimator_(
|
acknowledged_bitrate_estimator_(
|
||||||
rtc::MakeUnique<AcknowledgedBitrateEstimator>()),
|
rtc::MakeUnique<AcknowledgedBitrateEstimator>()),
|
||||||
bwe_(new DelayBasedBwe(nullptr, clock)),
|
bwe_(new DelayBasedBwe(nullptr)),
|
||||||
feedback_observer_(bitrate_controller_.get()),
|
feedback_observer_(bitrate_controller_.get()),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
send_time_history_(clock_, 10000),
|
send_time_history_(clock_, 10000),
|
||||||
@ -72,7 +72,7 @@ void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) {
|
|||||||
|
|
||||||
int64_t rtt_ms =
|
int64_t rtt_ms =
|
||||||
clock_->TimeInMilliseconds() - feedback.latest_send_time_ms();
|
clock_->TimeInMilliseconds() - feedback.latest_send_time_ms();
|
||||||
bwe_->OnRttUpdate(rtt_ms, rtt_ms);
|
bwe_->OnRttUpdate(rtt_ms);
|
||||||
BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms);
|
BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms);
|
||||||
|
|
||||||
std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(),
|
std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(),
|
||||||
@ -80,7 +80,8 @@ void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) {
|
|||||||
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
|
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
|
||||||
packet_feedback_vector);
|
packet_feedback_vector);
|
||||||
DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector(
|
DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector(
|
||||||
packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps());
|
packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps(),
|
||||||
|
clock_->TimeInMilliseconds());
|
||||||
if (result.updated)
|
if (result.updated)
|
||||||
bitrate_controller_->OnDelayBasedBweResult(result);
|
bitrate_controller_->OnDelayBasedBweResult(result);
|
||||||
|
|
||||||
|
|||||||
@ -239,7 +239,7 @@ if (!build_with_chromium) {
|
|||||||
# TODO(kwiberg): Remove this dependency.
|
# TODO(kwiberg): Remove this dependency.
|
||||||
"../api/audio_codecs:audio_codecs_api",
|
"../api/audio_codecs:audio_codecs_api",
|
||||||
"../modules/congestion_controller",
|
"../modules/congestion_controller",
|
||||||
"../modules/congestion_controller:delay_based_bwe",
|
"../modules/congestion_controller/goog_cc:delay_based_bwe",
|
||||||
"../modules/congestion_controller/goog_cc:estimators",
|
"../modules/congestion_controller/goog_cc:estimators",
|
||||||
"../modules/pacing",
|
"../modules/pacing",
|
||||||
"../modules/rtp_rtcp",
|
"../modules/rtp_rtcp",
|
||||||
|
|||||||
@ -31,9 +31,9 @@
|
|||||||
#include "modules/audio_coding/neteq/tools/neteq_replacement_input.h"
|
#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/neteq_test.h"
|
||||||
#include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
|
#include "modules/audio_coding/neteq/tools/resample_input_audio_file.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/acknowledged_bitrate_estimator.h"
|
||||||
#include "modules/congestion_controller/goog_cc/bitrate_estimator.h"
|
#include "modules/congestion_controller/goog_cc/bitrate_estimator.h"
|
||||||
|
#include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
|
||||||
#include "modules/congestion_controller/include/receive_side_congestion_controller.h"
|
#include "modules/congestion_controller/include/receive_side_congestion_controller.h"
|
||||||
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
|
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
|
||||||
#include "modules/include/module_common_types.h"
|
#include "modules/include/module_common_types.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user