Added implementation of four functions in the BBR congestion controller:
1) Function responsible for receiving feedback, digesting data and deciding switch scenarios. 2) Function which enters Startup mode. 3) Function which exits Startup mode. 4) Function which calculates, whether or not full bandwidth is reached. BUG=webrtc:7713 Review-Url: https://codereview.webrtc.org/2924603002 Cr-Commit-Position: refs/heads/master@{#18901}
This commit is contained in:
parent
bc0c4f581f
commit
191113a46b
@ -75,6 +75,7 @@ if (rtc_include_tests) {
|
||||
"test/estimators/bbr.cc",
|
||||
"test/estimators/bbr.h",
|
||||
"test/estimators/congestion_window.h",
|
||||
"test/estimators/max_bandwidth_filter.cc",
|
||||
"test/estimators/max_bandwidth_filter.h",
|
||||
"test/estimators/min_rtt_filter.h",
|
||||
"test/estimators/nada.cc",
|
||||
|
||||
@ -95,7 +95,7 @@ BweSender* CreateBweSender(BandwidthEstimatorType estimator,
|
||||
case kNadaEstimator:
|
||||
return new NadaBweSender(kbps, observer, clock);
|
||||
case kBbrEstimator:
|
||||
return new BbrBweSender();
|
||||
return new BbrBweSender(clock);
|
||||
case kTcpEstimator:
|
||||
FALLTHROUGH();
|
||||
case kNullEstimator:
|
||||
|
||||
@ -157,7 +157,7 @@ BbrBweFeedback::BbrBweFeedback(
|
||||
int flow_id,
|
||||
int64_t send_time_us,
|
||||
int64_t latest_send_time_ms,
|
||||
const std::vector<std::pair<uint64_t, int64_t>>& packet_feedback_vector)
|
||||
const std::vector<uint64_t>& packet_feedback_vector)
|
||||
: FeedbackPacket(flow_id, send_time_us, latest_send_time_ms),
|
||||
packet_feedback_vector_(packet_feedback_vector) {}
|
||||
|
||||
|
||||
@ -11,18 +11,34 @@
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
BbrBweSender::BbrBweSender() : BweSender() {
|
||||
namespace {
|
||||
const int kFeedbackIntervalsMs = 100;
|
||||
// BBR uses this value to double sending rate each round trip. Design document
|
||||
// suggests using this value.
|
||||
const float kHighGain = 2.885f;
|
||||
// BBR uses this value to drain queues created during STARTUP in one round trip
|
||||
// time.
|
||||
const float kDrainGain = 1 / kHighGain;
|
||||
// kStartupGrowthTarget and kMaxRoundsWithoutGrowth are chosen from
|
||||
// experiments,according to design document.
|
||||
const float kStartupGrowthTarget = 1.25f;
|
||||
const int kMaxRoundsWithoutGrowth = 3;
|
||||
} // namespace
|
||||
|
||||
BbrBweSender::BbrBweSender(Clock* clock)
|
||||
: BweSender(0),
|
||||
clock_(clock),
|
||||
mode_(STARTUP),
|
||||
max_bandwidth_filter_(new MaxBandwidthFilter()),
|
||||
round_count_(0),
|
||||
last_packet_sent_(0),
|
||||
round_trip_end_(0),
|
||||
full_bandwidth_reached_(false) {
|
||||
// Initially enter Startup mode.
|
||||
EnterStartup();
|
||||
}
|
||||
@ -30,18 +46,66 @@ BbrBweSender::BbrBweSender() : BweSender() {
|
||||
BbrBweSender::~BbrBweSender() {}
|
||||
|
||||
int BbrBweSender::GetFeedbackIntervalMs() const {
|
||||
return 0;
|
||||
return kFeedbackIntervalsMs;
|
||||
}
|
||||
|
||||
void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) {}
|
||||
void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) {
|
||||
const BbrBweFeedback& fb = static_cast<const BbrBweFeedback&>(feedback);
|
||||
// feedback_vector holds values of acknowledged packets' sequence numbers.
|
||||
const std::vector<uint64_t>& feedback_vector = fb.packet_feedback_vector();
|
||||
// Check if new round started for the connection. Round is the period of time
|
||||
// from sending packet to its acknowledgement.
|
||||
bool new_round_started = false;
|
||||
if (!feedback_vector.empty()) {
|
||||
uint64_t last_acked_packet = *feedback_vector.rbegin();
|
||||
if (last_acked_packet > round_trip_end_) {
|
||||
new_round_started = true;
|
||||
round_count_++;
|
||||
round_trip_end_ = last_packet_sent_;
|
||||
}
|
||||
}
|
||||
if (new_round_started && !full_bandwidth_reached_) {
|
||||
full_bandwidth_reached_ = max_bandwidth_filter_->FullBandwidthReached(
|
||||
kStartupGrowthTarget, kMaxRoundsWithoutGrowth);
|
||||
}
|
||||
int now = clock_->TimeInMilliseconds();
|
||||
switch (mode_) {
|
||||
break;
|
||||
case STARTUP:
|
||||
TryExitingStartup();
|
||||
break;
|
||||
case DRAIN:
|
||||
TryExitingDrain(now);
|
||||
break;
|
||||
case PROBE_BW:
|
||||
TryUpdatingCyclePhase(now);
|
||||
break;
|
||||
case PROBE_RTT:
|
||||
TryExitingProbeRtt(now);
|
||||
break;
|
||||
}
|
||||
TryEnteringProbeRtt(now);
|
||||
// TODO(gnish): implement functions updating congestion window and pacing rate
|
||||
// controllers.
|
||||
}
|
||||
|
||||
bool BbrBweSender::UpdateBandwidthAndMinRtt() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void BbrBweSender::EnterStartup() {}
|
||||
void BbrBweSender::EnterStartup() {
|
||||
mode_ = STARTUP;
|
||||
pacing_gain_ = kHighGain;
|
||||
congestion_window_gain_ = kHighGain;
|
||||
}
|
||||
|
||||
void BbrBweSender::TryExitingStartup() {}
|
||||
void BbrBweSender::TryExitingStartup() {
|
||||
if (full_bandwidth_reached_) {
|
||||
mode_ = DRAIN;
|
||||
pacing_gain_ = kDrainGain;
|
||||
congestion_window_gain_ = kHighGain;
|
||||
}
|
||||
}
|
||||
|
||||
void BbrBweSender::TryExitingDrain(int64_t now) {}
|
||||
|
||||
@ -49,22 +113,22 @@ void BbrBweSender::EnterProbeBw(int64_t now) {}
|
||||
|
||||
void BbrBweSender::TryUpdatingCyclePhase(int64_t now) {}
|
||||
|
||||
void BbrBweSender::EnterProbeRtt(int64_t now) {}
|
||||
|
||||
void BbrBweSender::TryEnteringProbeRtt(int64_t now) {}
|
||||
void BbrBweSender::TryExitingProbeRtt(int64_t now) {}
|
||||
|
||||
int64_t BbrBweSender::TimeUntilNextProcess() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
void BbrBweSender::OnPacketsSent(const Packets& packets) {}
|
||||
void BbrBweSender::OnPacketsSent(const Packets& packets) {
|
||||
last_packet_sent_ =
|
||||
static_cast<const MediaPacket*>(packets.back())->sequence_number();
|
||||
}
|
||||
|
||||
void BbrBweSender::Process() {}
|
||||
|
||||
BbrBweReceiver::BbrBweReceiver(int flow_id)
|
||||
: BweReceiver(flow_id, kReceivingRateTimeWindowMs),
|
||||
clock_(0),
|
||||
packet_feedbacks_() {}
|
||||
: BweReceiver(flow_id, kReceivingRateTimeWindowMs), clock_(0) {}
|
||||
|
||||
BbrBweReceiver::~BbrBweReceiver() {}
|
||||
|
||||
|
||||
@ -12,14 +12,10 @@
|
||||
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_BBR_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_BBR_H_
|
||||
|
||||
#include <climits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -30,7 +26,7 @@ class MinRttFilter;
|
||||
class CongestionWindow;
|
||||
class BbrBweSender : public BweSender {
|
||||
public:
|
||||
BbrBweSender();
|
||||
explicit BbrBweSender(Clock* clock);
|
||||
virtual ~BbrBweSender();
|
||||
enum Mode {
|
||||
// Startup phase.
|
||||
@ -64,8 +60,21 @@ class BbrBweSender : public BweSender {
|
||||
void TryExitingDrain(int64_t now);
|
||||
void EnterProbeBw(int64_t now);
|
||||
void EnterProbeRtt(int64_t now);
|
||||
void TryExitingProbeRtt(int64_t now);
|
||||
void TryUpdatingCyclePhase(int64_t now);
|
||||
void TryEnteringProbeRtt(int64_t now);
|
||||
void TryExitingProbeRtt(int64_t now);
|
||||
Clock* const clock_;
|
||||
Mode mode_;
|
||||
std::unique_ptr<MaxBandwidthFilter> max_bandwidth_filter_;
|
||||
uint64_t round_count_;
|
||||
uint64_t last_packet_sent_;
|
||||
uint64_t round_trip_end_;
|
||||
float pacing_gain_;
|
||||
float congestion_window_gain_;
|
||||
|
||||
// If optimal bandwidth has been discovered and reached, (for example after
|
||||
// Startup mode) set this variable to true.
|
||||
bool full_bandwidth_reached_;
|
||||
};
|
||||
|
||||
class BbrBweReceiver : public BweReceiver {
|
||||
@ -78,7 +87,6 @@ class BbrBweReceiver : public BweReceiver {
|
||||
|
||||
private:
|
||||
SimulatedClock clock_;
|
||||
std::vector<std::pair<uint64_t, int64_t>> packet_feedbacks_;
|
||||
};
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
|
||||
@ -12,17 +12,6 @@
|
||||
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_CONGESTION_WINDOW_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_CONGESTION_WINDOW_H_
|
||||
|
||||
#include <climits>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
@ -39,10 +28,6 @@ class CongestionWindow {
|
||||
// Ack was received by sender, meaning
|
||||
// packet is no longer inflight.
|
||||
void AckReceived();
|
||||
|
||||
// Returnes whether or not data inflight has been under
|
||||
// fixed value for past x rounds and y ms.
|
||||
bool DataInflightDecreased();
|
||||
};
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
MaxBandwidthFilter::MaxBandwidthFilter() {}
|
||||
|
||||
MaxBandwidthFilter::~MaxBandwidthFilter() {}
|
||||
|
||||
bool MaxBandwidthFilter::FullBandwidthReached(float growth_target,
|
||||
int max_rounds_without_growth) {
|
||||
// Minimal bandwidth necessary to assume that better bandwidth can still be
|
||||
// found and full bandwidth is not reached.
|
||||
int64_t minimal_bandwidth = bandwidth_last_round_ * growth_target;
|
||||
if (max_bandwidth_estimate_ >= minimal_bandwidth) {
|
||||
bandwidth_last_round_ = max_bandwidth_estimate_;
|
||||
rounds_without_growth_ = 0;
|
||||
return false;
|
||||
}
|
||||
rounds_without_growth_++;
|
||||
if (rounds_without_growth_ >= max_rounds_without_growth)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
} // namespace webrtc
|
||||
@ -12,16 +12,7 @@
|
||||
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MAX_BANDWIDTH_FILTER_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MAX_BANDWIDTH_FILTER_H_
|
||||
|
||||
#include <climits>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
@ -29,18 +20,24 @@ namespace bwe {
|
||||
class MaxBandwidthFilter {
|
||||
public:
|
||||
MaxBandwidthFilter();
|
||||
|
||||
~MaxBandwidthFilter();
|
||||
int64_t max_bandwidth_estimate();
|
||||
int64_t max_bandwidth_estimate() { return max_bandwidth_estimate_; }
|
||||
|
||||
// Save bandwidth sample for the current round.
|
||||
// We save bandwidth samples for past 10 rounds to
|
||||
// provide better bandwidth estimate.
|
||||
|
||||
void AddBandwidthSample(int64_t round);
|
||||
void AddBandwidthSample(int64_t sample, int64_t round);
|
||||
|
||||
// Check if bandwidth has grown by certain multiplier for past x rounds,
|
||||
// to decide whether or not delivery rate plateaued.
|
||||
bool DeliveryRateGrows();
|
||||
// to decide whether or not full bandwidth was reached.
|
||||
bool FullBandwidthReached(float growth_target, int max_rounds_without_growth);
|
||||
|
||||
private:
|
||||
int64_t bandwidth_last_round_;
|
||||
int64_t max_bandwidth_estimate_;
|
||||
int64_t rounds_without_growth_;
|
||||
};
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
|
||||
@ -12,16 +12,6 @@
|
||||
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MIN_RTT_FILTER_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MIN_RTT_FILTER_H_
|
||||
|
||||
#include <climits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
@ -32,8 +22,8 @@ class MinRttFilter {
|
||||
int64_t min_rtt();
|
||||
void UpdateMinRtt(int64_t min_rtt);
|
||||
|
||||
// Checks whether or last discovered min_rtt value
|
||||
// is older than x seconds.
|
||||
// Checks whether or not last discovered min_rtt value is older than x
|
||||
// seconds.
|
||||
bool MinRttExpired(int64_t now);
|
||||
void set_min_rtt_discovery_time(int64_t discovery_time);
|
||||
};
|
||||
|
||||
@ -111,20 +111,18 @@ class FeedbackPacket : public Packet {
|
||||
|
||||
class BbrBweFeedback : public FeedbackPacket {
|
||||
public:
|
||||
BbrBweFeedback(
|
||||
int flow_id,
|
||||
int64_t send_time_us,
|
||||
int64_t latest_send_time_ms,
|
||||
const std::vector<std::pair<uint64_t, int64_t>>& packet_feedback_vector);
|
||||
BbrBweFeedback(int flow_id,
|
||||
int64_t send_time_us,
|
||||
int64_t latest_send_time_ms,
|
||||
const std::vector<uint64_t>& packet_feedback_vector);
|
||||
virtual ~BbrBweFeedback() {}
|
||||
|
||||
const std::vector<std::pair<uint64_t, int64_t>>& packet_feedback_vector()
|
||||
const {
|
||||
const std::vector<uint64_t>& packet_feedback_vector() const {
|
||||
return packet_feedback_vector_;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<std::pair<uint64_t, int64_t>> packet_feedback_vector_;
|
||||
const std::vector<uint64_t> packet_feedback_vector_;
|
||||
};
|
||||
|
||||
class RembFeedback : public FeedbackPacket {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user