Enable configuring probes via field trial.
This CL adds a field trial that lets us control the size of the initial probes, how we grow the following probes and how big and frequent our ALR probes are. Bug: webrtc:10394 Change-Id: I6c7783dfada9aaf55cd836dd8991bb7b8ca4993b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/126880 Reviewed-by: Sebastian Jansson <srte@webrtc.org> Commit-Queue: Jonas Olsson <jonasolsson@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27077}
This commit is contained in:
@ -179,6 +179,7 @@ rtc_source_set("probe_controller") {
|
|||||||
"../../../rtc_base:logging",
|
"../../../rtc_base:logging",
|
||||||
"../../../rtc_base:macromagic",
|
"../../../rtc_base:macromagic",
|
||||||
"../../../rtc_base:safe_conversions",
|
"../../../rtc_base:safe_conversions",
|
||||||
|
"../../../rtc_base/experiments:field_trial_parser",
|
||||||
"../../../rtc_base/system:unused",
|
"../../../rtc_base/system:unused",
|
||||||
"../../../system_wrappers:metrics",
|
"../../../system_wrappers:metrics",
|
||||||
"//third_party/abseil-cpp/absl/memory:memory",
|
"//third_party/abseil-cpp/absl/memory:memory",
|
||||||
|
@ -45,15 +45,6 @@ constexpr int kExponentialProbingDisabled = 0;
|
|||||||
// specify max bitrate.
|
// specify max bitrate.
|
||||||
constexpr int64_t kDefaultMaxProbingBitrateBps = 5000000;
|
constexpr int64_t kDefaultMaxProbingBitrateBps = 5000000;
|
||||||
|
|
||||||
// Interval between probes when ALR periodic probing is enabled.
|
|
||||||
constexpr int64_t kAlrPeriodicProbingIntervalMs = 5000;
|
|
||||||
|
|
||||||
// Minimum probe bitrate percentage to probe further for repeated probes,
|
|
||||||
// relative to the previous probe. For example, if 1Mbps probe results in
|
|
||||||
// 80kbps, then we'll probe again at 1.6Mbps. In that case second probe won't be
|
|
||||||
// sent if we get 600kbps from the first one.
|
|
||||||
constexpr int kRepeatedProbeMinPercentage = 70;
|
|
||||||
|
|
||||||
// If the bitrate drops to a factor |kBitrateDropThreshold| or lower
|
// If the bitrate drops to a factor |kBitrateDropThreshold| or lower
|
||||||
// and we recover within |kBitrateDropTimeoutMs|, then we'll send
|
// and we recover within |kBitrateDropTimeoutMs|, then we'll send
|
||||||
// a probe at a fraction |kProbeFractionAfterDrop| of the original bitrate.
|
// a probe at a fraction |kProbeFractionAfterDrop| of the original bitrate.
|
||||||
@ -82,6 +73,9 @@ constexpr char kBweRapidRecoveryExperiment[] =
|
|||||||
// Never probe higher than configured by OnMaxTotalAllocatedBitrate().
|
// Never probe higher than configured by OnMaxTotalAllocatedBitrate().
|
||||||
constexpr char kCappedProbingFieldTrialName[] = "WebRTC-BweCappedProbing";
|
constexpr char kCappedProbingFieldTrialName[] = "WebRTC-BweCappedProbing";
|
||||||
|
|
||||||
|
constexpr char kConfigurableProbingFieldTrialName[] =
|
||||||
|
"WebRTC-Bwe-ConfigurableProbing";
|
||||||
|
|
||||||
void MaybeLogProbeClusterCreated(RtcEventLog* event_log,
|
void MaybeLogProbeClusterCreated(RtcEventLog* event_log,
|
||||||
const ProbeClusterConfig& probe) {
|
const ProbeClusterConfig& probe) {
|
||||||
RTC_DCHECK(event_log);
|
RTC_DCHECK(event_log);
|
||||||
@ -98,6 +92,25 @@ void MaybeLogProbeClusterCreated(RtcEventLog* event_log,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
ProbeControllerConfig::ProbeControllerConfig(
|
||||||
|
const WebRtcKeyValueConfig* key_value_config)
|
||||||
|
: first_exponential_probe_scale_("p1", 3.0),
|
||||||
|
second_exponential_probe_scale_("p2", 6.0),
|
||||||
|
further_exponential_probe_scale_("step_size", 2),
|
||||||
|
further_probe_threshold("further_probe_threshold", 0.7),
|
||||||
|
alr_probing_interval_("alr_interval", TimeDelta::seconds(5)),
|
||||||
|
alr_probe_scale_("alr_scale", 2) {
|
||||||
|
ParseFieldTrial(
|
||||||
|
{&first_exponential_probe_scale_, &second_exponential_probe_scale_,
|
||||||
|
&further_exponential_probe_scale_, &further_probe_threshold,
|
||||||
|
&alr_probing_interval_, &alr_probe_scale_},
|
||||||
|
key_value_config->Lookup(kConfigurableProbingFieldTrialName));
|
||||||
|
}
|
||||||
|
|
||||||
|
ProbeControllerConfig::ProbeControllerConfig(const ProbeControllerConfig&) =
|
||||||
|
default;
|
||||||
|
ProbeControllerConfig::~ProbeControllerConfig() = default;
|
||||||
|
|
||||||
ProbeController::ProbeController(const WebRtcKeyValueConfig* key_value_config,
|
ProbeController::ProbeController(const WebRtcKeyValueConfig* key_value_config,
|
||||||
RtcEventLog* event_log)
|
RtcEventLog* event_log)
|
||||||
: enable_periodic_alr_probing_(false),
|
: enable_periodic_alr_probing_(false),
|
||||||
@ -107,7 +120,8 @@ ProbeController::ProbeController(const WebRtcKeyValueConfig* key_value_config,
|
|||||||
limit_probes_with_allocateable_rate_(
|
limit_probes_with_allocateable_rate_(
|
||||||
key_value_config->Lookup(kCappedProbingFieldTrialName)
|
key_value_config->Lookup(kCappedProbingFieldTrialName)
|
||||||
.find("Disabled") != 0),
|
.find("Disabled") != 0),
|
||||||
event_log_(event_log) {
|
event_log_(event_log),
|
||||||
|
config_(ProbeControllerConfig(key_value_config)) {
|
||||||
Reset(0);
|
Reset(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,8 +218,13 @@ std::vector<ProbeClusterConfig> ProbeController::InitiateExponentialProbing(
|
|||||||
|
|
||||||
// When probing at 1.8 Mbps ( 6x 300), this represents a threshold of
|
// When probing at 1.8 Mbps ( 6x 300), this represents a threshold of
|
||||||
// 1.2 Mbps to continue probing.
|
// 1.2 Mbps to continue probing.
|
||||||
return InitiateProbing(
|
std::vector<int64_t> probes = {static_cast<int64_t>(
|
||||||
at_time_ms, {3 * start_bitrate_bps_, 6 * start_bitrate_bps_}, true);
|
config_.first_exponential_probe_scale_ * start_bitrate_bps_)};
|
||||||
|
if (config_.second_exponential_probe_scale_) {
|
||||||
|
probes.push_back(config_.second_exponential_probe_scale_.Value() *
|
||||||
|
start_bitrate_bps_);
|
||||||
|
}
|
||||||
|
return InitiateProbing(at_time_ms, probes, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ProbeClusterConfig> ProbeController::SetEstimatedBitrate(
|
std::vector<ProbeClusterConfig> ProbeController::SetEstimatedBitrate(
|
||||||
@ -229,8 +248,11 @@ std::vector<ProbeClusterConfig> ProbeController::SetEstimatedBitrate(
|
|||||||
|
|
||||||
if (min_bitrate_to_probe_further_bps_ != kExponentialProbingDisabled &&
|
if (min_bitrate_to_probe_further_bps_ != kExponentialProbingDisabled &&
|
||||||
bitrate_bps > min_bitrate_to_probe_further_bps_) {
|
bitrate_bps > min_bitrate_to_probe_further_bps_) {
|
||||||
// Double the probing bitrate.
|
pending_probes = InitiateProbing(
|
||||||
pending_probes = InitiateProbing(at_time_ms, {2 * bitrate_bps}, true);
|
at_time_ms,
|
||||||
|
{static_cast<int64_t>(config_.further_exponential_probe_scale_ *
|
||||||
|
bitrate_bps)},
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,16 +313,6 @@ std::vector<ProbeClusterConfig> ProbeController::RequestProbe(
|
|||||||
return std::vector<ProbeClusterConfig>();
|
return std::vector<ProbeClusterConfig>();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ProbeClusterConfig> ProbeController::InitiateCapacityProbing(
|
|
||||||
int64_t bitrate_bps,
|
|
||||||
int64_t at_time_ms) {
|
|
||||||
if (state_ != State::kWaitingForProbingResult) {
|
|
||||||
RTC_DCHECK(network_available_);
|
|
||||||
return InitiateProbing(at_time_ms, {2 * bitrate_bps}, true);
|
|
||||||
}
|
|
||||||
return std::vector<ProbeClusterConfig>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProbeController::SetMaxBitrate(int64_t max_bitrate_bps) {
|
void ProbeController::SetMaxBitrate(int64_t max_bitrate_bps) {
|
||||||
max_bitrate_bps_ = max_bitrate_bps;
|
max_bitrate_bps_ = max_bitrate_bps;
|
||||||
}
|
}
|
||||||
@ -339,9 +351,12 @@ std::vector<ProbeClusterConfig> ProbeController::Process(int64_t at_time_ms) {
|
|||||||
if (alr_start_time_ms_ && estimated_bitrate_bps_ > 0) {
|
if (alr_start_time_ms_ && estimated_bitrate_bps_ > 0) {
|
||||||
int64_t next_probe_time_ms =
|
int64_t next_probe_time_ms =
|
||||||
std::max(*alr_start_time_ms_, time_last_probing_initiated_ms_) +
|
std::max(*alr_start_time_ms_, time_last_probing_initiated_ms_) +
|
||||||
kAlrPeriodicProbingIntervalMs;
|
config_.alr_probing_interval_->ms();
|
||||||
if (at_time_ms >= next_probe_time_ms) {
|
if (at_time_ms >= next_probe_time_ms) {
|
||||||
return InitiateProbing(at_time_ms, {estimated_bitrate_bps_ * 2}, true);
|
return InitiateProbing(at_time_ms,
|
||||||
|
{static_cast<int64_t>(estimated_bitrate_bps_ *
|
||||||
|
config_.alr_probe_scale_)},
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,7 +365,7 @@ std::vector<ProbeClusterConfig> ProbeController::Process(int64_t at_time_ms) {
|
|||||||
|
|
||||||
std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
|
std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
|
||||||
int64_t now_ms,
|
int64_t now_ms,
|
||||||
std::initializer_list<int64_t> bitrates_to_probe,
|
std::vector<int64_t> bitrates_to_probe,
|
||||||
bool probe_further) {
|
bool probe_further) {
|
||||||
int64_t max_probe_bitrate_bps =
|
int64_t max_probe_bitrate_bps =
|
||||||
max_bitrate_bps_ > 0 ? max_bitrate_bps_ : kDefaultMaxProbingBitrateBps;
|
max_bitrate_bps_ > 0 ? max_bitrate_bps_ : kDefaultMaxProbingBitrateBps;
|
||||||
@ -389,7 +404,7 @@ std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
|
|||||||
if (probe_further) {
|
if (probe_further) {
|
||||||
state_ = State::kWaitingForProbingResult;
|
state_ = State::kWaitingForProbingResult;
|
||||||
min_bitrate_to_probe_further_bps_ =
|
min_bitrate_to_probe_further_bps_ =
|
||||||
(*(bitrates_to_probe.end() - 1)) * kRepeatedProbeMinPercentage / 100;
|
(*(bitrates_to_probe.end() - 1)) * config_.further_probe_threshold;
|
||||||
} else {
|
} else {
|
||||||
state_ = State::kProbingComplete;
|
state_ = State::kProbingComplete;
|
||||||
min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled;
|
min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled;
|
||||||
|
@ -21,12 +21,34 @@
|
|||||||
#include "api/transport/webrtc_key_value_config.h"
|
#include "api/transport/webrtc_key_value_config.h"
|
||||||
#include "logging/rtc_event_log/rtc_event_log.h"
|
#include "logging/rtc_event_log/rtc_event_log.h"
|
||||||
#include "rtc_base/constructor_magic.h"
|
#include "rtc_base/constructor_magic.h"
|
||||||
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/system/unused.h"
|
#include "rtc_base/system/unused.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
class Clock;
|
class Clock;
|
||||||
|
|
||||||
|
struct ProbeControllerConfig {
|
||||||
|
explicit ProbeControllerConfig(const WebRtcKeyValueConfig* key_value_config);
|
||||||
|
ProbeControllerConfig(const ProbeControllerConfig&);
|
||||||
|
ProbeControllerConfig& operator=(const ProbeControllerConfig&) = default;
|
||||||
|
~ProbeControllerConfig();
|
||||||
|
|
||||||
|
// These parameters configure the initial probes. First we send one or two
|
||||||
|
// probes of sizes p1 * start_bitrate_bps_ and p2 * start_bitrate_bps_.
|
||||||
|
// Then whenever we get a bitrate estimate of at least further_probe_threshold
|
||||||
|
// times the size of the last sent probe we'll send another one of size
|
||||||
|
// step_size times the new estimate.
|
||||||
|
FieldTrialParameter<double> first_exponential_probe_scale_;
|
||||||
|
FieldTrialOptional<double> second_exponential_probe_scale_;
|
||||||
|
FieldTrialParameter<double> further_exponential_probe_scale_;
|
||||||
|
FieldTrialParameter<double> further_probe_threshold;
|
||||||
|
|
||||||
|
// Configures how often we send ALR probes and how big they are.
|
||||||
|
FieldTrialParameter<TimeDelta> alr_probing_interval_;
|
||||||
|
FieldTrialParameter<double> alr_probe_scale_;
|
||||||
|
};
|
||||||
|
|
||||||
// This class controls initiation of probing to estimate initial channel
|
// This class controls initiation of probing to estimate initial channel
|
||||||
// capacity. There is also support for probing during a session when max
|
// capacity. There is also support for probing during a session when max
|
||||||
// bitrate is adjusted by an application.
|
// bitrate is adjusted by an application.
|
||||||
@ -63,9 +85,6 @@ class ProbeController {
|
|||||||
RTC_WARN_UNUSED_RESULT std::vector<ProbeClusterConfig> RequestProbe(
|
RTC_WARN_UNUSED_RESULT std::vector<ProbeClusterConfig> RequestProbe(
|
||||||
int64_t at_time_ms);
|
int64_t at_time_ms);
|
||||||
|
|
||||||
RTC_WARN_UNUSED_RESULT std::vector<ProbeClusterConfig>
|
|
||||||
InitiateCapacityProbing(int64_t bitrate_bps, int64_t at_time_ms);
|
|
||||||
|
|
||||||
// Sets a new maximum probing bitrate, without generating a new probe cluster.
|
// Sets a new maximum probing bitrate, without generating a new probe cluster.
|
||||||
void SetMaxBitrate(int64_t max_bitrate_bps);
|
void SetMaxBitrate(int64_t max_bitrate_bps);
|
||||||
|
|
||||||
@ -90,7 +109,7 @@ class ProbeController {
|
|||||||
InitiateExponentialProbing(int64_t at_time_ms);
|
InitiateExponentialProbing(int64_t at_time_ms);
|
||||||
RTC_WARN_UNUSED_RESULT std::vector<ProbeClusterConfig> InitiateProbing(
|
RTC_WARN_UNUSED_RESULT std::vector<ProbeClusterConfig> InitiateProbing(
|
||||||
int64_t now_ms,
|
int64_t now_ms,
|
||||||
std::initializer_list<int64_t> bitrates_to_probe,
|
std::vector<int64_t> bitrates_to_probe,
|
||||||
bool probe_further);
|
bool probe_further);
|
||||||
|
|
||||||
bool network_available_;
|
bool network_available_;
|
||||||
@ -118,6 +137,8 @@ class ProbeController {
|
|||||||
|
|
||||||
int32_t next_probe_cluster_id_ = 1;
|
int32_t next_probe_cluster_id_ = 1;
|
||||||
|
|
||||||
|
ProbeControllerConfig config_;
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(ProbeController);
|
RTC_DISALLOW_COPY_AND_ASSIGN(ProbeController);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
#include "api/units/timestamp.h"
|
#include "api/units/timestamp.h"
|
||||||
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||||
#include "modules/congestion_controller/goog_cc/probe_controller.h"
|
#include "modules/congestion_controller/goog_cc/probe_controller.h"
|
||||||
|
#include "rtc_base/logging.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
|
#include "test/field_trial.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ class ProbeControllerTest : public ::testing::Test {
|
|||||||
|
|
||||||
FieldTrialBasedConfig field_trial_config_;
|
FieldTrialBasedConfig field_trial_config_;
|
||||||
SimulatedClock clock_;
|
SimulatedClock clock_;
|
||||||
MockRtcEventLog mock_rtc_event_log;
|
NiceMock<MockRtcEventLog> mock_rtc_event_log;
|
||||||
std::unique_ptr<ProbeController> probe_controller_;
|
std::unique_ptr<ProbeController> probe_controller_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,6 +91,7 @@ TEST_F(ProbeControllerTest, InitiatesProbingOnMaxBitrateIncrease) {
|
|||||||
probes = probe_controller_->Process(NowMs());
|
probes = probe_controller_->Process(NowMs());
|
||||||
probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
|
probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
|
||||||
kMaxBitrateBps + 100, NowMs());
|
kMaxBitrateBps + 100, NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100);
|
EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +105,7 @@ TEST_F(ProbeControllerTest, InitiatesProbingOnMaxBitrateIncreaseAtMaxBitrate) {
|
|||||||
probes = probe_controller_->SetEstimatedBitrate(kMaxBitrateBps, NowMs());
|
probes = probe_controller_->SetEstimatedBitrate(kMaxBitrateBps, NowMs());
|
||||||
probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
|
probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
|
||||||
kMaxBitrateBps + 100, NowMs());
|
kMaxBitrateBps + 100, NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100);
|
EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +119,7 @@ TEST_F(ProbeControllerTest, TestExponentialProbing) {
|
|||||||
EXPECT_EQ(probes.size(), 0u);
|
EXPECT_EQ(probes.size(), 0u);
|
||||||
|
|
||||||
probes = probe_controller_->SetEstimatedBitrate(1800, NowMs());
|
probes = probe_controller_->SetEstimatedBitrate(1800, NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * 1800);
|
EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * 1800);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,6 +257,7 @@ TEST_F(ProbeControllerTest, PeriodicProbingAfterReset) {
|
|||||||
// until SetEstimatedBitrate is called with an updated estimate.
|
// until SetEstimatedBitrate is called with an updated estimate.
|
||||||
clock_.AdvanceTimeMilliseconds(10000);
|
clock_.AdvanceTimeMilliseconds(10000);
|
||||||
probes = probe_controller_->Process(NowMs());
|
probes = probe_controller_->Process(NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
EXPECT_EQ(probes[0].target_data_rate.bps(), kStartBitrateBps * 2);
|
EXPECT_EQ(probes[0].target_data_rate.bps(), kStartBitrateBps * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,6 +268,7 @@ TEST_F(ProbeControllerTest, TestExponentialProbingOverflow) {
|
|||||||
// Verify that probe bitrate is capped at the specified max bitrate.
|
// Verify that probe bitrate is capped at the specified max bitrate.
|
||||||
probes =
|
probes =
|
||||||
probe_controller_->SetEstimatedBitrate(60 * kMbpsMultiplier, NowMs());
|
probe_controller_->SetEstimatedBitrate(60 * kMbpsMultiplier, NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
EXPECT_EQ(probes[0].target_data_rate.bps(), 100 * kMbpsMultiplier);
|
EXPECT_EQ(probes[0].target_data_rate.bps(), 100 * kMbpsMultiplier);
|
||||||
// Verify that repeated probes aren't sent.
|
// Verify that repeated probes aren't sent.
|
||||||
probes =
|
probes =
|
||||||
@ -293,6 +300,7 @@ TEST_F(ProbeControllerTest, TestAllocatedBitrateCap) {
|
|||||||
// Probes such as ALR capped at 2x the max allocation limit.
|
// Probes such as ALR capped at 2x the max allocation limit.
|
||||||
clock_.AdvanceTimeMilliseconds(5000);
|
clock_.AdvanceTimeMilliseconds(5000);
|
||||||
probes = probe_controller_->Process(NowMs());
|
probes = probe_controller_->Process(NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * max_allocated_bps);
|
EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * max_allocated_bps);
|
||||||
|
|
||||||
// Remove allocation limit.
|
// Remove allocation limit.
|
||||||
@ -300,8 +308,31 @@ TEST_F(ProbeControllerTest, TestAllocatedBitrateCap) {
|
|||||||
probe_controller_->OnMaxTotalAllocatedBitrate(0, NowMs()).empty());
|
probe_controller_->OnMaxTotalAllocatedBitrate(0, NowMs()).empty());
|
||||||
clock_.AdvanceTimeMilliseconds(5000);
|
clock_.AdvanceTimeMilliseconds(5000);
|
||||||
probes = probe_controller_->Process(NowMs());
|
probes = probe_controller_->Process(NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
EXPECT_EQ(probes[0].target_data_rate.bps(), estimated_bitrate_bps * 2);
|
EXPECT_EQ(probes[0].target_data_rate.bps(), estimated_bitrate_bps * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProbeControllerTest, ConfigurableProbingFieldTrial) {
|
||||||
|
auto trials = test::ScopedFieldTrials(
|
||||||
|
"WebRTC-Bwe-ConfigurableProbing/"
|
||||||
|
"p1:2,p2:5,step_size:3,further_probe_threshold:0.8/");
|
||||||
|
probe_controller_.reset(
|
||||||
|
new ProbeController(&field_trial_config_, &mock_rtc_event_log));
|
||||||
|
auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
|
||||||
|
kMaxBitrateBps, NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 2u);
|
||||||
|
EXPECT_EQ(probes[0].target_data_rate.bps(), 600);
|
||||||
|
EXPECT_EQ(probes[1].target_data_rate.bps(), 1500);
|
||||||
|
|
||||||
|
// Repeated probe should only be sent when estimated bitrate climbs above
|
||||||
|
// 0.8 * 5 * kStartBitrateBps = 1200.
|
||||||
|
probes = probe_controller_->SetEstimatedBitrate(1100, NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 0u);
|
||||||
|
|
||||||
|
probes = probe_controller_->SetEstimatedBitrate(1250, NowMs());
|
||||||
|
EXPECT_EQ(probes.size(), 1u);
|
||||||
|
EXPECT_EQ(probes[0].target_data_rate.bps(), 3 * 1250);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
Reference in New Issue
Block a user