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:
committed by
Commit Bot
parent
b471c905a4
commit
0c7ec80927
@ -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",
|
||||
]
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)),
|
||||
|
||||
@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user