Change behaviour of repeated initial probes

Repeated initial probes are sent every second until
ProbeController::OnMaxAllocatedBitrate is invoked (Media is beeing sent) or 5s has passed.
Each probe has a duration of 100ms, sent in packet bursts every 20ms.

ProbeController::waiting_for_initial_probe_result_ is no longer needed
and is removed.
Setting field trial for duration between probe packets bursts are moved
from BitrateProber to ProbeController.

Bug: webrtc:14928
Change-Id: I3170533f679fc2cc2aa5402e248fa1f6996d3ccd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/350640
Reviewed-by: Diep Bui <diepbp@google.com>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42323}
This commit is contained in:
Per K 2024-05-16 10:42:59 +00:00 committed by WebRTC LUCI CQ
parent d122464b6a
commit b25c747d5d
10 changed files with 148 additions and 89 deletions

View File

@ -214,7 +214,10 @@ struct PacerConfig {
struct ProbeClusterConfig {
Timestamp at_time = Timestamp::PlusInfinity();
DataRate target_data_rate = DataRate::Zero();
// Duration of a probe.
TimeDelta target_duration = TimeDelta::Zero();
// Delta time between sent bursts of packets during probe.
TimeDelta min_probe_delta = TimeDelta::Millis(2);
int32_t target_probe_count = 0;
int32_t id = 0;
};

View File

@ -89,8 +89,10 @@ ProbeControllerConfig::ProbeControllerConfig(
further_exponential_probe_scale("step_size", 2),
further_probe_threshold("further_probe_threshold", 0.7),
abort_further_probe_if_max_lower_than_current("abort_further", false),
repeated_initial_probing_duration("initial_probing_duration",
TimeDelta::Seconds(5)),
repeated_initial_probing_time_period("initial_probing",
TimeDelta::Seconds(5)),
initial_probe_duration("initial_probe_duration", TimeDelta::Millis(100)),
initial_min_probe_delta("initial_min_probe_delta", TimeDelta::Millis(20)),
alr_probing_interval("alr_interval", TimeDelta::Seconds(5)),
alr_probe_scale("alr_scale", 2),
network_state_estimate_probing_interval("network_state_interval",
@ -104,13 +106,13 @@ ProbeControllerConfig::ProbeControllerConfig(
network_state_probe_scale("network_state_scale", 1.0),
network_state_probe_duration("network_state_probe_duration",
TimeDelta::Millis(15)),
probe_on_max_allocated_bitrate_change("probe_max_allocation", true),
first_allocation_probe_scale("alloc_p1", 1),
second_allocation_probe_scale("alloc_p2", 2),
allocation_probe_limit_by_current_scale("alloc_current_bwe_limit"),
min_probe_packets_sent("min_probe_packets_sent", 5),
min_probe_duration("min_probe_duration", TimeDelta::Millis(15)),
min_probe_delta("min_probe_delta", TimeDelta::Millis(2)),
loss_limited_probe_scale("loss_limited_scale", 1.5),
skip_if_estimate_larger_than_fraction_of_max(
"skip_if_est_larger_than_fraction_of_max",
@ -120,7 +122,8 @@ ProbeControllerConfig::ProbeControllerConfig(
&further_exponential_probe_scale,
&further_probe_threshold,
&abort_further_probe_if_max_lower_than_current,
&repeated_initial_probing_duration,
&repeated_initial_probing_time_period,
&initial_probe_duration,
&alr_probing_interval,
&alr_probe_scale,
&probe_on_max_allocated_bitrate_change,
@ -128,6 +131,8 @@ ProbeControllerConfig::ProbeControllerConfig(
&second_allocation_probe_scale,
&allocation_probe_limit_by_current_scale,
&min_probe_duration,
&min_probe_delta,
&initial_min_probe_delta,
&network_state_estimate_probing_interval,
&probe_if_estimate_lower_than_network_state_estimate_ratio,
&estimate_lower_than_network_state_estimate_probing_interval,
@ -217,7 +222,6 @@ std::vector<ProbeClusterConfig> ProbeController::OnMaxTotalAllocatedBitrate(
Timestamp at_time) {
const bool in_alr = alr_start_time_.has_value();
const bool allow_allocation_probe = in_alr;
if (config_.probe_on_max_allocated_bitrate_change &&
state_ == State::kProbingComplete &&
max_total_allocated_bitrate != max_total_allocated_bitrate_ &&
@ -257,6 +261,10 @@ std::vector<ProbeClusterConfig> ProbeController::OnMaxTotalAllocatedBitrate(
return InitiateProbing(at_time, probes, allow_further_probing);
}
if (!max_total_allocated_bitrate.IsZero()) {
last_allowed_repeated_initial_probe_ = at_time;
}
max_total_allocated_bitrate_ = max_total_allocated_bitrate;
return std::vector<ProbeClusterConfig>();
}
@ -285,7 +293,6 @@ void ProbeController::UpdateState(State new_state) {
break;
case State::kProbingComplete:
state_ = State::kProbingComplete;
waiting_for_initial_probe_result_ = false;
min_bitrate_to_probe_further_ = DataRate::PlusInfinity();
break;
}
@ -306,13 +313,13 @@ std::vector<ProbeClusterConfig> ProbeController::InitiateExponentialProbing(
probes.push_back(config_.second_exponential_probe_scale.Value() *
start_bitrate_);
}
waiting_for_initial_probe_result_ = true;
if (repeated_initial_probing_enabled_) {
if (repeated_initial_probing_enabled_ &&
max_total_allocated_bitrate_.IsZero()) {
last_allowed_repeated_initial_probe_ =
at_time + config_.repeated_initial_probing_duration;
at_time + config_.repeated_initial_probing_time_period;
RTC_LOG(LS_INFO) << "Repeated initial probing enabled, last allowed probe: "
<< last_allowed_repeated_initial_probe_
<< "now: " << at_time;
<< " now: " << at_time;
}
return InitiateProbing(at_time, probes, true);
@ -335,8 +342,6 @@ std::vector<ProbeClusterConfig> ProbeController::SetEstimatedBitrate(
if (config_.abort_further_probe_if_max_lower_than_current &&
(bitrate > max_bitrate_ ||
(!max_total_allocated_bitrate_.IsZero() &&
!(waiting_for_initial_probe_result_ &&
repeated_initial_probing_enabled_) &&
bitrate > 2 * max_total_allocated_bitrate_))) {
// No need to continue probing.
min_bitrate_to_probe_further_ = DataRate::PlusInfinity();
@ -425,7 +430,6 @@ void ProbeController::SetNetworkStateEstimate(
void ProbeController::Reset(Timestamp at_time) {
bandwidth_limited_cause_ = BandwidthLimitedCause::kDelayBasedLimited;
state_ = State::kInit;
waiting_for_initial_probe_result_ = false;
min_bitrate_to_probe_further_ = DataRate::PlusInfinity();
time_last_probing_initiated_ = Timestamp::Zero();
estimated_bitrate_ = DataRate::Zero();
@ -437,7 +441,6 @@ void ProbeController::Reset(Timestamp at_time) {
alr_end_time_.reset();
time_of_last_large_drop_ = now;
bitrate_before_last_large_drop_ = DataRate::Zero();
max_total_allocated_bitrate_ = DataRate::Zero();
}
bool ProbeController::TimeForAlrProbe(Timestamp at_time) const {
@ -506,7 +509,6 @@ std::vector<ProbeClusterConfig> ProbeController::Process(Timestamp at_time) {
return {};
}
if (TimeForNextRepeatedInitialProbe(at_time)) {
waiting_for_initial_probe_result_ = true;
return InitiateProbing(
at_time, {estimated_bitrate_ * config_.first_exponential_probe_scale},
true);
@ -518,6 +520,29 @@ std::vector<ProbeClusterConfig> ProbeController::Process(Timestamp at_time) {
return std::vector<ProbeClusterConfig>();
}
ProbeClusterConfig ProbeController::CreateProbeClusterConfig(Timestamp at_time,
DataRate bitrate) {
ProbeClusterConfig config;
config.at_time = at_time;
config.target_data_rate = bitrate;
if (network_estimate_ &&
config_.network_state_estimate_probing_interval->IsFinite()) {
config.target_duration = config_.network_state_probe_duration;
config.min_probe_delta = config_.min_probe_delta;
} else if (at_time < last_allowed_repeated_initial_probe_) {
config.target_duration = config_.initial_probe_duration;
config.min_probe_delta = config_.initial_min_probe_delta;
} else {
config.target_duration = config_.min_probe_duration;
config.min_probe_delta = config_.min_probe_delta;
}
config.target_probe_count = config_.min_probe_packets_sent;
config.id = next_probe_cluster_id_;
next_probe_cluster_id_++;
MaybeLogProbeClusterCreated(event_log_, config);
return config;
}
std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
Timestamp now,
std::vector<DataRate> bitrates_to_probe,
@ -538,9 +563,7 @@ std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
}
DataRate max_probe_bitrate = max_bitrate_;
if (max_total_allocated_bitrate_ > DataRate::Zero() &&
!(repeated_initial_probing_enabled_ &&
waiting_for_initial_probe_result_)) {
if (max_total_allocated_bitrate_ > DataRate::Zero()) {
// If a max allocated bitrate has been configured, allow probing up to 2x
// that rate. This allows some overhead to account for bursty streams,
// which otherwise would have to ramp up when the overshoot is already in
@ -556,7 +579,8 @@ std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
case BandwidthLimitedCause::kRttBasedBackOffHighRtt:
case BandwidthLimitedCause::kDelayBasedLimitedDelayIncreased:
case BandwidthLimitedCause::kLossLimitedBwe:
RTC_LOG(LS_INFO) << "Not sending probe in bandwidth limited state.";
RTC_LOG(LS_INFO) << "Not sending probe in bandwidth limited state. "
<< static_cast<int>(bandwidth_limited_cause_);
return {};
case BandwidthLimitedCause::kLossLimitedBweIncreasing:
estimate_capped_bitrate =
@ -590,21 +614,7 @@ std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
probe_further = false;
}
ProbeClusterConfig config;
config.at_time = now;
config.target_data_rate = bitrate;
if (network_estimate_ &&
config_.network_state_estimate_probing_interval->IsFinite()) {
config.target_duration = config_.network_state_probe_duration;
} else {
config.target_duration = config_.min_probe_duration;
}
config.target_probe_count = config_.min_probe_packets_sent;
config.id = next_probe_cluster_id_;
next_probe_cluster_id_++;
MaybeLogProbeClusterCreated(event_log_, config);
pending_probes.push_back(config);
pending_probes.push_back(CreateProbeClusterConfig(now, bitrate));
}
time_last_probing_initiated_ = now;
if (probe_further) {

View File

@ -45,12 +45,16 @@ struct ProbeControllerConfig {
FieldTrialParameter<bool> abort_further_probe_if_max_lower_than_current;
// Duration of time from the first initial probe where repeated initial probes
// are sent if repeated initial probing is enabled.
FieldTrialParameter<TimeDelta> repeated_initial_probing_duration;
FieldTrialParameter<TimeDelta> repeated_initial_probing_time_period;
// The minimum probing duration of an individual probe during
// the repeated_initial_probing_time_period.
FieldTrialParameter<TimeDelta> initial_probe_duration;
// Delta time between sent bursts of packets in a probe during
// the repeated_initial_probing_time_period.
FieldTrialParameter<TimeDelta> initial_min_probe_delta;
// Configures how often we send ALR probes and how big they are.
FieldTrialParameter<TimeDelta> alr_probing_interval;
FieldTrialParameter<double> alr_probe_scale;
// Configures how often we send probes if NetworkStateEstimate is available.
FieldTrialParameter<TimeDelta> network_state_estimate_probing_interval;
// Periodically probe as long as the ratio between current estimate and
@ -74,6 +78,8 @@ struct ProbeControllerConfig {
FieldTrialParameter<int> min_probe_packets_sent;
// The minimum probing duration.
FieldTrialParameter<TimeDelta> min_probe_duration;
// Delta time between sent bursts of packets in a probe.
FieldTrialParameter<TimeDelta> min_probe_delta;
FieldTrialParameter<double> loss_limited_probe_scale;
// Don't send a probe if min(estimate, network state estimate) is larger than
// this fraction of the set max bitrate.
@ -83,7 +89,7 @@ struct ProbeControllerConfig {
// Reason that bandwidth estimate is limited. Bandwidth estimate can be limited
// by either delay based bwe, or loss based bwe when it increases/decreases the
// estimate.
enum class BandwidthLimitedCause {
enum class BandwidthLimitedCause : int {
kLossLimitedBweIncreasing = 0,
kLossLimitedBwe = 1,
kDelayBasedLimited = 2,
@ -126,8 +132,10 @@ class ProbeController {
void EnablePeriodicAlrProbing(bool enable);
// Probes are sent periodically every 1s during the first 5s after the network
// becomes available. The probes ignores allocated bitrate constraints and
// probe up to max configured bitrate configured via SetBitrates.
// becomes available or until OnMaxTotalAllocatedBitrate is invoked with a
// none zero max_total_allocated_bitrate (there are active streams being
// sent.) Probe rate is up to max configured bitrate configured via
// SetBitrates.
void EnableRepeatedInitialProbing(bool enable);
void SetAlrStartTimeMs(absl::optional<int64_t> alr_start_time);
@ -139,8 +147,9 @@ class ProbeController {
void SetNetworkStateEstimate(webrtc::NetworkStateEstimate estimate);
// Resets the ProbeController to a state equivalent to as if it was just
// created EXCEPT for `enable_periodic_alr_probing_` and
// `network_available_`.
// created EXCEPT for configuration settings like
// `enable_periodic_alr_probing_` `network_available_` and
// `max_total_allocated_bitrate_`.
void Reset(Timestamp at_time);
ABSL_MUST_USE_RESULT std::vector<ProbeClusterConfig> Process(
@ -166,9 +175,10 @@ class ProbeController {
bool TimeForAlrProbe(Timestamp at_time) const;
bool TimeForNetworkStateProbe(Timestamp at_time) const;
bool TimeForNextRepeatedInitialProbe(Timestamp at_time) const;
ProbeClusterConfig CreateProbeClusterConfig(Timestamp at_time,
DataRate bitrate);
bool network_available_;
bool waiting_for_initial_probe_result_ = false;
bool repeated_initial_probing_enabled_ = false;
Timestamp last_allowed_repeated_initial_probe_ = Timestamp::MinusInfinity();
BandwidthLimitedCause bandwidth_limited_cause_ =

View File

@ -378,37 +378,6 @@ TEST(ProbeControllerTest, ExponentialProbingStopIfMaxAllocatedBitrateLow) {
EXPECT_THAT(probes, IsEmpty());
}
TEST(ProbeControllerTest, RepeatedInitialProbingIgnoreLowMaxAllocatedbitrate) {
ProbeControllerFixture fixture;
std::unique_ptr<ProbeController> probe_controller =
fixture.CreateController();
ASSERT_THAT(
probe_controller->OnNetworkAvailability({.network_available = true}),
IsEmpty());
auto probes = probe_controller->SetBitrates(
kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime());
ASSERT_THAT(probes, SizeIs(Gt(0)));
probe_controller->EnableRepeatedInitialProbing(true);
// Repeated probe is sent when estimated bitrate climbs above
// 0.7 * 6 * kStartBitrate = 1260. During the initial probe, we ignore the
// allocation limit and probe up to the max.
probes = probe_controller->OnMaxTotalAllocatedBitrate(kStartBitrate,
fixture.CurrentTime());
EXPECT_THAT(probes, IsEmpty());
probes = probe_controller->SetEstimatedBitrate(
DataRate::BitsPerSec(1800), BandwidthLimitedCause::kDelayBasedLimited,
fixture.CurrentTime());
EXPECT_EQ(probes.size(), 1u);
EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * 1800);
probes = probe_controller->SetEstimatedBitrate(
probes[0].target_data_rate, BandwidthLimitedCause::kDelayBasedLimited,
fixture.CurrentTime());
EXPECT_EQ(probes.size(), 1u);
}
TEST(ProbeControllerTest, InitialProbingToLowMaxAllocatedbitrate) {
ProbeControllerFixture fixture;
std::unique_ptr<ProbeController> probe_controller =
@ -475,6 +444,8 @@ TEST(ProbeControllerTest, RepeatedInitialProbingSendsNewProbeAfterTimeout) {
// Expect a probe every second.
EXPECT_EQ(fixture.CurrentTime() - last_probe_time,
TimeDelta::Seconds(1.1));
EXPECT_EQ(probes[0].min_probe_delta, TimeDelta::Millis(20));
EXPECT_EQ(probes[0].target_duration, TimeDelta::Millis(100));
last_probe_time = fixture.CurrentTime();
} else {
EXPECT_LT(fixture.CurrentTime() - last_probe_time,
@ -486,6 +457,28 @@ TEST(ProbeControllerTest, RepeatedInitialProbingSendsNewProbeAfterTimeout) {
EXPECT_THAT(probe_controller->Process(fixture.CurrentTime()), IsEmpty());
}
TEST(ProbeControllerTest, RepeatedInitialProbingStopIfMaxAllocatedBitrateSet) {
ProbeControllerFixture fixture;
std::unique_ptr<ProbeController> probe_controller =
fixture.CreateController();
probe_controller->EnableRepeatedInitialProbing(true);
ASSERT_THAT(
probe_controller->OnNetworkAvailability({.network_available = true}),
IsEmpty());
auto probes = probe_controller->SetBitrates(
kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime());
EXPECT_THAT(probes, SizeIs(Gt(0)));
fixture.AdvanceTime(TimeDelta::Millis(1100));
probes = probe_controller->Process(fixture.CurrentTime());
EXPECT_THAT(probes, SizeIs(1));
probes = probe_controller->OnMaxTotalAllocatedBitrate(kMinBitrate,
fixture.CurrentTime());
fixture.AdvanceTime(TimeDelta::Millis(1100));
probes = probe_controller->Process(fixture.CurrentTime());
EXPECT_THAT(probes, IsEmpty());
}
TEST(ProbeControllerTest, RequestProbeInAlr) {
ProbeControllerFixture fixture;
std::unique_ptr<ProbeController> probe_controller =
@ -1274,6 +1267,27 @@ TEST(ProbeControllerTest,
EXPECT_TRUE(probes.empty());
}
TEST(ProbeControllerTest, MaxAllocatedBitrateNotReset) {
ProbeControllerFixture fixture;
std::unique_ptr<ProbeController> probe_controller =
fixture.CreateController();
ASSERT_THAT(
probe_controller->OnNetworkAvailability({.network_available = true}),
IsEmpty());
auto probes = probe_controller->SetBitrates(
kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime());
ASSERT_FALSE(probes.empty());
probes = probe_controller->OnMaxTotalAllocatedBitrate(kStartBitrate / 4,
fixture.CurrentTime());
probe_controller->Reset(fixture.CurrentTime());
probes = probe_controller->SetBitrates(kMinBitrate, kStartBitrate,
kMaxBitrate, fixture.CurrentTime());
ASSERT_FALSE(probes.empty());
EXPECT_EQ(probes[0].target_data_rate, kStartBitrate / 4 * 2);
}
TEST(ProbeControllerTest, SkipAlrProbeIfEstimateLargerThanMaxProbe) {
ProbeControllerFixture fixture(
"WebRTC-Bwe-ProbingConfiguration/"

View File

@ -98,6 +98,7 @@ if (rtc_include_tests) {
":interval_budget",
":pacing",
"../../api/task_queue:task_queue",
"../../api/transport:field_trial_based_config",
"../../api/transport:network_control",
"../../api/units:data_rate",
"../../api/units:data_size",

View File

@ -12,7 +12,9 @@
#include <algorithm>
#include "api/field_trials_view.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
@ -26,10 +28,9 @@ constexpr size_t kMaxPendingProbeClusters = 5;
BitrateProberConfig::BitrateProberConfig(
const FieldTrialsView* key_value_config)
: min_probe_delta("min_probe_delta", TimeDelta::Millis(2)),
max_probe_delay("max_probe_delay", TimeDelta::Millis(10)),
: max_probe_delay("max_probe_delay", TimeDelta::Millis(10)),
min_packet_size("min_packet_size", DataSize::Bytes(200)) {
ParseFieldTrial({&min_probe_delta, &max_probe_delay, &min_packet_size},
ParseFieldTrial({&max_probe_delay, &min_packet_size},
key_value_config->Lookup("WebRTC-Bwe-ProbingBehavior"));
}
@ -93,6 +94,7 @@ void BitrateProber::OnIncomingPacket(DataSize packet_size) {
void BitrateProber::CreateProbeCluster(
const ProbeClusterConfig& cluster_config) {
RTC_DCHECK(probing_state_ != ProbingState::kDisabled);
RTC_DCHECK(cluster_config.min_probe_delta > TimeDelta::Zero());
while (!clusters_.empty() &&
(cluster_config.at_time - clusters_.front().requested_at >
@ -109,6 +111,7 @@ void BitrateProber::CreateProbeCluster(
(cluster_config.target_data_rate * cluster_config.target_duration)
.bytes();
RTC_DCHECK_GE(cluster.pace_info.probe_cluster_min_bytes, 0);
cluster.min_probe_delta = cluster_config.min_probe_delta;
cluster.pace_info.send_bitrate = cluster_config.target_data_rate;
cluster.pace_info.probe_cluster_id = cluster_config.id;
clusters_.push(cluster);
@ -164,7 +167,7 @@ DataSize BitrateProber::RecommendedMinProbeSize() const {
return DataSize::Zero();
}
DataRate send_rate = clusters_.front().pace_info.send_bitrate;
return send_rate * config_.min_probe_delta;
return send_rate * clusters_.front().min_probe_delta;
}
void BitrateProber::ProbeSent(Timestamp now, DataSize size) {

View File

@ -16,8 +16,10 @@
#include <queue>
#include "api/transport/field_trial_based_config.h"
#include "api/field_trials_view.h"
#include "api/transport/network_types.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/experiments/field_trial_parser.h"
namespace webrtc {
@ -29,8 +31,6 @@ struct BitrateProberConfig {
BitrateProberConfig& operator=(const BitrateProberConfig&) = default;
~BitrateProberConfig() = default;
// A minimum interval between probes to allow scheduling to be feasible.
FieldTrialParameter<TimeDelta> min_probe_delta;
// Maximum amount of time each probe can be delayed.
FieldTrialParameter<TimeDelta> max_probe_delay;
// This is used to start sending a probe after a large enough packet.
@ -103,9 +103,9 @@ class BitrateProber {
int sent_probes = 0;
int sent_bytes = 0;
TimeDelta min_probe_delta = TimeDelta::Zero();
Timestamp requested_at = Timestamp::MinusInfinity();
Timestamp started_at = Timestamp::MinusInfinity();
int retries = 0;
};
Timestamp CalculateNextProbeTime(const ProbeCluster& cluster) const;

View File

@ -12,6 +12,7 @@
#include <algorithm>
#include "api/transport/field_trial_based_config.h"
#include "api/transport/network_types.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
@ -39,11 +40,13 @@ TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) {
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = kTestBitrate1,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = kTestBitrate2,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 1});
EXPECT_FALSE(prober.is_probing());
@ -100,6 +103,7 @@ TEST(BitrateProberTest, DoesntProbeWithoutRecentPackets) {
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = DataRate::KilobitsPerSec(900),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
EXPECT_FALSE(prober.is_probing());
@ -125,6 +129,7 @@ TEST(BitrateProberTest, DiscardsDelayedProbes) {
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = DataRate::KilobitsPerSec(900),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
@ -154,6 +159,7 @@ TEST(BitrateProberTest, LimitsNumberOfPendingProbeClusters) {
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = DataRate::KilobitsPerSec(900),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
prober.OnIncomingPacket(kProbeSize);
@ -165,6 +171,7 @@ TEST(BitrateProberTest, LimitsNumberOfPendingProbeClusters) {
{.at_time = now,
.target_data_rate = DataRate::KilobitsPerSec(900),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = i});
prober.OnIncomingPacket(kProbeSize);
@ -190,6 +197,7 @@ TEST(BitrateProberTest, DoesntInitializeProbingForSmallPackets) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = DataRate::KilobitsPerSec(1000),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
prober.OnIncomingPacket(DataSize::Bytes(100));
@ -208,6 +216,7 @@ TEST(BitrateProberTest, DoesInitializeProbingForSmallPacketsIfConfigured) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = DataRate::KilobitsPerSec(1000),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
prober.OnIncomingPacket(DataSize::Bytes(10));
@ -224,6 +233,7 @@ TEST(BitrateProberTest, VerifyProbeSizeOnHighBitrate) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = kHighBitrate,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
// Probe size should ensure a minimum of 1 ms interval.
@ -231,10 +241,9 @@ TEST(BitrateProberTest, VerifyProbeSizeOnHighBitrate) {
kHighBitrate * TimeDelta::Millis(1));
}
TEST(BitrateProberTest, ProbeSizeCanBeSetWithFieldTrial) {
const test::ExplicitKeyValueConfig trials(
"WebRTC-Bwe-ProbingBehavior/min_probe_delta:20ms/");
BitrateProber prober(trials);
TEST(BitrateProberTest, ProbeSizeCanBeSetInProbeClusterConfig) {
const FieldTrialBasedConfig config;
BitrateProber prober(config);
prober.SetEnabled(true);
const DataRate kHighBitrate = DataRate::KilobitsPerSec(10000); // 10 Mbps
@ -242,6 +251,7 @@ TEST(BitrateProberTest, ProbeSizeCanBeSetWithFieldTrial) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = kHighBitrate,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(20),
.target_probe_count = 5,
.id = 0});
EXPECT_EQ(prober.RecommendedMinProbeSize(),
@ -267,6 +277,7 @@ TEST(BitrateProberTest, MinumumNumberOfProbingPackets) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = kBitrate,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
@ -290,6 +301,7 @@ TEST(BitrateProberTest, ScaleBytesUsedForProbing) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = kBitrate,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
prober.OnIncomingPacket(kPacketSize);
@ -314,6 +326,7 @@ TEST(BitrateProberTest, HighBitrateProbing) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = kBitrate,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
prober.OnIncomingPacket(kPacketSize);
@ -340,6 +353,7 @@ TEST(BitrateProberTest, ProbeClusterTimeout) {
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = kBitrate,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
prober.OnIncomingPacket(kSmallPacketSize);
@ -348,6 +362,7 @@ TEST(BitrateProberTest, ProbeClusterTimeout) {
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = kBitrate / 10,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 1});
prober.OnIncomingPacket(kSmallPacketSize);
@ -356,6 +371,7 @@ TEST(BitrateProberTest, ProbeClusterTimeout) {
prober.CreateProbeCluster({.at_time = now,
.target_data_rate = kBitrate / 10,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 2});
prober.OnIncomingPacket(kSmallPacketSize);
@ -378,6 +394,7 @@ TEST(BitrateProberTest, CanProbeImmediatelyIfConfigured) {
prober.CreateProbeCluster({.at_time = Timestamp::Zero(),
.target_data_rate = DataRate::KilobitsPerSec(300),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 5,
.id = 0});
EXPECT_TRUE(prober.is_probing());
@ -392,6 +409,7 @@ TEST(BitrateProberTest, CanProbeImmediatelyAgainAfterProbeIfConfigured) {
.at_time = Timestamp::Zero(),
.target_data_rate = DataRate::KilobitsPerSec(300),
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = TimeDelta::Millis(2),
.target_probe_count = 1,
.id = 0};
prober.CreateProbeCluster(cluster_config);

View File

@ -443,8 +443,7 @@ TEST(TaskQueuePacedSenderTest, SchedulesProbeAtSentTime) {
TEST(TaskQueuePacedSenderTest, NoMinSleepTimeWhenProbing) {
// Set min_probe_delta to be less than kMinSleepTime (1ms).
const TimeDelta kMinProbeDelta = TimeDelta::Micros(200);
ScopedKeyValueConfig trials(
"WebRTC-Bwe-ProbingBehavior/min_probe_delta:200us/");
ScopedKeyValueConfig trials;
GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
MockPacketRouter packet_router;
TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
@ -473,6 +472,7 @@ TEST(TaskQueuePacedSenderTest, NoMinSleepTimeWhenProbing) {
{{.at_time = time_controller.GetClock()->CurrentTime(),
.target_data_rate = kProbingRate,
.target_duration = TimeDelta::Millis(15),
.min_probe_delta = kMinProbeDelta,
.target_probe_count = 5,
.id = kProbeClusterId}});

View File

@ -199,7 +199,7 @@ TEST_P(BweRampupWithInitialProbeTest, BweRampUpBothDirectionsWithoutMedia) {
// Test that 1s after offer/answer exchange finish, we have a BWE estimate,
// even though no video frames have been sent.
s.ProcessMessages(TimeDelta::Seconds(1));
s.ProcessMessages(TimeDelta::Seconds(2));
auto callee_inbound_stats =
GetStatsAndProcess(s, callee)->GetStatsOfType<RTCInboundRtpStreamStats>();