Limit BWE reductions before first measured throughput.

After detecting overuse of the network capacity, the target
bitrate is reduced. Normally, this should happen at most once
per RTT to prevent repeated reductions from the same overuse
signal. This CL fixes a bug that allowed repeated reductions
if an overuse was detected before it had the first reliable
throughput measurement.

The fix is guarded by a field trial. To enable the fix, use
WebRTC-BweInitialBackOffInterval/Enabled-200/

Bug: webrtc:9493
Change-Id: Iae566227fd94ebb8a4449406572158a8b79d9c53
Reviewed-on: https://webrtc-review.googlesource.com/88765
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24021}
This commit is contained in:
Bjorn Terelius
2018-07-18 14:59:56 +02:00
committed by Commit Bot
parent b471c905a4
commit 0c7ec80927
7 changed files with 145 additions and 15 deletions

View File

@ -212,6 +212,7 @@ if (rtc_include_tests) {
"../../pacing",
"../../remote_bitrate_estimator",
"../../rtp_rtcp:rtp_rtcp_format",
"//system_wrappers:field_trial_api",
"//testing/gmock",
"//third_party/abseil-cpp/absl/memory",
]

View File

@ -239,11 +239,9 @@ DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
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.
rate_control_.InitialTimeToReduceFurther(now_ms)) {
// Overusing before we have a measured acknowledged bitrate. Reduce send
// rate by 50% every 200 ms.
// 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);

View File

@ -13,6 +13,7 @@
#include "modules/pacing/paced_sender.h"
#include "rtc_base/constructormagic.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/field_trial.h"
#include "test/field_trial.h"
#include "test/gtest.h"
@ -234,4 +235,58 @@ TEST_F(DelayBasedBweTest, TestInitialOveruse) {
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000);
}
class DelayBasedBweTestWithBackoffTimeoutExperiment : public DelayBasedBweTest {
public:
DelayBasedBweTestWithBackoffTimeoutExperiment()
: DelayBasedBweTest("WebRTC-BweInitialBackOffInterval/Enabled-200/") {}
};
// This test subsumes and improves DelayBasedBweTest.TestInitialOveruse above.
TEST_F(DelayBasedBweTestWithBackoffTimeoutExperiment, 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 frames = 0; frames < 30 && !seen_overuse; ++frames) {
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;
} else if (bitrate_observer_.updated()) {
bitrate_bps = bitrate_observer_.latest_bitrate();
bitrate_observer_.Reset();
}
}
EXPECT_TRUE(seen_overuse);
// Continue generating an additional 15 frames (equivalent to 167 ms) and
// verify that we don't back down further.
for (int frames = 0; frames < 15 && seen_overuse; ++frames) {
bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps);
EXPECT_FALSE(overuse);
if (bitrate_observer_.updated()) {
bitrate_bps = bitrate_observer_.latest_bitrate();
EXPECT_GE(bitrate_bps, kStartBitrate / 2 - 15000);
EXPECT_LE(bitrate_bps, kInitialCapacityBps + 15000);
bitrate_observer_.Reset();
}
}
}
} // namespace webrtc

View File

@ -148,7 +148,20 @@ int64_t StreamGenerator::GenerateFrame(std::vector<PacketFeedback>* packets,
} // namespace test
DelayBasedBweTest::DelayBasedBweTest()
: clock_(100000000),
: field_trial(),
clock_(100000000),
acknowledged_bitrate_estimator_(
absl::make_unique<AcknowledgedBitrateEstimator>()),
bitrate_estimator_(new DelayBasedBwe(nullptr)),
stream_generator_(new test::StreamGenerator(1e6, // Capacity.
clock_.TimeInMicroseconds())),
arrival_time_offset_ms_(0),
first_update_(true) {}
DelayBasedBweTest::DelayBasedBweTest(const std::string& field_trial_string)
: field_trial(
absl::make_unique<test::ScopedFieldTrials>(field_trial_string)),
clock_(100000000),
acknowledged_bitrate_estimator_(
absl::make_unique<AcknowledgedBitrateEstimator>()),
bitrate_estimator_(new DelayBasedBwe(nullptr)),

View File

@ -14,6 +14,7 @@
#include <list>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
@ -22,6 +23,7 @@
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "rtc_base/constructormagic.h"
#include "system_wrappers/include/clock.h"
#include "test/field_trial.h"
#include "test/gtest.h"
namespace webrtc {
@ -114,6 +116,7 @@ class StreamGenerator {
class DelayBasedBweTest : public ::testing::Test {
public:
DelayBasedBweTest();
explicit DelayBasedBweTest(const std::string& field_trial_string);
virtual ~DelayBasedBweTest();
protected:
@ -163,6 +166,8 @@ class DelayBasedBweTest : public ::testing::Test {
static const uint32_t kDefaultSsrc;
std::unique_ptr<test::ScopedFieldTrials>
field_trial; // Must be initialized first.
SimulatedClock clock_; // Time at the receiver.
test::TestBitrateObserver bitrate_observer_;
std::unique_ptr<AcknowledgedBitrateEstimator> acknowledged_bitrate_estimator_;