Using data unit classes in DelayBasedBwe.

Bug: webrtc:9718
Change-Id: I1b6ed37afd7680dfad6267addfe46155c378525d
Reviewed-on: https://webrtc-review.googlesource.com/c/110903
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25702}
This commit is contained in:
Sebastian Jansson 2018-11-19 18:01:17 +01:00 committed by Commit Bot
parent 2e0c655bc6
commit b6787bcd79
17 changed files with 201 additions and 179 deletions

View File

@ -153,14 +153,12 @@ void BitrateControllerImpl::OnDelayBasedBweResult(
rtc::CritScope cs(&critsect_); rtc::CritScope cs(&critsect_);
if (result.probe) { if (result.probe) {
bandwidth_estimation_.SetSendBitrate( bandwidth_estimation_.SetSendBitrate(
DataRate::bps(result.target_bitrate_bps), result.target_bitrate, Timestamp::ms(clock_->TimeInMilliseconds()));
Timestamp::ms(clock_->TimeInMilliseconds()));
} }
// Since SetSendBitrate now resets the delay-based estimate, we have to call // Since SetSendBitrate now resets the delay-based estimate, we have to call
// UpdateDelayBasedEstimate after SetSendBitrate. // UpdateDelayBasedEstimate after SetSendBitrate.
bandwidth_estimation_.UpdateDelayBasedEstimate( bandwidth_estimation_.UpdateDelayBasedEstimate(
Timestamp::ms(clock_->TimeInMilliseconds()), Timestamp::ms(clock_->TimeInMilliseconds()), result.target_bitrate);
DataRate::bps(result.target_bitrate_bps));
} }
MaybeTriggerOnNetworkChanged(); MaybeTriggerOnNetworkChanged();
} }

View File

@ -169,7 +169,7 @@ TEST_F(BitrateControllerTest, OneBitrateObserverOneRtcpObserver) {
EXPECT_EQ(300000, bitrate_observer_.last_bitrate_); EXPECT_EQ(300000, bitrate_observer_.last_bitrate_);
// Test that a low delay-based estimate limits the combined estimate. // Test that a low delay-based estimate limits the combined estimate.
webrtc::DelayBasedBwe::Result result(false, 280000); webrtc::DelayBasedBwe::Result result(false, webrtc::DataRate::kbps(280));
controller_->OnDelayBasedBweResult(result); controller_->OnDelayBasedBweResult(result);
EXPECT_EQ(280000, bitrate_observer_.last_bitrate_); EXPECT_EQ(280000, bitrate_observer_.last_bitrate_);

View File

@ -275,13 +275,12 @@ void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(Timestamp at_time,
void SendSideBandwidthEstimation::IncomingPacketFeedbackVector( void SendSideBandwidthEstimation::IncomingPacketFeedbackVector(
const TransportPacketsFeedback& report, const TransportPacketsFeedback& report,
absl::optional<uint32_t> acked_bitrate_bps) { absl::optional<DataRate> acked_bitrate) {
if (!loss_based_bandwidth_estimation_.Enabled()) if (!loss_based_bandwidth_estimation_.Enabled())
return; return;
if (acked_bitrate_bps) { if (acked_bitrate) {
DataRate acked_bitrate = DataRate::bps(*acked_bitrate_bps);
loss_based_bandwidth_estimation_.UpdateAcknowledgedBitrate( loss_based_bandwidth_estimation_.UpdateAcknowledgedBitrate(
acked_bitrate, report.feedback_time); *acked_bitrate, report.feedback_time);
} }
loss_based_bandwidth_estimation_.UpdateLossStatistics(report.packet_feedbacks, loss_based_bandwidth_estimation_.UpdateLossStatistics(report.packet_feedbacks,
report.feedback_time); report.feedback_time);

View File

@ -91,7 +91,7 @@ class SendSideBandwidthEstimation {
void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate); void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate);
int GetMinBitrate() const; int GetMinBitrate() const;
void IncomingPacketFeedbackVector(const TransportPacketsFeedback& report, void IncomingPacketFeedbackVector(const TransportPacketsFeedback& report,
absl::optional<uint32_t> acked_bitrate_bps); absl::optional<DataRate> acked_bitrate);
private: private:
enum UmaState { kNoUpdate, kFirstDone, kDone }; enum UmaState { kNoUpdate, kFirstDone, kDone };

View File

@ -97,6 +97,7 @@ rtc_source_set("estimators") {
] ]
deps = [ deps = [
"../../../api/units:data_rate",
"../../../logging:rtc_event_bwe", "../../../logging:rtc_event_bwe",
"../../../logging:rtc_event_log_api", "../../../logging:rtc_event_log_api",
"../../../rtc_base:checks", "../../../rtc_base:checks",

View File

@ -72,6 +72,18 @@ absl::optional<uint32_t> AcknowledgedBitrateEstimator::PeekBps() const {
return bitrate_estimator_->PeekBps(); return bitrate_estimator_->PeekBps();
} }
absl::optional<DataRate> AcknowledgedBitrateEstimator::bitrate() const {
if (bitrate_bps())
return DataRate::bps(*bitrate_bps());
return absl::nullopt;
}
absl::optional<DataRate> AcknowledgedBitrateEstimator::PeekRate() const {
if (PeekBps())
return DataRate::bps(*PeekBps());
return absl::nullopt;
}
void AcknowledgedBitrateEstimator::SetAlrEndedTimeMs( void AcknowledgedBitrateEstimator::SetAlrEndedTimeMs(
int64_t alr_ended_time_ms) { int64_t alr_ended_time_ms) {
alr_ended_time_ms_.emplace(alr_ended_time_ms); alr_ended_time_ms_.emplace(alr_ended_time_ms);

View File

@ -17,6 +17,8 @@
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "modules/congestion_controller/goog_cc/bitrate_estimator.h" #include "modules/congestion_controller/goog_cc/bitrate_estimator.h"
#include "api/units/data_rate.h"
namespace webrtc { namespace webrtc {
struct PacketFeedback; struct PacketFeedback;
@ -33,6 +35,8 @@ class AcknowledgedBitrateEstimator {
const std::vector<PacketFeedback>& packet_feedback_vector); const std::vector<PacketFeedback>& packet_feedback_vector);
absl::optional<uint32_t> bitrate_bps() const; absl::optional<uint32_t> bitrate_bps() const;
absl::optional<uint32_t> PeekBps() const; absl::optional<uint32_t> PeekBps() const;
absl::optional<DataRate> bitrate() const;
absl::optional<DataRate> PeekRate() const;
void SetAlrEndedTimeMs(int64_t alr_ended_time_ms); void SetAlrEndedTimeMs(int64_t alr_ended_time_ms);
void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps); void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps);

View File

@ -27,8 +27,9 @@
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
#include "system_wrappers/include/metrics.h" #include "system_wrappers/include/metrics.h"
namespace webrtc {
namespace { namespace {
static const int64_t kStreamTimeOutMs = 2000; constexpr TimeDelta kStreamTimeOut = TimeDelta::Seconds<2>();
constexpr int kTimestampGroupLengthMs = 5; constexpr int kTimestampGroupLengthMs = 5;
constexpr int kAbsSendTimeFraction = 18; constexpr int kAbsSendTimeFraction = 18;
constexpr int kAbsSendTimeInterArrivalUpshift = 8; constexpr int kAbsSendTimeInterArrivalUpshift = 8;
@ -67,18 +68,16 @@ size_t ReadTrendlineFilterWindowSize() {
} }
} // namespace } // namespace
namespace webrtc {
DelayBasedBwe::Result::Result() DelayBasedBwe::Result::Result()
: updated(false), : updated(false),
probe(false), probe(false),
target_bitrate_bps(0), target_bitrate(DataRate::Zero()),
recovered_from_overuse(false) {} recovered_from_overuse(false) {}
DelayBasedBwe::Result::Result(bool probe, uint32_t target_bitrate_bps) DelayBasedBwe::Result::Result(bool probe, DataRate target_bitrate)
: updated(true), : updated(true),
probe(probe), probe(probe),
target_bitrate_bps(target_bitrate_bps), target_bitrate(target_bitrate),
recovered_from_overuse(false) {} recovered_from_overuse(false) {}
DelayBasedBwe::Result::~Result() {} DelayBasedBwe::Result::~Result() {}
@ -87,7 +86,7 @@ DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log)
: event_log_(event_log), : event_log_(event_log),
inter_arrival_(), inter_arrival_(),
delay_detector_(), delay_detector_(),
last_seen_packet_ms_(-1), last_seen_packet_(Timestamp::MinusInfinity()),
uma_recorded_(false), uma_recorded_(false),
probe_bitrate_estimator_(event_log), probe_bitrate_estimator_(event_log),
trendline_window_size_( trendline_window_size_(
@ -97,7 +96,7 @@ DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log)
trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff),
trendline_threshold_gain_(kDefaultTrendlineThresholdGain), trendline_threshold_gain_(kDefaultTrendlineThresholdGain),
consecutive_delayed_feedbacks_(0), consecutive_delayed_feedbacks_(0),
prev_bitrate_(0), prev_bitrate_(DataRate::Zero()),
prev_state_(BandwidthUsage::kBwNormal) { prev_state_(BandwidthUsage::kBwNormal) {
RTC_LOG(LS_INFO) RTC_LOG(LS_INFO)
<< "Using Trendline filter for delay change estimation with window size " << "Using Trendline filter for delay change estimation with window size "
@ -111,8 +110,8 @@ DelayBasedBwe::~DelayBasedBwe() {}
DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
const std::vector<PacketFeedback>& packet_feedback_vector, const std::vector<PacketFeedback>& packet_feedback_vector,
absl::optional<uint32_t> acked_bitrate_bps, absl::optional<DataRate> acked_bitrate,
int64_t at_time_ms) { Timestamp at_time) {
RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(), RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(),
packet_feedback_vector.end(), packet_feedback_vector.end(),
PacketFeedbackComparator())); PacketFeedbackComparator()));
@ -139,7 +138,7 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
if (packet_feedback.send_time_ms < 0) if (packet_feedback.send_time_ms < 0)
continue; continue;
delayed_feedback = false; delayed_feedback = false;
IncomingPacketFeedback(packet_feedback, at_time_ms); IncomingPacketFeedback(packet_feedback, at_time);
if (prev_detector_state == BandwidthUsage::kBwUnderusing && if (prev_detector_state == BandwidthUsage::kBwUnderusing &&
delay_detector_->State() == BandwidthUsage::kBwNormal) { delay_detector_->State() == BandwidthUsage::kBwNormal) {
recovered_from_overuse = true; recovered_from_overuse = true;
@ -148,50 +147,51 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
} }
if (delayed_feedback) { if (delayed_feedback) {
return OnDelayedFeedback(packet_feedback_vector.back().arrival_time_ms); Timestamp arrival_time = Timestamp::PlusInfinity();
if (packet_feedback_vector.back().arrival_time_ms > 0)
arrival_time =
Timestamp::ms(packet_feedback_vector.back().arrival_time_ms);
return OnDelayedFeedback(arrival_time);
} else { } else {
consecutive_delayed_feedbacks_ = 0; consecutive_delayed_feedbacks_ = 0;
return MaybeUpdateEstimate(acked_bitrate_bps, recovered_from_overuse, return MaybeUpdateEstimate(acked_bitrate, recovered_from_overuse, at_time);
at_time_ms);
} }
return Result(); return Result();
} }
DelayBasedBwe::Result DelayBasedBwe::OnDelayedFeedback( DelayBasedBwe::Result DelayBasedBwe::OnDelayedFeedback(Timestamp receive_time) {
int64_t receive_time_ms) {
++consecutive_delayed_feedbacks_; ++consecutive_delayed_feedbacks_;
if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) {
consecutive_delayed_feedbacks_ = 0; consecutive_delayed_feedbacks_ = 0;
return OnLongFeedbackDelay(receive_time_ms); return OnLongFeedbackDelay(receive_time);
} }
return Result(); return Result();
} }
DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay(
int64_t arrival_time_ms) { Timestamp arrival_time) {
// Estimate should always be valid since a start bitrate always is set in the // Estimate should always be valid since a start bitrate always is set in the
// Call constructor. An alternative would be to return an empty Result here, // Call constructor. An alternative would be to return an empty Result here,
// or to estimate the throughput based on the feedback we received. // or to estimate the throughput based on the feedback we received.
RTC_DCHECK(rate_control_.ValidEstimate()); RTC_DCHECK(rate_control_.ValidEstimate());
rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2,
arrival_time_ms); arrival_time.ms());
Result result; Result result;
result.updated = true; result.updated = true;
result.probe = false; result.probe = false;
result.target_bitrate_bps = rate_control_.LatestEstimate(); result.target_bitrate = DataRate::bps(rate_control_.LatestEstimate());
RTC_LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to " RTC_LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to "
<< result.target_bitrate_bps; << ToString(result.target_bitrate);
return result; return result;
} }
void DelayBasedBwe::IncomingPacketFeedback( void DelayBasedBwe::IncomingPacketFeedback(
const PacketFeedback& packet_feedback, const PacketFeedback& packet_feedback,
int64_t at_time_ms) { Timestamp at_time) {
int64_t now_ms = at_time_ms;
// Reset if the stream has timed out. // Reset if the stream has timed out.
if (last_seen_packet_ms_ == -1 || if (last_seen_packet_.IsInfinite() ||
now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { at_time - last_seen_packet_ > kStreamTimeOut) {
inter_arrival_.reset( inter_arrival_.reset(
new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
kTimestampToMs, true)); kTimestampToMs, true));
@ -199,7 +199,7 @@ void DelayBasedBwe::IncomingPacketFeedback(
trendline_smoothing_coeff_, trendline_smoothing_coeff_,
trendline_threshold_gain_)); trendline_threshold_gain_));
} }
last_seen_packet_ms_ = now_ms; last_seen_packet_ = at_time;
uint32_t send_time_24bits = uint32_t send_time_24bits =
static_cast<uint32_t>( static_cast<uint32_t>(
@ -216,7 +216,7 @@ void DelayBasedBwe::IncomingPacketFeedback(
int64_t t_delta = 0; int64_t t_delta = 0;
int size_delta = 0; int size_delta = 0;
if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms, if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms,
now_ms, packet_feedback.payload_size, at_time.ms(), packet_feedback.payload_size,
&ts_delta, &t_delta, &size_delta)) { &ts_delta, &t_delta, &size_delta)) {
double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
delay_detector_->Update(t_delta, ts_delta_ms, delay_detector_->Update(t_delta, ts_delta_ms,
@ -229,102 +229,105 @@ void DelayBasedBwe::IncomingPacketFeedback(
} }
DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate( DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
absl::optional<uint32_t> acked_bitrate_bps, absl::optional<DataRate> acked_bitrate,
bool recovered_from_overuse, bool recovered_from_overuse,
int64_t at_time_ms) { Timestamp at_time) {
Result result; Result result;
int64_t now_ms = at_time_ms;
absl::optional<int> probe_bitrate_bps = absl::optional<DataRate> probe_bitrate =
probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps(); probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrate();
// Currently overusing the bandwidth. // Currently overusing the bandwidth.
if (delay_detector_->State() == BandwidthUsage::kBwOverusing) { if (delay_detector_->State() == BandwidthUsage::kBwOverusing) {
if (acked_bitrate_bps && if (acked_bitrate &&
rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { rate_control_.TimeToReduceFurther(at_time.ms(), acked_bitrate->bps())) {
result.updated = result.updated =
UpdateEstimate(now_ms, acked_bitrate_bps, &result.target_bitrate_bps); UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate);
} else if (!acked_bitrate_bps && rate_control_.ValidEstimate() && } else if (!acked_bitrate && rate_control_.ValidEstimate() &&
rate_control_.InitialTimeToReduceFurther(now_ms)) { rate_control_.InitialTimeToReduceFurther(at_time.ms())) {
// Overusing before we have a measured acknowledged bitrate. Reduce send // Overusing before we have a measured acknowledged bitrate. Reduce send
// rate by 50% every 200 ms. // rate by 50% every 200 ms.
// TODO(tschumim): Improve this and/or the acknowledged bitrate estimator // TODO(tschumim): Improve this and/or the acknowledged bitrate estimator
// so that we (almost) always have a bitrate estimate. // so that we (almost) always have a bitrate estimate.
rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, now_ms); rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2,
at_time.ms());
result.updated = true; result.updated = true;
result.probe = false; result.probe = false;
result.target_bitrate_bps = rate_control_.LatestEstimate(); result.target_bitrate = DataRate::bps(rate_control_.LatestEstimate());
} }
} else { } else {
if (probe_bitrate_bps) { if (probe_bitrate) {
result.probe = true; result.probe = true;
result.updated = true; result.updated = true;
result.target_bitrate_bps = *probe_bitrate_bps; result.target_bitrate = *probe_bitrate;
rate_control_.SetEstimate(*probe_bitrate_bps, now_ms); rate_control_.SetEstimate(probe_bitrate->bps(), at_time.ms());
} else { } else {
result.updated = result.updated =
UpdateEstimate(now_ms, acked_bitrate_bps, &result.target_bitrate_bps); UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate);
result.recovered_from_overuse = recovered_from_overuse; result.recovered_from_overuse = recovered_from_overuse;
} }
} }
BandwidthUsage detector_state = delay_detector_->State(); BandwidthUsage detector_state = delay_detector_->State();
if ((result.updated && prev_bitrate_ != result.target_bitrate_bps) || if ((result.updated && prev_bitrate_ != result.target_bitrate) ||
detector_state != prev_state_) { detector_state != prev_state_) {
uint32_t bitrate_bps = DataRate bitrate = result.updated ? result.target_bitrate : prev_bitrate_;
result.updated ? result.target_bitrate_bps : prev_bitrate_;
BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, bitrate_bps); BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", at_time.ms(), bitrate.bps());
if (event_log_) { if (event_log_) {
event_log_->Log(absl::make_unique<RtcEventBweUpdateDelayBased>( event_log_->Log(absl::make_unique<RtcEventBweUpdateDelayBased>(
bitrate_bps, detector_state)); bitrate.bps(), detector_state));
} }
prev_bitrate_ = bitrate_bps; prev_bitrate_ = bitrate;
prev_state_ = detector_state; prev_state_ = detector_state;
} }
return result; return result;
} }
bool DelayBasedBwe::UpdateEstimate(int64_t now_ms, bool DelayBasedBwe::UpdateEstimate(Timestamp at_time,
absl::optional<uint32_t> acked_bitrate_bps, absl::optional<DataRate> acked_bitrate,
uint32_t* target_bitrate_bps) { DataRate* target_rate) {
absl::optional<int> acked_bitrate_bps;
if (acked_bitrate)
acked_bitrate_bps = acked_bitrate->bps<int>();
const RateControlInput input(delay_detector_->State(), acked_bitrate_bps); const RateControlInput input(delay_detector_->State(), acked_bitrate_bps);
*target_bitrate_bps = rate_control_.Update(&input, now_ms); *target_rate = DataRate::bps(rate_control_.Update(&input, at_time.ms()));
return rate_control_.ValidEstimate(); return rate_control_.ValidEstimate();
} }
void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms) { void DelayBasedBwe::OnRttUpdate(TimeDelta avg_rtt) {
rate_control_.SetRtt(avg_rtt_ms); rate_control_.SetRtt(avg_rtt.ms());
} }
bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
uint32_t* bitrate_bps) const { DataRate* bitrate) const {
// Currently accessed from both the process thread (see // Currently accessed from both the process thread (see
// ModuleRtpRtcpImpl::Process()) and the configuration thread (see // ModuleRtpRtcpImpl::Process()) and the configuration thread (see
// Call::GetStats()). Should in the future only be accessed from a single // Call::GetStats()). Should in the future only be accessed from a single
// thread. // thread.
RTC_DCHECK(ssrcs); RTC_DCHECK(ssrcs);
RTC_DCHECK(bitrate_bps); RTC_DCHECK(bitrate);
if (!rate_control_.ValidEstimate()) if (!rate_control_.ValidEstimate())
return false; return false;
*ssrcs = {kFixedSsrc}; *ssrcs = {kFixedSsrc};
*bitrate_bps = rate_control_.LatestEstimate(); *bitrate = DataRate::bps(rate_control_.LatestEstimate());
return true; return true;
} }
void DelayBasedBwe::SetStartBitrate(int start_bitrate_bps) { void DelayBasedBwe::SetStartBitrate(DataRate start_bitrate) {
RTC_LOG(LS_INFO) << "BWE Setting start bitrate to: " << start_bitrate_bps; RTC_LOG(LS_INFO) << "BWE Setting start bitrate to: "
rate_control_.SetStartBitrate(start_bitrate_bps); << ToString(start_bitrate);
rate_control_.SetStartBitrate(start_bitrate.bps());
} }
void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { void DelayBasedBwe::SetMinBitrate(DataRate min_bitrate) {
// Called from both the configuration thread and the network thread. Shouldn't // Called from both the configuration thread and the network thread. Shouldn't
// be called from the network thread in the future. // be called from the network thread in the future.
rate_control_.SetMinBitrate(min_bitrate_bps); rate_control_.SetMinBitrate(min_bitrate.bps());
} }
int64_t DelayBasedBwe::GetExpectedBwePeriodMs() const { TimeDelta DelayBasedBwe::GetExpectedBwePeriod() const {
return rate_control_.GetExpectedBandwidthPeriodMs(); return TimeDelta::ms(rate_control_.GetExpectedBandwidthPeriodMs());
} }
} // namespace webrtc } // namespace webrtc

View File

@ -33,11 +33,11 @@ class DelayBasedBwe {
public: public:
struct Result { struct Result {
Result(); Result();
Result(bool probe, uint32_t target_bitrate_bps); Result(bool probe, DataRate target_bitrate);
~Result(); ~Result();
bool updated; bool updated;
bool probe; bool probe;
uint32_t target_bitrate_bps; DataRate target_bitrate = DataRate::Zero();
bool recovered_from_overuse; bool recovered_from_overuse;
}; };
@ -46,35 +46,34 @@ class DelayBasedBwe {
Result IncomingPacketFeedbackVector( Result IncomingPacketFeedbackVector(
const std::vector<PacketFeedback>& packet_feedback_vector, const std::vector<PacketFeedback>& packet_feedback_vector,
absl::optional<uint32_t> acked_bitrate_bps, absl::optional<DataRate> acked_bitrate,
int64_t at_time_ms); Timestamp at_time);
Result OnDelayedFeedback(int64_t receive_time_ms); Result OnDelayedFeedback(Timestamp receive_time);
void OnRttUpdate(int64_t avg_rtt_ms); void OnRttUpdate(TimeDelta avg_rtt);
bool LatestEstimate(std::vector<uint32_t>* ssrcs, bool LatestEstimate(std::vector<uint32_t>* ssrcs, DataRate* bitrate) const;
uint32_t* bitrate_bps) const; void SetStartBitrate(DataRate start_bitrate);
void SetStartBitrate(int start_bitrate_bps); void SetMinBitrate(DataRate min_bitrate);
void SetMinBitrate(int min_bitrate_bps); TimeDelta GetExpectedBwePeriod() const;
int64_t GetExpectedBwePeriodMs() const;
private: private:
friend class GoogCcStatePrinter; friend class GoogCcStatePrinter;
void IncomingPacketFeedback(const PacketFeedback& packet_feedback, void IncomingPacketFeedback(const PacketFeedback& packet_feedback,
int64_t at_time_ms); Timestamp at_time);
Result OnLongFeedbackDelay(int64_t arrival_time_ms); Result OnLongFeedbackDelay(Timestamp arrival_time);
Result MaybeUpdateEstimate(absl::optional<uint32_t> acked_bitrate_bps, Result MaybeUpdateEstimate(absl::optional<DataRate> acked_bitrate,
bool request_probe, bool request_probe,
int64_t at_time_ms); Timestamp at_time);
// Updates the current remote rate estimate and returns true if a valid // Updates the current remote rate estimate and returns true if a valid
// estimate exists. // estimate exists.
bool UpdateEstimate(int64_t now_ms, bool UpdateEstimate(Timestamp now,
absl::optional<uint32_t> acked_bitrate_bps, absl::optional<DataRate> acked_bitrate,
uint32_t* target_bitrate_bps); DataRate* target_bitrate);
rtc::RaceChecker network_race_; rtc::RaceChecker network_race_;
RtcEventLog* const event_log_; RtcEventLog* const event_log_;
std::unique_ptr<InterArrival> inter_arrival_; std::unique_ptr<InterArrival> inter_arrival_;
std::unique_ptr<DelayIncreaseDetectorInterface> delay_detector_; std::unique_ptr<DelayIncreaseDetectorInterface> delay_detector_;
int64_t last_seen_packet_ms_; Timestamp last_seen_packet_;
bool uma_recorded_; bool uma_recorded_;
AimdRateControl rate_control_; AimdRateControl rate_control_;
ProbeBitrateEstimator probe_bitrate_estimator_; ProbeBitrateEstimator probe_bitrate_estimator_;
@ -82,7 +81,7 @@ class DelayBasedBwe {
double trendline_smoothing_coeff_; double trendline_smoothing_coeff_;
double trendline_threshold_gain_; double trendline_threshold_gain_;
int consecutive_delayed_feedbacks_; int consecutive_delayed_feedbacks_;
uint32_t prev_bitrate_; DataRate prev_bitrate_;
BandwidthUsage prev_state_; BandwidthUsage prev_state_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe); RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe);

View File

@ -25,7 +25,7 @@ constexpr int kNumProbesCluster1 = 8;
const PacedPacketInfo kPacingInfo0(0, kNumProbesCluster0, 2000); const PacedPacketInfo kPacingInfo0(0, kNumProbesCluster0, 2000);
const PacedPacketInfo kPacingInfo1(1, kNumProbesCluster1, 4000); const PacedPacketInfo kPacingInfo1(1, kNumProbesCluster1, 4000);
constexpr float kTargetUtilizationFraction = 0.95f; constexpr float kTargetUtilizationFraction = 0.95f;
constexpr int64_t kDummyTimestamp = 1000; constexpr Timestamp kDummyTimestamp = Timestamp::Seconds<1000>();
} // namespace } // namespace
TEST_F(DelayBasedBweTest, NoCrashEmptyFeedback) { TEST_F(DelayBasedBweTest, NoCrashEmptyFeedback) {
@ -144,12 +144,12 @@ TEST_F(DelayBasedBweTest, ProbeDetectionSlowerArrivalHighBitrate) {
} }
TEST_F(DelayBasedBweTest, GetExpectedBwePeriodMs) { TEST_F(DelayBasedBweTest, GetExpectedBwePeriodMs) {
int64_t default_interval_ms = bitrate_estimator_->GetExpectedBwePeriodMs(); auto default_interval = bitrate_estimator_->GetExpectedBwePeriod();
EXPECT_GT(default_interval_ms, 0); EXPECT_GT(default_interval.ms(), 0);
CapacityDropTestHelper(1, true, 333, 0); CapacityDropTestHelper(1, true, 333, 0);
int64_t interval_ms = bitrate_estimator_->GetExpectedBwePeriodMs(); auto interval = bitrate_estimator_->GetExpectedBwePeriod();
EXPECT_GT(interval_ms, 0); EXPECT_GT(interval.ms(), 0);
EXPECT_NE(interval_ms, default_interval_ms); EXPECT_NE(interval.ms(), default_interval.ms());
} }
TEST_F(DelayBasedBweTest, InitialBehavior) { TEST_F(DelayBasedBweTest, InitialBehavior) {
@ -199,20 +199,20 @@ TEST_F(DelayBasedBweTest, TestLongTimeoutAndWrap) {
} }
TEST_F(DelayBasedBweTest, TestInitialOveruse) { TEST_F(DelayBasedBweTest, TestInitialOveruse) {
const uint32_t kStartBitrate = 300e3; const DataRate kStartBitrate = DataRate::kbps(300);
const uint32_t kInitialCapacityBps = 200e3; const DataRate kInitialCapacity = DataRate::kbps(200);
const uint32_t kDummySsrc = 0; const uint32_t kDummySsrc = 0;
// High FPS to ensure that we send a lot of packets in a short time. // High FPS to ensure that we send a lot of packets in a short time.
const int kFps = 90; const int kFps = 90;
stream_generator_->AddStream(new test::RtpStream(kFps, kStartBitrate)); stream_generator_->AddStream(new test::RtpStream(kFps, kStartBitrate.bps()));
stream_generator_->set_capacity_bps(kInitialCapacityBps); stream_generator_->set_capacity_bps(kInitialCapacity.bps());
// Needed to initialize the AimdRateControl. // Needed to initialize the AimdRateControl.
bitrate_estimator_->SetStartBitrate(kStartBitrate); bitrate_estimator_->SetStartBitrate(kStartBitrate);
// Produce 30 frames (in 1/3 second) and give them to the estimator. // Produce 30 frames (in 1/3 second) and give them to the estimator.
uint32_t bitrate_bps = kStartBitrate; int64_t bitrate_bps = kStartBitrate.bps();
bool seen_overuse = false; bool seen_overuse = false;
for (int i = 0; i < 30; ++i) { for (int i = 0; i < 30; ++i) {
bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps); bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps);
@ -222,7 +222,8 @@ TEST_F(DelayBasedBweTest, TestInitialOveruse) {
EXPECT_FALSE(acknowledged_bitrate_estimator_->bitrate_bps().has_value()); EXPECT_FALSE(acknowledged_bitrate_estimator_->bitrate_bps().has_value());
if (overuse) { if (overuse) {
EXPECT_TRUE(bitrate_observer_.updated()); EXPECT_TRUE(bitrate_observer_.updated());
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000); EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate.bps() / 2,
15000);
bitrate_bps = bitrate_observer_.latest_bitrate(); bitrate_bps = bitrate_observer_.latest_bitrate();
seen_overuse = true; seen_overuse = true;
break; break;
@ -232,7 +233,8 @@ TEST_F(DelayBasedBweTest, TestInitialOveruse) {
} }
} }
EXPECT_TRUE(seen_overuse); EXPECT_TRUE(seen_overuse);
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000); EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate.bps() / 2,
15000);
} }
class DelayBasedBweTestWithBackoffTimeoutExperiment : public DelayBasedBweTest { class DelayBasedBweTestWithBackoffTimeoutExperiment : public DelayBasedBweTest {
@ -243,20 +245,20 @@ class DelayBasedBweTestWithBackoffTimeoutExperiment : public DelayBasedBweTest {
// This test subsumes and improves DelayBasedBweTest.TestInitialOveruse above. // This test subsumes and improves DelayBasedBweTest.TestInitialOveruse above.
TEST_F(DelayBasedBweTestWithBackoffTimeoutExperiment, TestInitialOveruse) { TEST_F(DelayBasedBweTestWithBackoffTimeoutExperiment, TestInitialOveruse) {
const uint32_t kStartBitrate = 300e3; const DataRate kStartBitrate = DataRate::kbps(300);
const uint32_t kInitialCapacityBps = 200e3; const DataRate kInitialCapacity = DataRate::kbps(200);
const uint32_t kDummySsrc = 0; const uint32_t kDummySsrc = 0;
// High FPS to ensure that we send a lot of packets in a short time. // High FPS to ensure that we send a lot of packets in a short time.
const int kFps = 90; const int kFps = 90;
stream_generator_->AddStream(new test::RtpStream(kFps, kStartBitrate)); stream_generator_->AddStream(new test::RtpStream(kFps, kStartBitrate.bps()));
stream_generator_->set_capacity_bps(kInitialCapacityBps); stream_generator_->set_capacity_bps(kInitialCapacity.bps());
// Needed to initialize the AimdRateControl. // Needed to initialize the AimdRateControl.
bitrate_estimator_->SetStartBitrate(kStartBitrate); bitrate_estimator_->SetStartBitrate(kStartBitrate);
// Produce 30 frames (in 1/3 second) and give them to the estimator. // Produce 30 frames (in 1/3 second) and give them to the estimator.
uint32_t bitrate_bps = kStartBitrate; int64_t bitrate_bps = kStartBitrate.bps();
bool seen_overuse = false; bool seen_overuse = false;
for (int frames = 0; frames < 30 && !seen_overuse; ++frames) { for (int frames = 0; frames < 30 && !seen_overuse; ++frames) {
bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps); bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps);
@ -266,7 +268,8 @@ TEST_F(DelayBasedBweTestWithBackoffTimeoutExperiment, TestInitialOveruse) {
EXPECT_FALSE(acknowledged_bitrate_estimator_->bitrate_bps().has_value()); EXPECT_FALSE(acknowledged_bitrate_estimator_->bitrate_bps().has_value());
if (overuse) { if (overuse) {
EXPECT_TRUE(bitrate_observer_.updated()); EXPECT_TRUE(bitrate_observer_.updated());
EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate / 2, 15000); EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate.bps() / 2,
15000);
bitrate_bps = bitrate_observer_.latest_bitrate(); bitrate_bps = bitrate_observer_.latest_bitrate();
seen_overuse = true; seen_overuse = true;
} else if (bitrate_observer_.updated()) { } else if (bitrate_observer_.updated()) {
@ -282,8 +285,8 @@ TEST_F(DelayBasedBweTestWithBackoffTimeoutExperiment, TestInitialOveruse) {
EXPECT_FALSE(overuse); EXPECT_FALSE(overuse);
if (bitrate_observer_.updated()) { if (bitrate_observer_.updated()) {
bitrate_bps = bitrate_observer_.latest_bitrate(); bitrate_bps = bitrate_observer_.latest_bitrate();
EXPECT_GE(bitrate_bps, kStartBitrate / 2 - 15000); EXPECT_GE(bitrate_bps, kStartBitrate.bps() / 2 - 15000);
EXPECT_LE(bitrate_bps, kInitialCapacityBps + 15000); EXPECT_LE(bitrate_bps, kInitialCapacity.bps() + 15000);
bitrate_observer_.Reset(); bitrate_observer_.Reset();
} }
} }

View File

@ -201,12 +201,12 @@ void DelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms,
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets); acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets);
DelayBasedBwe::Result result = DelayBasedBwe::Result result =
bitrate_estimator_->IncomingPacketFeedbackVector( bitrate_estimator_->IncomingPacketFeedbackVector(
packets, acknowledged_bitrate_estimator_->bitrate_bps(), packets, acknowledged_bitrate_estimator_->bitrate(),
clock_.TimeInMilliseconds()); Timestamp::ms(clock_.TimeInMilliseconds()));
const uint32_t kDummySsrc = 0; const uint32_t kDummySsrc = 0;
if (result.updated) { if (result.updated) {
bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc}, bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc},
result.target_bitrate_bps); result.target_bitrate.bps());
} }
} }
@ -237,13 +237,13 @@ bool DelayBasedBweTest::GenerateAndProcessFrame(uint32_t ssrc,
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets); acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets);
DelayBasedBwe::Result result = DelayBasedBwe::Result result =
bitrate_estimator_->IncomingPacketFeedbackVector( bitrate_estimator_->IncomingPacketFeedbackVector(
packets, acknowledged_bitrate_estimator_->bitrate_bps(), packets, acknowledged_bitrate_estimator_->bitrate(),
clock_.TimeInMilliseconds()); Timestamp::ms(clock_.TimeInMilliseconds()));
const uint32_t kDummySsrc = 0; const uint32_t kDummySsrc = 0;
if (result.updated) { if (result.updated) {
bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc}, bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc},
result.target_bitrate_bps); result.target_bitrate.bps());
if (!first_update_ && result.target_bitrate_bps < bitrate_bps) if (!first_update_ && result.target_bitrate.bps() < bitrate_bps)
overuse = true; overuse = true;
first_update_ = false; first_update_ = false;
} }
@ -289,14 +289,14 @@ void DelayBasedBweTest::InitialBehaviorTestHelper(
const int kFramerate = 50; // 50 fps to avoid rounding errors. const int kFramerate = 50; // 50 fps to avoid rounding errors.
const int kFrameIntervalMs = 1000 / kFramerate; const int kFrameIntervalMs = 1000 / kFramerate;
const PacedPacketInfo kPacingInfo(0, 5, 5000); const PacedPacketInfo kPacingInfo(0, 5, 5000);
uint32_t bitrate_bps = 0; DataRate bitrate = DataRate::Zero();
int64_t send_time_ms = 0; int64_t send_time_ms = 0;
uint16_t sequence_number = 0; uint16_t sequence_number = 0;
std::vector<uint32_t> ssrcs; std::vector<uint32_t> ssrcs;
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps)); EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
EXPECT_EQ(0u, ssrcs.size()); EXPECT_EQ(0u, ssrcs.size());
clock_.AdvanceTimeMilliseconds(1000); clock_.AdvanceTimeMilliseconds(1000);
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps)); EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
EXPECT_FALSE(bitrate_observer_.updated()); EXPECT_FALSE(bitrate_observer_.updated());
bitrate_observer_.Reset(); bitrate_observer_.Reset();
clock_.AdvanceTimeMilliseconds(1000); clock_.AdvanceTimeMilliseconds(1000);
@ -308,7 +308,7 @@ void DelayBasedBweTest::InitialBehaviorTestHelper(
i < kInitialProbingPackets ? kPacingInfo : PacedPacketInfo(); i < kInitialProbingPackets ? kPacingInfo : PacedPacketInfo();
if (i == kNumInitialPackets) { if (i == kNumInitialPackets) {
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps)); EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
EXPECT_EQ(0u, ssrcs.size()); EXPECT_EQ(0u, ssrcs.size());
EXPECT_FALSE(bitrate_observer_.updated()); EXPECT_FALSE(bitrate_observer_.updated());
bitrate_observer_.Reset(); bitrate_observer_.Reset();
@ -318,13 +318,14 @@ void DelayBasedBweTest::InitialBehaviorTestHelper(
clock_.AdvanceTimeMilliseconds(1000 / kFramerate); clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
send_time_ms += kFrameIntervalMs; send_time_ms += kFrameIntervalMs;
} }
EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps)); EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
ASSERT_EQ(1u, ssrcs.size()); ASSERT_EQ(1u, ssrcs.size());
EXPECT_EQ(kDefaultSsrc, ssrcs.front()); EXPECT_EQ(kDefaultSsrc, ssrcs.front());
EXPECT_NEAR(expected_converge_bitrate, bitrate_bps, kAcceptedBitrateErrorBps); EXPECT_NEAR(expected_converge_bitrate, bitrate.bps(),
kAcceptedBitrateErrorBps);
EXPECT_TRUE(bitrate_observer_.updated()); EXPECT_TRUE(bitrate_observer_.updated());
bitrate_observer_.Reset(); bitrate_observer_.Reset();
EXPECT_EQ(bitrate_observer_.latest_bitrate(), bitrate_bps); EXPECT_EQ(bitrate_observer_.latest_bitrate(), bitrate.bps());
} }
void DelayBasedBweTest::RateIncreaseReorderingTestHelper( void DelayBasedBweTest::RateIncreaseReorderingTestHelper(
@ -509,7 +510,7 @@ void DelayBasedBweTest::TestWrappingHelper(int silence_time_s) {
clock_.AdvanceTimeMilliseconds(kFrameIntervalMs); clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
send_time_ms += kFrameIntervalMs; send_time_ms += kFrameIntervalMs;
} }
uint32_t bitrate_before = 0; DataRate bitrate_before = DataRate::Zero();
std::vector<uint32_t> ssrcs; std::vector<uint32_t> ssrcs;
bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_before); bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_before);
@ -522,7 +523,7 @@ void DelayBasedBweTest::TestWrappingHelper(int silence_time_s) {
clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs); clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
send_time_ms += kFrameIntervalMs; send_time_ms += kFrameIntervalMs;
} }
uint32_t bitrate_after = 0; DataRate bitrate_after = DataRate::Zero();
bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_after); bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_after);
EXPECT_LT(bitrate_after, bitrate_before); EXPECT_LT(bitrate_after, bitrate_before);
} }

View File

@ -159,7 +159,7 @@ GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
{&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_}, {&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
field_trial::FindFullName("WebRTC-Bwe-SafeResetOnRouteChange")); field_trial::FindFullName("WebRTC-Bwe-SafeResetOnRouteChange"));
delay_based_bwe_->SetMinBitrate(congestion_controller::GetMinBitrateBps()); delay_based_bwe_->SetMinBitrate(congestion_controller::GetMinBitrate());
if (in_cwnd_experiment_ && if (in_cwnd_experiment_ &&
!ReadCwndExperimentParameter(&accepted_queue_ms_)) { !ReadCwndExperimentParameter(&accepted_queue_ms_)) {
RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment " RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
@ -203,16 +203,16 @@ NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
if (estimated_bitrate_bps && (!msg.constraints.starting_rate || if (estimated_bitrate_bps && (!msg.constraints.starting_rate ||
estimated_bitrate_bps < start_bitrate_bps)) { estimated_bitrate_bps < start_bitrate_bps)) {
start_bitrate_bps = *estimated_bitrate_bps; start_bitrate_bps = *estimated_bitrate_bps;
if (msg.constraints.starting_rate) { msg.constraints.starting_rate = DataRate::bps(start_bitrate_bps);
msg.constraints.starting_rate = DataRate::bps(start_bitrate_bps);
}
} }
} }
acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator()); acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
delay_based_bwe_.reset(new DelayBasedBwe(event_log_)); delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
delay_based_bwe_->SetStartBitrate(start_bitrate_bps); if (msg.constraints.starting_rate)
delay_based_bwe_->SetMinBitrate(min_bitrate_bps); delay_based_bwe_->SetStartBitrate(*msg.constraints.starting_rate);
// TODO(srte): Use original values instead of converted.
delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps));
bandwidth_estimation_->OnRouteChange(); bandwidth_estimation_->OnRouteChange();
bandwidth_estimation_->SetBitrates( bandwidth_estimation_->SetBitrates(
msg.constraints.starting_rate, DataRate::bps(min_bitrate_bps), msg.constraints.starting_rate, DataRate::bps(min_bitrate_bps),
@ -282,7 +282,7 @@ NetworkControlUpdate GoogCcNetworkController::OnRoundTripTimeUpdate(
if (packet_feedback_only_) if (packet_feedback_only_)
return NetworkControlUpdate(); return NetworkControlUpdate();
if (msg.smoothed) { if (msg.smoothed) {
delay_based_bwe_->OnRttUpdate(msg.round_trip_time.ms()); delay_based_bwe_->OnRttUpdate(msg.round_trip_time);
} else { } else {
bandwidth_estimation_->UpdateRtt(msg.round_trip_time, msg.receive_time); bandwidth_estimation_->UpdateRtt(msg.round_trip_time, msg.receive_time);
} }
@ -370,9 +370,9 @@ GoogCcNetworkController::UpdateBitrateConstraints(
starting_rate, DataRate::bps(min_bitrate_bps), starting_rate, DataRate::bps(min_bitrate_bps),
constraints.max_data_rate.value_or(DataRate::Infinity()), constraints.max_data_rate.value_or(DataRate::Infinity()),
constraints.at_time); constraints.at_time);
if (start_bitrate_bps > 0) if (starting_rate)
delay_based_bwe_->SetStartBitrate(start_bitrate_bps); delay_based_bwe_->SetStartBitrate(*starting_rate);
delay_based_bwe_->SetMinBitrate(min_bitrate_bps); delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps));
return probes; return probes;
} }
@ -391,11 +391,11 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
TransportPacketsFeedback report) { TransportPacketsFeedback report) {
if (report.packet_feedbacks.empty()) { if (report.packet_feedbacks.empty()) {
DelayBasedBwe::Result result = delay_based_bwe_->OnDelayedFeedback( DelayBasedBwe::Result result = delay_based_bwe_->OnDelayedFeedback(
report.sendless_arrival_times.back().ms()); report.sendless_arrival_times.back());
NetworkControlUpdate update; NetworkControlUpdate update;
if (result.updated) { if (result.updated) {
bandwidth_estimation_->UpdateDelayBasedEstimate( bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time,
report.feedback_time, DataRate::bps(result.target_bitrate_bps)); result.target_bitrate);
MaybeTriggerOnNetworkChanged(&update, report.feedback_time); MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
} }
return update; return update;
@ -436,7 +436,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
int64_t sum_rtt_ms = std::accumulate(feedback_max_rtts_.begin(), int64_t sum_rtt_ms = std::accumulate(feedback_max_rtts_.begin(),
feedback_max_rtts_.end(), 0); feedback_max_rtts_.end(), 0);
int64_t mean_rtt_ms = sum_rtt_ms / feedback_max_rtts_.size(); int64_t mean_rtt_ms = sum_rtt_ms / feedback_max_rtts_.size();
delay_based_bwe_->OnRttUpdate(mean_rtt_ms); delay_based_bwe_->OnRttUpdate(TimeDelta::ms(mean_rtt_ms));
} }
TimeDelta feedback_min_rtt = TimeDelta::PlusInfinity(); TimeDelta feedback_min_rtt = TimeDelta::PlusInfinity();
@ -481,25 +481,24 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
previously_in_alr = alr_start_time.has_value(); previously_in_alr = alr_start_time.has_value();
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector( acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
received_feedback_vector); received_feedback_vector);
auto acknowledged_bitrate = acknowledged_bitrate_estimator_->bitrate_bps(); auto acknowledged_bitrate = acknowledged_bitrate_estimator_->bitrate();
bandwidth_estimation_->IncomingPacketFeedbackVector(report, bandwidth_estimation_->IncomingPacketFeedbackVector(report,
acknowledged_bitrate); acknowledged_bitrate);
DelayBasedBwe::Result result; DelayBasedBwe::Result result;
result = delay_based_bwe_->IncomingPacketFeedbackVector( result = delay_based_bwe_->IncomingPacketFeedbackVector(
received_feedback_vector, acknowledged_bitrate, received_feedback_vector, acknowledged_bitrate, report.feedback_time);
report.feedback_time.ms());
NetworkControlUpdate update; NetworkControlUpdate update;
if (result.updated) { if (result.updated) {
if (result.probe) { if (result.probe) {
bandwidth_estimation_->SetSendBitrate( bandwidth_estimation_->SetSendBitrate(result.target_bitrate,
DataRate::bps(result.target_bitrate_bps), report.feedback_time); report.feedback_time);
} }
// Since SetSendBitrate now resets the delay-based estimate, we have to call // Since SetSendBitrate now resets the delay-based estimate, we have to call
// UpdateDelayBasedEstimate after SetSendBitrate. // UpdateDelayBasedEstimate after SetSendBitrate.
bandwidth_estimation_->UpdateDelayBasedEstimate( bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time,
report.feedback_time, DataRate::bps(result.target_bitrate_bps)); result.target_bitrate);
// Update the estimate in the ProbeController, in case we want to probe. // Update the estimate in the ProbeController, in case we want to probe.
MaybeTriggerOnNetworkChanged(&update, report.feedback_time); MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
} }
@ -550,7 +549,7 @@ NetworkControlUpdate GoogCcNetworkController::GetNetworkState(
last_estimated_fraction_loss_ / 255.0; last_estimated_fraction_loss_ / 255.0;
update.target_rate->network_estimate.round_trip_time = rtt; update.target_rate->network_estimate.round_trip_time = rtt;
update.target_rate->network_estimate.bwe_period = update.target_rate->network_estimate.bwe_period =
TimeDelta::ms(delay_based_bwe_->GetExpectedBwePeriodMs()); delay_based_bwe_->GetExpectedBwePeriod();
update.target_rate->at_time = at_time; update.target_rate->at_time = at_time;
update.target_rate->target_rate = bandwidth; update.target_rate->target_rate = bandwidth;
update.pacer_config = GetPacingRates(at_time); update.pacer_config = GetPacingRates(at_time);
@ -589,8 +588,7 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
DataRate bandwidth = DataRate::bps(estimated_bitrate_bps); DataRate bandwidth = DataRate::bps(estimated_bitrate_bps);
last_bandwidth_ = bandwidth; last_bandwidth_ = bandwidth;
TimeDelta bwe_period = TimeDelta bwe_period = delay_based_bwe_->GetExpectedBwePeriod();
TimeDelta::ms(delay_based_bwe_->GetExpectedBwePeriodMs());
// Set the target rate to the full estimated bandwidth since the estimation // Set the target rate to the full estimated bandwidth since the estimation
// for legacy reasons includes target rate constraints. // for legacy reasons includes target rate constraints.

View File

@ -170,11 +170,13 @@ int ProbeBitrateEstimator::HandleProbeAndEstimateBitrate(
return *estimated_bitrate_bps_; return *estimated_bitrate_bps_;
} }
absl::optional<int> absl::optional<DataRate>
ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrateBps() { ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrate() {
absl::optional<int> estimated_bitrate_bps = estimated_bitrate_bps_; absl::optional<int> estimated_bitrate_bps = estimated_bitrate_bps_;
estimated_bitrate_bps_.reset(); estimated_bitrate_bps_.reset();
return estimated_bitrate_bps; if (estimated_bitrate_bps)
return DataRate::bps(*estimated_bitrate_bps);
return absl::nullopt;
} }
void ProbeBitrateEstimator::EraseOldClusters(int64_t timestamp_ms) { void ProbeBitrateEstimator::EraseOldClusters(int64_t timestamp_ms) {

View File

@ -28,7 +28,7 @@ class ProbeBitrateEstimator {
// Returns the estimated bitrate if the probe completes a valid cluster. // Returns the estimated bitrate if the probe completes a valid cluster.
int HandleProbeAndEstimateBitrate(const PacketFeedback& packet_feedback); int HandleProbeAndEstimateBitrate(const PacketFeedback& packet_feedback);
absl::optional<int> FetchAndResetLastEstimatedBitrateBps(); absl::optional<DataRate> FetchAndResetLastEstimatedBitrate();
private: private:
struct AggregatedCluster { struct AggregatedCluster {

View File

@ -202,7 +202,7 @@ TEST_F(TestProbeBitrateEstimator, IgnoreSizeFirstReceivePacket) {
} }
TEST_F(TestProbeBitrateEstimator, NoLastEstimatedBitrateBps) { TEST_F(TestProbeBitrateEstimator, NoLastEstimatedBitrateBps) {
EXPECT_FALSE(probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps()); EXPECT_FALSE(probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrate());
} }
TEST_F(TestProbeBitrateEstimator, FetchLastEstimatedBitrateBps) { TEST_F(TestProbeBitrateEstimator, FetchLastEstimatedBitrateBps) {
@ -211,11 +211,11 @@ TEST_F(TestProbeBitrateEstimator, FetchLastEstimatedBitrateBps) {
AddPacketFeedback(0, 1000, 20, 30); AddPacketFeedback(0, 1000, 20, 30);
AddPacketFeedback(0, 1000, 30, 40); AddPacketFeedback(0, 1000, 30, 40);
auto estimated_bitrate_bps = auto estimated_bitrate =
probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps(); probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrate();
EXPECT_TRUE(estimated_bitrate_bps); EXPECT_TRUE(estimated_bitrate);
EXPECT_NEAR(*estimated_bitrate_bps, 800000, 10); EXPECT_NEAR(estimated_bitrate->bps(), 800000, 10);
EXPECT_FALSE(probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps()); EXPECT_FALSE(probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrate());
} }
} // namespace webrtc } // namespace webrtc

View File

@ -153,7 +153,7 @@ SendSideCongestionController::SendSideCongestionController(
pacer_pushback_experiment_(IsPacerPushbackExperimentEnabled()), pacer_pushback_experiment_(IsPacerPushbackExperimentEnabled()),
congestion_window_pushback_controller_( congestion_window_pushback_controller_(
MaybeCreateCongestionWindowPushbackController()) { MaybeCreateCongestionWindowPushbackController()) {
delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps_));
if (in_cwnd_experiment_ && if (in_cwnd_experiment_ &&
!ReadCwndExperimentParameter(&accepted_queue_ms_)) { !ReadCwndExperimentParameter(&accepted_queue_ms_)) {
RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment " RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
@ -221,9 +221,9 @@ void SendSideCongestionController::SetBweBitrates(int min_bitrate_bps,
{ {
rtc::CritScope cs(&bwe_lock_); rtc::CritScope cs(&bwe_lock_);
if (start_bitrate_bps > 0) if (start_bitrate_bps > 0)
delay_based_bwe_->SetStartBitrate(start_bitrate_bps); delay_based_bwe_->SetStartBitrate(DataRate::bps(start_bitrate_bps));
min_bitrate_bps_ = min_bitrate_bps; min_bitrate_bps_ = min_bitrate_bps;
delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps_));
} }
MaybeTriggerOnNetworkChanged(); MaybeTriggerOnNetworkChanged();
} }
@ -260,8 +260,10 @@ void SendSideCongestionController::OnNetworkRouteChanged(
min_bitrate_bps_ = min_bitrate_bps; min_bitrate_bps_ = min_bitrate_bps;
delay_based_bwe_.reset(new DelayBasedBwe(event_log_)); delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator()); acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
delay_based_bwe_->SetStartBitrate(bitrate_bps); if (bitrate_bps > 0) {
delay_based_bwe_->SetMinBitrate(min_bitrate_bps); delay_based_bwe_->SetStartBitrate(DataRate::bps(bitrate_bps));
}
delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps));
} }
{ {
rtc::CritScope cs(&probe_lock_); rtc::CritScope cs(&probe_lock_);
@ -338,7 +340,7 @@ void SendSideCongestionController::OnSentPacket(
void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
int64_t max_rtt_ms) { int64_t max_rtt_ms) {
rtc::CritScope cs(&bwe_lock_); rtc::CritScope cs(&bwe_lock_);
delay_based_bwe_->OnRttUpdate(avg_rtt_ms); delay_based_bwe_->OnRttUpdate(TimeDelta::ms(avg_rtt_ms));
} }
int64_t SendSideCongestionController::TimeUntilNextProcess() { int64_t SendSideCongestionController::TimeUntilNextProcess() {
@ -415,8 +417,8 @@ void SendSideCongestionController::OnTransportFeedback(
{ {
rtc::CritScope cs(&bwe_lock_); rtc::CritScope cs(&bwe_lock_);
result = delay_based_bwe_->IncomingPacketFeedbackVector( result = delay_based_bwe_->IncomingPacketFeedbackVector(
feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps(), feedback_vector, acknowledged_bitrate_estimator_->bitrate(),
clock_->TimeInMilliseconds()); Timestamp::ms(clock_->TimeInMilliseconds()));
} }
if (result.updated) { if (result.updated) {
bitrate_controller_->OnDelayBasedBweResult(result); bitrate_controller_->OnDelayBasedBweResult(result);
@ -518,7 +520,7 @@ void SendSideCongestionController::MaybeTriggerOnNetworkChanged() {
int64_t probing_interval_ms; int64_t probing_interval_ms;
{ {
rtc::CritScope cs(&bwe_lock_); rtc::CritScope cs(&bwe_lock_);
probing_interval_ms = delay_based_bwe_->GetExpectedBwePeriodMs(); probing_interval_ms = delay_based_bwe_->GetExpectedBwePeriod().ms();
} }
{ {
rtc::CritScope cs(&observer_lock_); rtc::CritScope cs(&observer_lock_);

View File

@ -44,7 +44,7 @@ SendSideBweSender::SendSideBweSender(int kbps,
bitrate_controller_->SetStartBitrate(1000 * kbps); bitrate_controller_->SetStartBitrate(1000 * kbps);
bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps, bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps,
1000 * kMaxBitrateKbps); 1000 * kMaxBitrateKbps);
bwe_->SetMinBitrate(1000 * kMinBitrateKbps); bwe_->SetMinBitrate(DataRate::kbps(kMinBitrateKbps));
} }
SendSideBweSender::~SendSideBweSender() {} SendSideBweSender::~SendSideBweSender() {}
@ -72,7 +72,7 @@ void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) {
int64_t rtt_ms = int64_t rtt_ms =
clock_->TimeInMilliseconds() - feedback.latest_send_time_ms(); clock_->TimeInMilliseconds() - feedback.latest_send_time_ms();
bwe_->OnRttUpdate(rtt_ms); bwe_->OnRttUpdate(TimeDelta::ms(rtt_ms));
BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms); BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms);
std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(), std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(),
@ -80,8 +80,8 @@ void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) {
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector( acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
packet_feedback_vector); packet_feedback_vector);
DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector( DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector(
packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps(), packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate(),
clock_->TimeInMilliseconds()); Timestamp::ms(clock_->TimeInMilliseconds()));
if (result.updated) if (result.updated)
bitrate_controller_->OnDelayBasedBweResult(result); bitrate_controller_->OnDelayBasedBweResult(result);