Skip to content

Commit

Permalink
Adds loss rate filter in BBR controller.
Browse files Browse the repository at this point in the history
Adds a simple loss rate filter to the BBR network congestion controller.
The loss rate is used to control error correction. Previously the value
was reported as zero which would disable error correction.

Bug: webrtc:8415
Change-Id: Icec8f25fcc9509432ea91eaec30b39a024f92b42
Reviewed-on: https://webrtc-review.googlesource.com/78263
Commit-Queue: Sebastian Jansson <[email protected]>
Reviewed-by: Björn Terelius <[email protected]>
Cr-Commit-Position: refs/heads/master@{#23467}
  • Loading branch information
jonex authored and Commit Bot committed May 31, 2018
1 parent 613591a commit 3d8dbcb
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 0 deletions.
14 changes: 14 additions & 0 deletions modules/congestion_controller/bbr/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ rtc_source_set("bbr_controller") {
]
deps = [
":bandwidth_sampler",
":loss_rate_filter",
":rtt_stats",
":windowed_filter",
"../../../api:optional",
Expand Down Expand Up @@ -82,6 +83,16 @@ rtc_source_set("packet_number_indexed_queue") {
]
}

rtc_source_set("loss_rate_filter") {
visibility = [ ":*" ]
sources = [
"loss_rate_filter.cc",
"loss_rate_filter.h",
]
deps = [
"../../../api:optional",
]
}
rtc_source_set("rtt_stats") {
visibility = [ ":*" ]
sources = [
Expand All @@ -107,6 +118,7 @@ if (rtc_include_tests) {
"bandwidth_sampler_unittest.cc",
"bbr_network_controller_unittest.cc",
"data_transfer_tracker_unittest.cc",
"loss_rate_filter_unittest.cc",
"packet_number_indexed_queue_unittest.cc",
"rtt_stats_unittest.cc",
"windowed_filter_unittest.cc",
Expand All @@ -116,12 +128,14 @@ if (rtc_include_tests) {
":bbr",
":bbr_controller",
":data_transfer_tracker",
":loss_rate_filter",
":packet_number_indexed_queue",
":rtt_stats",
":windowed_filter",
"../../../api/transport:network_control_test",
"../../../api/units:data_rate",
"../../../api/units:time_delta",
"../../../api/units:timestamp",
"../../../test:test_support",
]
if (!build_with_chromium && is_clang) {
Expand Down
8 changes: 8 additions & 0 deletions modules/congestion_controller/bbr/bbr_network_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ BbrNetworkController::DebugState::DebugState(const DebugState& state) = default;
BbrNetworkController::BbrNetworkController(NetworkControllerConfig config)
: rtt_stats_(),
random_(10),
loss_rate_(),
mode_(STARTUP),
sampler_(new BandwidthSampler()),
round_trip_count_(0),
Expand Down Expand Up @@ -398,6 +399,13 @@ NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback(
DiscardLostPackets(lost_packets);

std::vector<PacketResult> acked_packets = msg.ReceivedWithSendInfo();

int packets_sent =
static_cast<int>(lost_packets.size() + acked_packets.size());
int packets_lost = static_cast<int>(lost_packets.size());
loss_rate_.UpdateWithLossStatus(msg.feedback_time.ms(), packets_sent,
packets_lost);

// Input the new data into the BBR model of the connection.
if (!acked_packets.empty()) {
int64_t last_acked_packet =
Expand Down
2 changes: 2 additions & 0 deletions modules/congestion_controller/bbr/bbr_network_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "api/transport/network_control.h"
#include "api/transport/network_types.h"
#include "modules/congestion_controller/bbr/bandwidth_sampler.h"
#include "modules/congestion_controller/bbr/loss_rate_filter.h"
#include "modules/congestion_controller/bbr/rtt_stats.h"
#include "modules/congestion_controller/bbr/windowed_filter.h"

Expand Down Expand Up @@ -215,6 +216,7 @@ class BbrNetworkController : public NetworkControllerInterface {

RttStats rtt_stats_;
webrtc::Random random_;
LossRateFilter loss_rate_;

rtc::Optional<TargetRateConstraints> constraints_;

Expand Down
48 changes: 48 additions & 0 deletions modules/congestion_controller/bbr/loss_rate_filter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/congestion_controller/bbr/loss_rate_filter.h"

namespace webrtc {
namespace bbr {
namespace {
// From SendSideBandwidthEstimation.
const int kLimitNumPackets = 20;
// From RTCPSender video report interval.
const int64_t kUpdateIntervalMs = 1000;
} // namespace

LossRateFilter::LossRateFilter()
: lost_packets_since_last_loss_update_(0),
expected_packets_since_last_loss_update_(0),
loss_rate_estimate_(0.0),
next_loss_update_ms_(0) {}

void LossRateFilter::UpdateWithLossStatus(int64_t feedback_time,
int packets_sent,
int packets_lost) {
lost_packets_since_last_loss_update_ += packets_lost;
expected_packets_since_last_loss_update_ += packets_sent;

if (feedback_time >= next_loss_update_ms_ &&
expected_packets_since_last_loss_update_ >= kLimitNumPackets) {
int64_t lost = lost_packets_since_last_loss_update_;
int64_t expected = expected_packets_since_last_loss_update_;
loss_rate_estimate_ = static_cast<double>(lost) / expected;
next_loss_update_ms_ = feedback_time + kUpdateIntervalMs;
lost_packets_since_last_loss_update_ = 0;
expected_packets_since_last_loss_update_ = 0;
}
}

double LossRateFilter::GetLossRate() const {
return loss_rate_estimate_;
}
} // namespace bbr
} // namespace webrtc
38 changes: 38 additions & 0 deletions modules/congestion_controller/bbr/loss_rate_filter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_CONGESTION_CONTROLLER_BBR_LOSS_RATE_FILTER_H_
#define MODULES_CONGESTION_CONTROLLER_BBR_LOSS_RATE_FILTER_H_

#include "api/optional.h"

namespace webrtc {
namespace bbr {

// Loss rate filter based on the implementation in SendSideBandwidthEstimation
// and the RTCPSender receiver report interval for video.
class LossRateFilter {
public:
LossRateFilter();
void UpdateWithLossStatus(int64_t feedback_time_ms,
int packets_sent,
int packets_lost);
double GetLossRate() const;

private:
int lost_packets_since_last_loss_update_;
int expected_packets_since_last_loss_update_;
double loss_rate_estimate_;
int64_t next_loss_update_ms_;
};

} // namespace bbr
} // namespace webrtc

#endif // MODULES_CONGESTION_CONTROLLER_BBR_LOSS_RATE_FILTER_H_
71 changes: 71 additions & 0 deletions modules/congestion_controller/bbr/loss_rate_filter_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/congestion_controller/bbr/loss_rate_filter.h"
#include "api/units/timestamp.h"
#include "test/gtest.h"

namespace webrtc {
namespace bbr {

namespace {
const Timestamp kTestStartTime = Timestamp::seconds(100000);
} // namespace

TEST(LossRateFilterTest, AccumulatesToOne) {
LossRateFilter filter;
Timestamp current_time = kTestStartTime;
for (int i = 0; i < 10; i++) {
filter.UpdateWithLossStatus(current_time.ms(), 10, 10);
current_time += TimeDelta::seconds(1);
}
EXPECT_NEAR(filter.GetLossRate(), 1.0, 0.01);
}

TEST(LossRateFilterTest, StaysAtZero) {
LossRateFilter filter;
Timestamp current_time = kTestStartTime;
for (int i = 0; i < 10; i++) {
filter.UpdateWithLossStatus(current_time.ms(), 10, 0);
current_time += TimeDelta::seconds(1);
}
EXPECT_NEAR(filter.GetLossRate(), 0.0, 0.01);
}

TEST(LossRateFilterTest, VariesWithInput) {
LossRateFilter filter;
Timestamp current_time = kTestStartTime;
for (int j = 0; j < 10; j++) {
for (int i = 0; i < 5; i++) {
filter.UpdateWithLossStatus(current_time.ms(), 10, 10);
current_time += TimeDelta::seconds(1);
}
EXPECT_NEAR(filter.GetLossRate(), 1.0, 0.1);
for (int i = 0; i < 5; i++) {
filter.UpdateWithLossStatus(current_time.ms(), 10, 0);
current_time += TimeDelta::seconds(1);
}
EXPECT_NEAR(filter.GetLossRate(), 0.0, 0.1);
}
}

TEST(LossRateFilterTest, DetectsChangingRate) {
LossRateFilter filter;
Timestamp current_time = kTestStartTime;
for (int per_decile = 0; per_decile < 10; per_decile += 1) {
// Update every 200 ms for 2 seconds
for (int i = 0; i < 10; i++) {
current_time += TimeDelta::ms(200);
filter.UpdateWithLossStatus(current_time.ms(), 10, per_decile);
}
EXPECT_NEAR(filter.GetLossRate(), per_decile / 10.0, 0.05);
}
}
} // namespace bbr
} // namespace webrtc

0 comments on commit 3d8dbcb

Please sign in to comment.