Index: webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
index 0d4dfb4c4b06cc9cba5af3bd7b2f006b29cff23a..fb7d29a387e6a4f45ef17989c59cac4c42f44156 100644 |
--- a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
+++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
@@ -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() {} |