Using units in SendSideBandwidthEstimation.
This CL moves SendSideBandwidthEstimation to use the unit types DataRate, TimeDelta and Timestamp. This prepares for upcoming changes. Bug: webrtc:9718 Change-Id: If10e329920dda037b53055ff3352ae7f8d7e32b8 Reviewed-on: https://webrtc-review.googlesource.com/c/104021 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25029}
This commit is contained in:

committed by
Commit Bot

parent
9f80b97309
commit
35b5e5f3b0
@ -44,6 +44,7 @@ rtc_static_library("bitrate_controller") {
|
|||||||
"../rtp_rtcp",
|
"../rtp_rtcp",
|
||||||
"../rtp_rtcp:rtp_rtcp_format",
|
"../rtp_rtcp:rtp_rtcp_format",
|
||||||
"//third_party/abseil-cpp/absl/memory",
|
"//third_party/abseil-cpp/absl/memory",
|
||||||
|
"//third_party/abseil-cpp/absl/types:optional",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,18 @@
|
|||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
namespace {
|
||||||
|
absl::optional<DataRate> ToOptionalDataRate(int start_bitrate_bps) {
|
||||||
|
if (start_bitrate_bps == -1)
|
||||||
|
return absl::nullopt;
|
||||||
|
return DataRate::bps(start_bitrate_bps);
|
||||||
|
}
|
||||||
|
DataRate MaxRate(int max_bitrate_bps) {
|
||||||
|
if (max_bitrate_bps == -1)
|
||||||
|
return DataRate::Infinity();
|
||||||
|
return DataRate::bps(max_bitrate_bps);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
class BitrateControllerImpl::RtcpBandwidthObserverImpl
|
class BitrateControllerImpl::RtcpBandwidthObserverImpl
|
||||||
: public RtcpBandwidthObserver {
|
: public RtcpBandwidthObserver {
|
||||||
public:
|
public:
|
||||||
@ -80,7 +91,9 @@ RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
|
|||||||
void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
|
void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
|
||||||
{
|
{
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
|
bandwidth_estimation_.SetSendBitrate(
|
||||||
|
DataRate::bps(start_bitrate_bps),
|
||||||
|
Timestamp::ms(clock_->TimeInMilliseconds()));
|
||||||
}
|
}
|
||||||
MaybeTriggerOnNetworkChanged();
|
MaybeTriggerOnNetworkChanged();
|
||||||
}
|
}
|
||||||
@ -89,7 +102,8 @@ void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
|
|||||||
int max_bitrate_bps) {
|
int max_bitrate_bps) {
|
||||||
{
|
{
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
|
bandwidth_estimation_.SetMinMaxBitrate(DataRate::bps(min_bitrate_bps),
|
||||||
|
DataRate::bps(max_bitrate_bps));
|
||||||
}
|
}
|
||||||
MaybeTriggerOnNetworkChanged();
|
MaybeTriggerOnNetworkChanged();
|
||||||
}
|
}
|
||||||
@ -99,8 +113,9 @@ void BitrateControllerImpl::SetBitrates(int start_bitrate_bps,
|
|||||||
int max_bitrate_bps) {
|
int max_bitrate_bps) {
|
||||||
{
|
{
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
bandwidth_estimation_.SetBitrates(start_bitrate_bps, min_bitrate_bps,
|
bandwidth_estimation_.SetBitrates(
|
||||||
max_bitrate_bps);
|
ToOptionalDataRate(start_bitrate_bps), DataRate::bps(min_bitrate_bps),
|
||||||
|
MaxRate(max_bitrate_bps), Timestamp::ms(clock_->TimeInMilliseconds()));
|
||||||
}
|
}
|
||||||
MaybeTriggerOnNetworkChanged();
|
MaybeTriggerOnNetworkChanged();
|
||||||
}
|
}
|
||||||
@ -111,8 +126,9 @@ void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
|
|||||||
{
|
{
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
|
bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
|
||||||
bandwidth_estimation_.SetBitrates(bitrate_bps, min_bitrate_bps,
|
bandwidth_estimation_.SetBitrates(
|
||||||
max_bitrate_bps);
|
ToOptionalDataRate(bitrate_bps), DataRate::bps(min_bitrate_bps),
|
||||||
|
MaxRate(max_bitrate_bps), Timestamp::ms(clock_->TimeInMilliseconds()));
|
||||||
}
|
}
|
||||||
MaybeTriggerOnNetworkChanged();
|
MaybeTriggerOnNetworkChanged();
|
||||||
}
|
}
|
||||||
@ -121,8 +137,8 @@ void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
|
|||||||
void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
|
void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
|
||||||
{
|
{
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
|
bandwidth_estimation_.UpdateReceiverEstimate(
|
||||||
bitrate);
|
Timestamp::ms(clock_->TimeInMilliseconds()), DataRate::bps(bitrate));
|
||||||
BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", clock_->TimeInMilliseconds(),
|
BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", clock_->TimeInMilliseconds(),
|
||||||
bitrate / 1000);
|
bitrate / 1000);
|
||||||
}
|
}
|
||||||
@ -136,12 +152,15 @@ void BitrateControllerImpl::OnDelayBasedBweResult(
|
|||||||
{
|
{
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
if (result.probe) {
|
if (result.probe) {
|
||||||
bandwidth_estimation_.SetSendBitrate(result.target_bitrate_bps);
|
bandwidth_estimation_.SetSendBitrate(
|
||||||
|
DataRate::bps(result.target_bitrate_bps),
|
||||||
|
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(clock_->TimeInMilliseconds(),
|
bandwidth_estimation_.UpdateDelayBasedEstimate(
|
||||||
result.target_bitrate_bps);
|
Timestamp::ms(clock_->TimeInMilliseconds()),
|
||||||
|
DataRate::bps(result.target_bitrate_bps));
|
||||||
}
|
}
|
||||||
MaybeTriggerOnNetworkChanged();
|
MaybeTriggerOnNetworkChanged();
|
||||||
}
|
}
|
||||||
@ -158,7 +177,8 @@ int64_t BitrateControllerImpl::TimeUntilNextProcess() {
|
|||||||
void BitrateControllerImpl::Process() {
|
void BitrateControllerImpl::Process() {
|
||||||
{
|
{
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
|
bandwidth_estimation_.UpdateEstimate(
|
||||||
|
Timestamp::ms(clock_->TimeInMilliseconds()));
|
||||||
}
|
}
|
||||||
MaybeTriggerOnNetworkChanged();
|
MaybeTriggerOnNetworkChanged();
|
||||||
last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
|
last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
|
||||||
@ -213,8 +233,9 @@ void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
|
|||||||
|
|
||||||
RTC_DCHECK_GE(total_number_of_packets, 0);
|
RTC_DCHECK_GE(total_number_of_packets, 0);
|
||||||
|
|
||||||
bandwidth_estimation_.UpdateReceiverBlock(fraction_lost_aggregate, rtt,
|
bandwidth_estimation_.UpdateReceiverBlock(
|
||||||
total_number_of_packets, now_ms);
|
fraction_lost_aggregate, TimeDelta::ms(rtt), total_number_of_packets,
|
||||||
|
Timestamp::ms(now_ms));
|
||||||
}
|
}
|
||||||
MaybeTriggerOnNetworkChanged();
|
MaybeTriggerOnNetworkChanged();
|
||||||
}
|
}
|
||||||
|
@ -27,22 +27,22 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
const int64_t kBweIncreaseIntervalMs = 1000;
|
constexpr TimeDelta kBweIncreaseInterval = TimeDelta::Millis<1000>();
|
||||||
const int64_t kBweDecreaseIntervalMs = 300;
|
constexpr TimeDelta kBweDecreaseInterval = TimeDelta::Millis<300>();
|
||||||
const int64_t kStartPhaseMs = 2000;
|
constexpr TimeDelta kStartPhase = TimeDelta::Millis<2000>();
|
||||||
const int64_t kBweConverganceTimeMs = 20000;
|
constexpr TimeDelta kBweConverganceTime = TimeDelta::Millis<20000>();
|
||||||
const int kLimitNumPackets = 20;
|
constexpr int kLimitNumPackets = 20;
|
||||||
const int kDefaultMaxBitrateBps = 1000000000;
|
constexpr DataRate kDefaultMaxBitrate = DataRate::BitsPerSec<1000000000>();
|
||||||
const int64_t kLowBitrateLogPeriodMs = 10000;
|
constexpr TimeDelta kLowBitrateLogPeriod = TimeDelta::Millis<10000>();
|
||||||
const int64_t kRtcEventLogPeriodMs = 5000;
|
constexpr TimeDelta kRtcEventLogPeriod = TimeDelta::Millis<5000>();
|
||||||
// Expecting that RTCP feedback is sent uniformly within [0.5, 1.5]s intervals.
|
// Expecting that RTCP feedback is sent uniformly within [0.5, 1.5]s intervals.
|
||||||
const int64_t kFeedbackIntervalMs = 5000;
|
constexpr TimeDelta kMaxRtcpFeedbackInterval = TimeDelta::Millis<5000>();
|
||||||
const int64_t kFeedbackTimeoutIntervals = 3;
|
constexpr int kFeedbackTimeoutIntervals = 3;
|
||||||
const int64_t kTimeoutIntervalMs = 1000;
|
constexpr TimeDelta kTimeoutInterval = TimeDelta::Millis<1000>();
|
||||||
|
|
||||||
const float kDefaultLowLossThreshold = 0.02f;
|
constexpr float kDefaultLowLossThreshold = 0.02f;
|
||||||
const float kDefaultHighLossThreshold = 0.1f;
|
constexpr float kDefaultHighLossThreshold = 0.1f;
|
||||||
const int kDefaultBitrateThresholdKbps = 0;
|
constexpr DataRate kDefaultBitrateThreshold = DataRate::Zero();
|
||||||
|
|
||||||
struct UmaRampUpMetric {
|
struct UmaRampUpMetric {
|
||||||
const char* metric_name;
|
const char* metric_name;
|
||||||
@ -99,7 +99,7 @@ bool ReadBweLossExperimentParameters(float* low_loss_threshold,
|
|||||||
"experiment from field trial string. Using default.";
|
"experiment from field trial string. Using default.";
|
||||||
*low_loss_threshold = kDefaultLowLossThreshold;
|
*low_loss_threshold = kDefaultLowLossThreshold;
|
||||||
*high_loss_threshold = kDefaultHighLossThreshold;
|
*high_loss_threshold = kDefaultHighLossThreshold;
|
||||||
*bitrate_threshold_kbps = kDefaultBitrateThresholdKbps;
|
*bitrate_threshold_kbps = kDefaultBitrateThreshold.kbps();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -107,33 +107,34 @@ bool ReadBweLossExperimentParameters(float* low_loss_threshold,
|
|||||||
SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log)
|
SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log)
|
||||||
: lost_packets_since_last_loss_update_(0),
|
: lost_packets_since_last_loss_update_(0),
|
||||||
expected_packets_since_last_loss_update_(0),
|
expected_packets_since_last_loss_update_(0),
|
||||||
current_bitrate_bps_(0),
|
current_bitrate_(DataRate::Zero()),
|
||||||
min_bitrate_configured_(congestion_controller::GetMinBitrateBps()),
|
min_bitrate_configured_(
|
||||||
max_bitrate_configured_(kDefaultMaxBitrateBps),
|
DataRate::bps(congestion_controller::GetMinBitrateBps())),
|
||||||
last_low_bitrate_log_ms_(-1),
|
max_bitrate_configured_(kDefaultMaxBitrate),
|
||||||
|
last_low_bitrate_log_(Timestamp::MinusInfinity()),
|
||||||
has_decreased_since_last_fraction_loss_(false),
|
has_decreased_since_last_fraction_loss_(false),
|
||||||
last_feedback_ms_(-1),
|
last_loss_feedback_(Timestamp::MinusInfinity()),
|
||||||
last_packet_report_ms_(-1),
|
last_loss_packet_report_(Timestamp::MinusInfinity()),
|
||||||
last_timeout_ms_(-1),
|
last_timeout_(Timestamp::MinusInfinity()),
|
||||||
last_fraction_loss_(0),
|
last_fraction_loss_(0),
|
||||||
last_logged_fraction_loss_(0),
|
last_logged_fraction_loss_(0),
|
||||||
last_round_trip_time_ms_(0),
|
last_round_trip_time_(TimeDelta::Zero()),
|
||||||
bwe_incoming_(0),
|
bwe_incoming_(DataRate::Zero()),
|
||||||
delay_based_bitrate_bps_(0),
|
delay_based_bitrate_(DataRate::Zero()),
|
||||||
time_last_decrease_ms_(0),
|
time_last_decrease_(Timestamp::MinusInfinity()),
|
||||||
first_report_time_ms_(-1),
|
first_report_time_(Timestamp::MinusInfinity()),
|
||||||
initially_lost_packets_(0),
|
initially_lost_packets_(0),
|
||||||
bitrate_at_2_seconds_kbps_(0),
|
bitrate_at_2_seconds_(DataRate::Zero()),
|
||||||
uma_update_state_(kNoUpdate),
|
uma_update_state_(kNoUpdate),
|
||||||
uma_rtt_state_(kNoUpdate),
|
uma_rtt_state_(kNoUpdate),
|
||||||
rampup_uma_stats_updated_(kNumUmaRampupMetrics, false),
|
rampup_uma_stats_updated_(kNumUmaRampupMetrics, false),
|
||||||
event_log_(event_log),
|
event_log_(event_log),
|
||||||
last_rtc_event_log_ms_(-1),
|
last_rtc_event_log_(Timestamp::MinusInfinity()),
|
||||||
in_timeout_experiment_(
|
in_timeout_experiment_(
|
||||||
webrtc::field_trial::IsEnabled("WebRTC-FeedbackTimeout")),
|
webrtc::field_trial::IsEnabled("WebRTC-FeedbackTimeout")),
|
||||||
low_loss_threshold_(kDefaultLowLossThreshold),
|
low_loss_threshold_(kDefaultLowLossThreshold),
|
||||||
high_loss_threshold_(kDefaultHighLossThreshold),
|
high_loss_threshold_(kDefaultHighLossThreshold),
|
||||||
bitrate_threshold_bps_(1000 * kDefaultBitrateThresholdKbps) {
|
bitrate_threshold_(kDefaultBitrateThreshold) {
|
||||||
RTC_DCHECK(event_log);
|
RTC_DCHECK(event_log);
|
||||||
if (BweLossExperimentIsEnabled()) {
|
if (BweLossExperimentIsEnabled()) {
|
||||||
uint32_t bitrate_threshold_kbps;
|
uint32_t bitrate_threshold_kbps;
|
||||||
@ -143,87 +144,87 @@ SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log)
|
|||||||
RTC_LOG(LS_INFO) << "Enabled BweLossExperiment with parameters "
|
RTC_LOG(LS_INFO) << "Enabled BweLossExperiment with parameters "
|
||||||
<< low_loss_threshold_ << ", " << high_loss_threshold_
|
<< low_loss_threshold_ << ", " << high_loss_threshold_
|
||||||
<< ", " << bitrate_threshold_kbps;
|
<< ", " << bitrate_threshold_kbps;
|
||||||
bitrate_threshold_bps_ = bitrate_threshold_kbps * 1000;
|
bitrate_threshold_ = DataRate::kbps(bitrate_threshold_kbps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {}
|
SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::SetBitrates(int send_bitrate,
|
void SendSideBandwidthEstimation::SetBitrates(
|
||||||
int min_bitrate,
|
absl::optional<DataRate> send_bitrate,
|
||||||
int max_bitrate) {
|
DataRate min_bitrate,
|
||||||
|
DataRate max_bitrate,
|
||||||
|
Timestamp at_time) {
|
||||||
SetMinMaxBitrate(min_bitrate, max_bitrate);
|
SetMinMaxBitrate(min_bitrate, max_bitrate);
|
||||||
if (send_bitrate > 0)
|
if (send_bitrate)
|
||||||
SetSendBitrate(send_bitrate);
|
SetSendBitrate(*send_bitrate, at_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::SetSendBitrate(int bitrate) {
|
void SendSideBandwidthEstimation::SetSendBitrate(DataRate bitrate,
|
||||||
RTC_DCHECK_GT(bitrate, 0);
|
Timestamp at_time) {
|
||||||
delay_based_bitrate_bps_ = 0; // Reset to avoid being capped by the estimate.
|
RTC_DCHECK(bitrate > DataRate::Zero());
|
||||||
CapBitrateToThresholds(Clock::GetRealTimeClock()->TimeInMilliseconds(),
|
// Reset to avoid being capped by the estimate.
|
||||||
bitrate);
|
delay_based_bitrate_ = DataRate::Zero();
|
||||||
|
CapBitrateToThresholds(at_time, bitrate);
|
||||||
// Clear last sent bitrate history so the new value can be used directly
|
// Clear last sent bitrate history so the new value can be used directly
|
||||||
// and not capped.
|
// and not capped.
|
||||||
min_bitrate_history_.clear();
|
min_bitrate_history_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::SetMinMaxBitrate(int min_bitrate,
|
void SendSideBandwidthEstimation::SetMinMaxBitrate(DataRate min_bitrate,
|
||||||
int max_bitrate) {
|
DataRate max_bitrate) {
|
||||||
RTC_DCHECK_GE(min_bitrate, 0);
|
|
||||||
min_bitrate_configured_ =
|
min_bitrate_configured_ =
|
||||||
std::max(min_bitrate, congestion_controller::GetMinBitrateBps());
|
std::max(min_bitrate, congestion_controller::GetMinBitrate());
|
||||||
if (max_bitrate > 0) {
|
if (max_bitrate > DataRate::Zero() && max_bitrate.IsFinite()) {
|
||||||
max_bitrate_configured_ =
|
max_bitrate_configured_ = std::max(min_bitrate_configured_, max_bitrate);
|
||||||
std::max<uint32_t>(min_bitrate_configured_, max_bitrate);
|
|
||||||
} else {
|
} else {
|
||||||
max_bitrate_configured_ = kDefaultMaxBitrateBps;
|
max_bitrate_configured_ = kDefaultMaxBitrate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SendSideBandwidthEstimation::GetMinBitrate() const {
|
int SendSideBandwidthEstimation::GetMinBitrate() const {
|
||||||
return min_bitrate_configured_;
|
return min_bitrate_configured_.bps<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::CurrentEstimate(int* bitrate,
|
void SendSideBandwidthEstimation::CurrentEstimate(int* bitrate,
|
||||||
uint8_t* loss,
|
uint8_t* loss,
|
||||||
int64_t* rtt) const {
|
int64_t* rtt) const {
|
||||||
*bitrate = current_bitrate_bps_;
|
*bitrate = current_bitrate_.bps<int>();
|
||||||
*loss = last_fraction_loss_;
|
*loss = last_fraction_loss_;
|
||||||
*rtt = last_round_trip_time_ms_;
|
*rtt = last_round_trip_time_.ms<int64_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdateReceiverEstimate(int64_t now_ms,
|
void SendSideBandwidthEstimation::UpdateReceiverEstimate(Timestamp at_time,
|
||||||
uint32_t bandwidth) {
|
DataRate bandwidth) {
|
||||||
bwe_incoming_ = bandwidth;
|
bwe_incoming_ = bandwidth;
|
||||||
CapBitrateToThresholds(now_ms, current_bitrate_bps_);
|
CapBitrateToThresholds(at_time, current_bitrate_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(
|
void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(Timestamp at_time,
|
||||||
int64_t now_ms,
|
DataRate bitrate) {
|
||||||
uint32_t bitrate_bps) {
|
delay_based_bitrate_ = bitrate;
|
||||||
delay_based_bitrate_bps_ = bitrate_bps;
|
CapBitrateToThresholds(at_time, current_bitrate_);
|
||||||
CapBitrateToThresholds(now_ms, current_bitrate_bps_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss,
|
void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss,
|
||||||
int64_t rtt_ms,
|
TimeDelta rtt,
|
||||||
int number_of_packets,
|
int number_of_packets,
|
||||||
int64_t now_ms) {
|
Timestamp at_time) {
|
||||||
const int kRoundingConstant = 128;
|
const int kRoundingConstant = 128;
|
||||||
int packets_lost = (static_cast<int>(fraction_loss) * number_of_packets +
|
int packets_lost = (static_cast<int>(fraction_loss) * number_of_packets +
|
||||||
kRoundingConstant) >>
|
kRoundingConstant) >>
|
||||||
8;
|
8;
|
||||||
UpdatePacketsLost(packets_lost, number_of_packets, now_ms);
|
UpdatePacketsLost(packets_lost, number_of_packets, at_time);
|
||||||
UpdateRtt(rtt_ms, now_ms);
|
UpdateRtt(rtt, at_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdatePacketsLost(int packets_lost,
|
void SendSideBandwidthEstimation::UpdatePacketsLost(int packets_lost,
|
||||||
int number_of_packets,
|
int number_of_packets,
|
||||||
int64_t now_ms) {
|
Timestamp at_time) {
|
||||||
last_feedback_ms_ = now_ms;
|
last_loss_feedback_ = at_time;
|
||||||
if (first_report_time_ms_ == -1)
|
if (first_report_time_.IsInfinite())
|
||||||
first_report_time_ms_ = now_ms;
|
first_report_time_ = at_time;
|
||||||
|
|
||||||
// Check sequence number diff and weight loss report
|
// Check sequence number diff and weight loss report
|
||||||
if (number_of_packets > 0) {
|
if (number_of_packets > 0) {
|
||||||
@ -244,202 +245,201 @@ void SendSideBandwidthEstimation::UpdatePacketsLost(int packets_lost,
|
|||||||
|
|
||||||
lost_packets_since_last_loss_update_ = 0;
|
lost_packets_since_last_loss_update_ = 0;
|
||||||
expected_packets_since_last_loss_update_ = 0;
|
expected_packets_since_last_loss_update_ = 0;
|
||||||
last_packet_report_ms_ = now_ms;
|
last_loss_packet_report_ = at_time;
|
||||||
UpdateEstimate(now_ms);
|
UpdateEstimate(at_time);
|
||||||
}
|
}
|
||||||
UpdateUmaStatsPacketsLost(now_ms, packets_lost);
|
UpdateUmaStatsPacketsLost(at_time, packets_lost);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdateUmaStatsPacketsLost(int64_t now_ms,
|
void SendSideBandwidthEstimation::UpdateUmaStatsPacketsLost(Timestamp at_time,
|
||||||
int packets_lost) {
|
int packets_lost) {
|
||||||
int bitrate_kbps = static_cast<int>((current_bitrate_bps_ + 500) / 1000);
|
DataRate bitrate_kbps = DataRate::kbps((current_bitrate_.bps() + 500) / 1000);
|
||||||
for (size_t i = 0; i < kNumUmaRampupMetrics; ++i) {
|
for (size_t i = 0; i < kNumUmaRampupMetrics; ++i) {
|
||||||
if (!rampup_uma_stats_updated_[i] &&
|
if (!rampup_uma_stats_updated_[i] &&
|
||||||
bitrate_kbps >= kUmaRampupMetrics[i].bitrate_kbps) {
|
bitrate_kbps.kbps() >= kUmaRampupMetrics[i].bitrate_kbps) {
|
||||||
RTC_HISTOGRAMS_COUNTS_100000(i, kUmaRampupMetrics[i].metric_name,
|
RTC_HISTOGRAMS_COUNTS_100000(i, kUmaRampupMetrics[i].metric_name,
|
||||||
now_ms - first_report_time_ms_);
|
(at_time - first_report_time_).ms());
|
||||||
rampup_uma_stats_updated_[i] = true;
|
rampup_uma_stats_updated_[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsInStartPhase(now_ms)) {
|
if (IsInStartPhase(at_time)) {
|
||||||
initially_lost_packets_ += packets_lost;
|
initially_lost_packets_ += packets_lost;
|
||||||
} else if (uma_update_state_ == kNoUpdate) {
|
} else if (uma_update_state_ == kNoUpdate) {
|
||||||
uma_update_state_ = kFirstDone;
|
uma_update_state_ = kFirstDone;
|
||||||
bitrate_at_2_seconds_kbps_ = bitrate_kbps;
|
bitrate_at_2_seconds_ = bitrate_kbps;
|
||||||
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitiallyLostPackets",
|
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitiallyLostPackets",
|
||||||
initially_lost_packets_, 0, 100, 50);
|
initially_lost_packets_, 0, 100, 50);
|
||||||
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialBandwidthEstimate",
|
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialBandwidthEstimate",
|
||||||
bitrate_at_2_seconds_kbps_, 0, 2000, 50);
|
bitrate_at_2_seconds_.kbps(), 0, 2000, 50);
|
||||||
} else if (uma_update_state_ == kFirstDone &&
|
} else if (uma_update_state_ == kFirstDone &&
|
||||||
now_ms - first_report_time_ms_ >= kBweConverganceTimeMs) {
|
at_time - first_report_time_ >= kBweConverganceTime) {
|
||||||
uma_update_state_ = kDone;
|
uma_update_state_ = kDone;
|
||||||
int bitrate_diff_kbps =
|
int bitrate_diff_kbps = std::max(
|
||||||
std::max(bitrate_at_2_seconds_kbps_ - bitrate_kbps, 0);
|
bitrate_at_2_seconds_.kbps<int>() - bitrate_kbps.kbps<int>(), 0);
|
||||||
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialVsConvergedDiff", bitrate_diff_kbps,
|
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialVsConvergedDiff", bitrate_diff_kbps,
|
||||||
0, 2000, 50);
|
0, 2000, 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdateRtt(int64_t rtt_ms, int64_t now_ms) {
|
void SendSideBandwidthEstimation::UpdateRtt(TimeDelta rtt, Timestamp at_time) {
|
||||||
// Update RTT if we were able to compute an RTT based on this RTCP.
|
// Update RTT if we were able to compute an RTT based on this RTCP.
|
||||||
// FlexFEC doesn't send RTCP SR, which means we won't be able to compute RTT.
|
// FlexFEC doesn't send RTCP SR, which means we won't be able to compute RTT.
|
||||||
if (rtt_ms > 0)
|
if (rtt > TimeDelta::Zero())
|
||||||
last_round_trip_time_ms_ = rtt_ms;
|
last_round_trip_time_ = rtt;
|
||||||
|
|
||||||
if (!IsInStartPhase(now_ms) && uma_rtt_state_ == kNoUpdate) {
|
if (!IsInStartPhase(at_time) && uma_rtt_state_ == kNoUpdate) {
|
||||||
uma_rtt_state_ = kDone;
|
uma_rtt_state_ = kDone;
|
||||||
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialRtt", static_cast<int>(rtt_ms), 0,
|
RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialRtt", rtt.ms<int>(), 0, 2000, 50);
|
||||||
2000, 50);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) {
|
void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) {
|
||||||
uint32_t new_bitrate = current_bitrate_bps_;
|
DataRate new_bitrate = current_bitrate_;
|
||||||
// We trust the REMB and/or delay-based estimate during the first 2 seconds if
|
// We trust the REMB and/or delay-based estimate during the first 2 seconds if
|
||||||
// we haven't had any packet loss reported, to allow startup bitrate probing.
|
// we haven't had any packet loss reported, to allow startup bitrate probing.
|
||||||
if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms)) {
|
if (last_fraction_loss_ == 0 && IsInStartPhase(at_time)) {
|
||||||
new_bitrate = std::max(bwe_incoming_, new_bitrate);
|
new_bitrate = std::max(bwe_incoming_, new_bitrate);
|
||||||
new_bitrate = std::max(delay_based_bitrate_bps_, new_bitrate);
|
new_bitrate = std::max(delay_based_bitrate_, new_bitrate);
|
||||||
|
|
||||||
if (new_bitrate != current_bitrate_bps_) {
|
if (new_bitrate != current_bitrate_) {
|
||||||
min_bitrate_history_.clear();
|
min_bitrate_history_.clear();
|
||||||
min_bitrate_history_.push_back(
|
min_bitrate_history_.push_back(std::make_pair(at_time, current_bitrate_));
|
||||||
std::make_pair(now_ms, current_bitrate_bps_));
|
CapBitrateToThresholds(at_time, new_bitrate);
|
||||||
CapBitrateToThresholds(now_ms, new_bitrate);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateMinHistory(now_ms);
|
UpdateMinHistory(at_time);
|
||||||
if (last_packet_report_ms_ == -1) {
|
if (last_loss_packet_report_.IsInfinite()) {
|
||||||
// No feedback received.
|
// No feedback received.
|
||||||
CapBitrateToThresholds(now_ms, current_bitrate_bps_);
|
CapBitrateToThresholds(at_time, current_bitrate_);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int64_t time_since_packet_report_ms = now_ms - last_packet_report_ms_;
|
TimeDelta time_since_loss_packet_report = at_time - last_loss_packet_report_;
|
||||||
int64_t time_since_feedback_ms = now_ms - last_feedback_ms_;
|
TimeDelta time_since_loss_feedback = at_time - last_loss_feedback_;
|
||||||
if (time_since_packet_report_ms < 1.2 * kFeedbackIntervalMs) {
|
if (time_since_loss_packet_report < 1.2 * kMaxRtcpFeedbackInterval) {
|
||||||
// We only care about loss above a given bitrate threshold.
|
// We only care about loss above a given bitrate threshold.
|
||||||
float loss = last_fraction_loss_ / 256.0f;
|
float loss = last_fraction_loss_ / 256.0f;
|
||||||
// We only make decisions based on loss when the bitrate is above a
|
// We only make decisions based on loss when the bitrate is above a
|
||||||
// threshold. This is a crude way of handling loss which is uncorrelated
|
// threshold. This is a crude way of handling loss which is uncorrelated
|
||||||
// to congestion.
|
// to congestion.
|
||||||
if (current_bitrate_bps_ < bitrate_threshold_bps_ ||
|
if (current_bitrate_ < bitrate_threshold_ || loss <= low_loss_threshold_) {
|
||||||
loss <= low_loss_threshold_) {
|
|
||||||
// Loss < 2%: Increase rate by 8% of the min bitrate in the last
|
// Loss < 2%: Increase rate by 8% of the min bitrate in the last
|
||||||
// kBweIncreaseIntervalMs.
|
// kBweIncreaseInterval.
|
||||||
// Note that by remembering the bitrate over the last second one can
|
// Note that by remembering the bitrate over the last second one can
|
||||||
// rampup up one second faster than if only allowed to start ramping
|
// rampup up one second faster than if only allowed to start ramping
|
||||||
// at 8% per second rate now. E.g.:
|
// at 8% per second rate now. E.g.:
|
||||||
// If sending a constant 100kbps it can rampup immediatly to 108kbps
|
// If sending a constant 100kbps it can rampup immediatly to 108kbps
|
||||||
// whenever a receiver report is received with lower packet loss.
|
// whenever a receiver report is received with lower packet loss.
|
||||||
// If instead one would do: current_bitrate_bps_ *= 1.08^(delta time),
|
// If instead one would do: current_bitrate_ *= 1.08^(delta time),
|
||||||
// it would take over one second since the lower packet loss to achieve
|
// it would take over one second since the lower packet loss to achieve
|
||||||
// 108kbps.
|
// 108kbps.
|
||||||
new_bitrate = static_cast<uint32_t>(
|
new_bitrate =
|
||||||
min_bitrate_history_.front().second * 1.08 + 0.5);
|
DataRate::bps(min_bitrate_history_.front().second.bps() * 1.08 + 0.5);
|
||||||
|
|
||||||
// Add 1 kbps extra, just to make sure that we do not get stuck
|
// Add 1 kbps extra, just to make sure that we do not get stuck
|
||||||
// (gives a little extra increase at low rates, negligible at higher
|
// (gives a little extra increase at low rates, negligible at higher
|
||||||
// rates).
|
// rates).
|
||||||
new_bitrate += 1000;
|
new_bitrate += DataRate::bps(1000);
|
||||||
} else if (current_bitrate_bps_ > bitrate_threshold_bps_) {
|
} else if (current_bitrate_ > bitrate_threshold_) {
|
||||||
if (loss <= high_loss_threshold_) {
|
if (loss <= high_loss_threshold_) {
|
||||||
// Loss between 2% - 10%: Do nothing.
|
// Loss between 2% - 10%: Do nothing.
|
||||||
} else {
|
} else {
|
||||||
// Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs
|
// Loss > 10%: Limit the rate decreases to once a kBweDecreaseInterval
|
||||||
// + rtt.
|
// + rtt.
|
||||||
if (!has_decreased_since_last_fraction_loss_ &&
|
if (!has_decreased_since_last_fraction_loss_ &&
|
||||||
(now_ms - time_last_decrease_ms_) >=
|
(at_time - time_last_decrease_) >=
|
||||||
(kBweDecreaseIntervalMs + last_round_trip_time_ms_)) {
|
(kBweDecreaseInterval + last_round_trip_time_)) {
|
||||||
time_last_decrease_ms_ = now_ms;
|
time_last_decrease_ = at_time;
|
||||||
|
|
||||||
// Reduce rate:
|
// Reduce rate:
|
||||||
// newRate = rate * (1 - 0.5*lossRate);
|
// newRate = rate * (1 - 0.5*lossRate);
|
||||||
// where packetLoss = 256*lossRate;
|
// where packetLoss = 256*lossRate;
|
||||||
new_bitrate = static_cast<uint32_t>(
|
new_bitrate =
|
||||||
(current_bitrate_bps_ *
|
DataRate::bps((current_bitrate_.bps() *
|
||||||
static_cast<double>(512 - last_fraction_loss_)) /
|
static_cast<double>(512 - last_fraction_loss_)) /
|
||||||
512.0);
|
512.0);
|
||||||
has_decreased_since_last_fraction_loss_ = true;
|
has_decreased_since_last_fraction_loss_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (time_since_feedback_ms >
|
} else if (time_since_loss_feedback >
|
||||||
kFeedbackTimeoutIntervals * kFeedbackIntervalMs &&
|
kFeedbackTimeoutIntervals * kMaxRtcpFeedbackInterval &&
|
||||||
(last_timeout_ms_ == -1 ||
|
(last_timeout_.IsInfinite() ||
|
||||||
now_ms - last_timeout_ms_ > kTimeoutIntervalMs)) {
|
at_time - last_timeout_ > kTimeoutInterval)) {
|
||||||
if (in_timeout_experiment_) {
|
if (in_timeout_experiment_) {
|
||||||
RTC_LOG(LS_WARNING) << "Feedback timed out (" << time_since_feedback_ms
|
RTC_LOG(LS_WARNING) << "Feedback timed out ("
|
||||||
<< " ms), reducing bitrate.";
|
<< ToString(time_since_loss_feedback)
|
||||||
new_bitrate *= 0.8;
|
<< "), reducing bitrate.";
|
||||||
|
new_bitrate = new_bitrate * 0.8;
|
||||||
// Reset accumulators since we've already acted on missing feedback and
|
// Reset accumulators since we've already acted on missing feedback and
|
||||||
// shouldn't to act again on these old lost packets.
|
// shouldn't to act again on these old lost packets.
|
||||||
lost_packets_since_last_loss_update_ = 0;
|
lost_packets_since_last_loss_update_ = 0;
|
||||||
expected_packets_since_last_loss_update_ = 0;
|
expected_packets_since_last_loss_update_ = 0;
|
||||||
last_timeout_ms_ = now_ms;
|
last_timeout_ = at_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CapBitrateToThresholds(now_ms, new_bitrate);
|
CapBitrateToThresholds(at_time, new_bitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const {
|
bool SendSideBandwidthEstimation::IsInStartPhase(Timestamp at_time) const {
|
||||||
return first_report_time_ms_ == -1 ||
|
return first_report_time_.IsInfinite() ||
|
||||||
now_ms - first_report_time_ms_ < kStartPhaseMs;
|
at_time - first_report_time_ < kStartPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::UpdateMinHistory(int64_t now_ms) {
|
void SendSideBandwidthEstimation::UpdateMinHistory(Timestamp at_time) {
|
||||||
// Remove old data points from history.
|
// Remove old data points from history.
|
||||||
// Since history precision is in ms, add one so it is able to increase
|
// Since history precision is in ms, add one so it is able to increase
|
||||||
// bitrate if it is off by as little as 0.5ms.
|
// bitrate if it is off by as little as 0.5ms.
|
||||||
while (!min_bitrate_history_.empty() &&
|
while (!min_bitrate_history_.empty() &&
|
||||||
now_ms - min_bitrate_history_.front().first + 1 >
|
at_time - min_bitrate_history_.front().first + TimeDelta::ms(1) >
|
||||||
kBweIncreaseIntervalMs) {
|
kBweIncreaseInterval) {
|
||||||
min_bitrate_history_.pop_front();
|
min_bitrate_history_.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Typical minimum sliding-window algorithm: Pop values higher than current
|
// Typical minimum sliding-window algorithm: Pop values higher than current
|
||||||
// bitrate before pushing it.
|
// bitrate before pushing it.
|
||||||
while (!min_bitrate_history_.empty() &&
|
while (!min_bitrate_history_.empty() &&
|
||||||
current_bitrate_bps_ <= min_bitrate_history_.back().second) {
|
current_bitrate_ <= min_bitrate_history_.back().second) {
|
||||||
min_bitrate_history_.pop_back();
|
min_bitrate_history_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
min_bitrate_history_.push_back(std::make_pair(now_ms, current_bitrate_bps_));
|
min_bitrate_history_.push_back(std::make_pair(at_time, current_bitrate_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSideBandwidthEstimation::CapBitrateToThresholds(int64_t now_ms,
|
void SendSideBandwidthEstimation::CapBitrateToThresholds(Timestamp at_time,
|
||||||
uint32_t bitrate_bps) {
|
DataRate bitrate) {
|
||||||
if (bwe_incoming_ > 0 && bitrate_bps > bwe_incoming_) {
|
if (bwe_incoming_ > DataRate::Zero() && bitrate > bwe_incoming_) {
|
||||||
bitrate_bps = bwe_incoming_;
|
bitrate = bwe_incoming_;
|
||||||
}
|
}
|
||||||
if (delay_based_bitrate_bps_ > 0 && bitrate_bps > delay_based_bitrate_bps_) {
|
if (delay_based_bitrate_ > DataRate::Zero() &&
|
||||||
bitrate_bps = delay_based_bitrate_bps_;
|
bitrate > delay_based_bitrate_) {
|
||||||
|
bitrate = delay_based_bitrate_;
|
||||||
}
|
}
|
||||||
if (bitrate_bps > max_bitrate_configured_) {
|
if (bitrate > max_bitrate_configured_) {
|
||||||
bitrate_bps = max_bitrate_configured_;
|
bitrate = max_bitrate_configured_;
|
||||||
}
|
}
|
||||||
if (bitrate_bps < min_bitrate_configured_) {
|
if (bitrate < min_bitrate_configured_) {
|
||||||
if (last_low_bitrate_log_ms_ == -1 ||
|
if (last_low_bitrate_log_.IsInfinite() ||
|
||||||
now_ms - last_low_bitrate_log_ms_ > kLowBitrateLogPeriodMs) {
|
at_time - last_low_bitrate_log_ > kLowBitrateLogPeriod) {
|
||||||
RTC_LOG(LS_WARNING) << "Estimated available bandwidth "
|
RTC_LOG(LS_WARNING) << "Estimated available bandwidth "
|
||||||
<< bitrate_bps / 1000
|
<< ToString(bitrate)
|
||||||
<< " kbps is below configured min bitrate "
|
<< " is below configured min bitrate "
|
||||||
<< min_bitrate_configured_ / 1000 << " kbps.";
|
<< ToString(min_bitrate_configured_) << ".";
|
||||||
last_low_bitrate_log_ms_ = now_ms;
|
last_low_bitrate_log_ = at_time;
|
||||||
}
|
}
|
||||||
bitrate_bps = min_bitrate_configured_;
|
bitrate = min_bitrate_configured_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitrate_bps != current_bitrate_bps_ ||
|
if (bitrate != current_bitrate_ ||
|
||||||
last_fraction_loss_ != last_logged_fraction_loss_ ||
|
last_fraction_loss_ != last_logged_fraction_loss_ ||
|
||||||
now_ms - last_rtc_event_log_ms_ > kRtcEventLogPeriodMs) {
|
at_time - last_rtc_event_log_ > kRtcEventLogPeriod) {
|
||||||
event_log_->Log(absl::make_unique<RtcEventBweUpdateLossBased>(
|
event_log_->Log(absl::make_unique<RtcEventBweUpdateLossBased>(
|
||||||
bitrate_bps, last_fraction_loss_,
|
bitrate.bps(), last_fraction_loss_,
|
||||||
expected_packets_since_last_loss_update_));
|
expected_packets_since_last_loss_update_));
|
||||||
last_logged_fraction_loss_ = last_fraction_loss_;
|
last_logged_fraction_loss_ = last_fraction_loss_;
|
||||||
last_rtc_event_log_ms_ = now_ms;
|
last_rtc_event_log_ = at_time;
|
||||||
}
|
}
|
||||||
current_bitrate_bps_ = bitrate_bps;
|
current_bitrate_ = bitrate;
|
||||||
}
|
}
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/types/optional.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -32,83 +33,86 @@ class SendSideBandwidthEstimation {
|
|||||||
void CurrentEstimate(int* bitrate, uint8_t* loss, int64_t* rtt) const;
|
void CurrentEstimate(int* bitrate, uint8_t* loss, int64_t* rtt) const;
|
||||||
|
|
||||||
// Call periodically to update estimate.
|
// Call periodically to update estimate.
|
||||||
void UpdateEstimate(int64_t now_ms);
|
void UpdateEstimate(Timestamp at_time);
|
||||||
|
|
||||||
// Call when we receive a RTCP message with TMMBR or REMB.
|
// Call when we receive a RTCP message with TMMBR or REMB.
|
||||||
void UpdateReceiverEstimate(int64_t now_ms, uint32_t bandwidth);
|
void UpdateReceiverEstimate(Timestamp at_time, DataRate bandwidth);
|
||||||
|
|
||||||
// Call when a new delay-based estimate is available.
|
// Call when a new delay-based estimate is available.
|
||||||
void UpdateDelayBasedEstimate(int64_t now_ms, uint32_t bitrate_bps);
|
void UpdateDelayBasedEstimate(Timestamp at_time, DataRate bitrate);
|
||||||
|
|
||||||
// Call when we receive a RTCP message with a ReceiveBlock.
|
// Call when we receive a RTCP message with a ReceiveBlock.
|
||||||
void UpdateReceiverBlock(uint8_t fraction_loss,
|
void UpdateReceiverBlock(uint8_t fraction_loss,
|
||||||
int64_t rtt_ms,
|
TimeDelta rtt_ms,
|
||||||
int number_of_packets,
|
int number_of_packets,
|
||||||
int64_t now_ms);
|
Timestamp at_time);
|
||||||
|
|
||||||
// Call when we receive a RTCP message with a ReceiveBlock.
|
// Call when we receive a RTCP message with a ReceiveBlock.
|
||||||
void UpdatePacketsLost(int packets_lost,
|
void UpdatePacketsLost(int packets_lost,
|
||||||
int number_of_packets,
|
int number_of_packets,
|
||||||
int64_t now_ms);
|
Timestamp at_time);
|
||||||
|
|
||||||
// Call when we receive a RTCP message with a ReceiveBlock.
|
// Call when we receive a RTCP message with a ReceiveBlock.
|
||||||
void UpdateRtt(int64_t rtt, int64_t now_ms);
|
void UpdateRtt(TimeDelta rtt, Timestamp at_time);
|
||||||
|
|
||||||
void SetBitrates(int send_bitrate, int min_bitrate, int max_bitrate);
|
void SetBitrates(absl::optional<DataRate> send_bitrate,
|
||||||
void SetSendBitrate(int bitrate);
|
DataRate min_bitrate,
|
||||||
void SetMinMaxBitrate(int min_bitrate, int max_bitrate);
|
DataRate max_bitrate,
|
||||||
|
Timestamp at_time);
|
||||||
|
void SetSendBitrate(DataRate bitrate, Timestamp at_time);
|
||||||
|
void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate);
|
||||||
int GetMinBitrate() const;
|
int GetMinBitrate() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum UmaState { kNoUpdate, kFirstDone, kDone };
|
enum UmaState { kNoUpdate, kFirstDone, kDone };
|
||||||
|
|
||||||
bool IsInStartPhase(int64_t now_ms) const;
|
bool IsInStartPhase(Timestamp at_time) const;
|
||||||
|
|
||||||
void UpdateUmaStatsPacketsLost(int64_t now_ms, int packets_lost);
|
void UpdateUmaStatsPacketsLost(Timestamp at_time, int packets_lost);
|
||||||
|
|
||||||
// Updates history of min bitrates.
|
// Updates history of min bitrates.
|
||||||
// After this method returns min_bitrate_history_.front().second contains the
|
// After this method returns min_bitrate_history_.front().second contains the
|
||||||
// min bitrate used during last kBweIncreaseIntervalMs.
|
// min bitrate used during last kBweIncreaseIntervalMs.
|
||||||
void UpdateMinHistory(int64_t now_ms);
|
void UpdateMinHistory(Timestamp at_time);
|
||||||
|
|
||||||
// Cap |bitrate_bps| to [min_bitrate_configured_, max_bitrate_configured_] and
|
// Cap |bitrate| to [min_bitrate_configured_, max_bitrate_configured_] and
|
||||||
// set |current_bitrate_bps_| to the capped value and updates the event log.
|
// set |current_bitrate_| to the capped value and updates the event log.
|
||||||
void CapBitrateToThresholds(int64_t now_ms, uint32_t bitrate_bps);
|
void CapBitrateToThresholds(Timestamp at_time, DataRate bitrate);
|
||||||
|
|
||||||
std::deque<std::pair<int64_t, uint32_t> > min_bitrate_history_;
|
std::deque<std::pair<Timestamp, DataRate> > min_bitrate_history_;
|
||||||
|
|
||||||
// incoming filters
|
// incoming filters
|
||||||
int lost_packets_since_last_loss_update_;
|
int lost_packets_since_last_loss_update_;
|
||||||
int expected_packets_since_last_loss_update_;
|
int expected_packets_since_last_loss_update_;
|
||||||
|
|
||||||
uint32_t current_bitrate_bps_;
|
DataRate current_bitrate_;
|
||||||
uint32_t min_bitrate_configured_;
|
DataRate min_bitrate_configured_;
|
||||||
uint32_t max_bitrate_configured_;
|
DataRate max_bitrate_configured_;
|
||||||
int64_t last_low_bitrate_log_ms_;
|
Timestamp last_low_bitrate_log_;
|
||||||
|
|
||||||
bool has_decreased_since_last_fraction_loss_;
|
bool has_decreased_since_last_fraction_loss_;
|
||||||
int64_t last_feedback_ms_;
|
Timestamp last_loss_feedback_;
|
||||||
int64_t last_packet_report_ms_;
|
Timestamp last_loss_packet_report_;
|
||||||
int64_t last_timeout_ms_;
|
Timestamp last_timeout_;
|
||||||
uint8_t last_fraction_loss_;
|
uint8_t last_fraction_loss_;
|
||||||
uint8_t last_logged_fraction_loss_;
|
uint8_t last_logged_fraction_loss_;
|
||||||
int64_t last_round_trip_time_ms_;
|
TimeDelta last_round_trip_time_;
|
||||||
|
|
||||||
uint32_t bwe_incoming_;
|
DataRate bwe_incoming_;
|
||||||
uint32_t delay_based_bitrate_bps_;
|
DataRate delay_based_bitrate_;
|
||||||
int64_t time_last_decrease_ms_;
|
Timestamp time_last_decrease_;
|
||||||
int64_t first_report_time_ms_;
|
Timestamp first_report_time_;
|
||||||
int initially_lost_packets_;
|
int initially_lost_packets_;
|
||||||
int bitrate_at_2_seconds_kbps_;
|
DataRate bitrate_at_2_seconds_;
|
||||||
UmaState uma_update_state_;
|
UmaState uma_update_state_;
|
||||||
UmaState uma_rtt_state_;
|
UmaState uma_rtt_state_;
|
||||||
std::vector<bool> rampup_uma_stats_updated_;
|
std::vector<bool> rampup_uma_stats_updated_;
|
||||||
RtcEventLog* event_log_;
|
RtcEventLog* event_log_;
|
||||||
int64_t last_rtc_event_log_ms_;
|
Timestamp last_rtc_event_log_;
|
||||||
bool in_timeout_experiment_;
|
bool in_timeout_experiment_;
|
||||||
float low_loss_threshold_;
|
float low_loss_threshold_;
|
||||||
float high_loss_threshold_;
|
float high_loss_threshold_;
|
||||||
uint32_t bitrate_threshold_bps_;
|
DataRate bitrate_threshold_;
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // MODULES_BITRATE_CONTROLLER_SEND_SIDE_BANDWIDTH_ESTIMATION_H_
|
#endif // MODULES_BITRATE_CONTROLLER_SEND_SIDE_BANDWIDTH_ESTIMATION_H_
|
||||||
|
@ -35,24 +35,25 @@ MATCHER(LossBasedBweUpdateWithBitrateAndLossFraction, "") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TestProbing(bool use_delay_based) {
|
void TestProbing(bool use_delay_based) {
|
||||||
MockRtcEventLog event_log;
|
testing::NiceMock<MockRtcEventLog> event_log;
|
||||||
SendSideBandwidthEstimation bwe(&event_log);
|
SendSideBandwidthEstimation bwe(&event_log);
|
||||||
bwe.SetMinMaxBitrate(100000, 1500000);
|
int64_t now_ms = 0;
|
||||||
bwe.SetSendBitrate(200000);
|
bwe.SetMinMaxBitrate(DataRate::bps(100000), DataRate::bps(1500000));
|
||||||
|
bwe.SetSendBitrate(DataRate::bps(200000), Timestamp::ms(now_ms));
|
||||||
|
|
||||||
const int kRembBps = 1000000;
|
const int kRembBps = 1000000;
|
||||||
const int kSecondRembBps = kRembBps + 500000;
|
const int kSecondRembBps = kRembBps + 500000;
|
||||||
int64_t now_ms = 0;
|
|
||||||
|
|
||||||
bwe.UpdateReceiverBlock(0, 50, 1, now_ms);
|
bwe.UpdateReceiverBlock(0, TimeDelta::ms(50), 1, Timestamp::ms(now_ms));
|
||||||
|
|
||||||
// Initial REMB applies immediately.
|
// Initial REMB applies immediately.
|
||||||
if (use_delay_based) {
|
if (use_delay_based) {
|
||||||
bwe.UpdateDelayBasedEstimate(now_ms, kRembBps);
|
bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
|
||||||
|
DataRate::bps(kRembBps));
|
||||||
} else {
|
} else {
|
||||||
bwe.UpdateReceiverEstimate(now_ms, kRembBps);
|
bwe.UpdateReceiverEstimate(Timestamp::ms(now_ms), DataRate::bps(kRembBps));
|
||||||
}
|
}
|
||||||
bwe.UpdateEstimate(now_ms);
|
bwe.UpdateEstimate(Timestamp::ms(now_ms));
|
||||||
int bitrate;
|
int bitrate;
|
||||||
uint8_t fraction_loss;
|
uint8_t fraction_loss;
|
||||||
int64_t rtt;
|
int64_t rtt;
|
||||||
@ -62,11 +63,13 @@ void TestProbing(bool use_delay_based) {
|
|||||||
// Second REMB doesn't apply immediately.
|
// Second REMB doesn't apply immediately.
|
||||||
now_ms += 2001;
|
now_ms += 2001;
|
||||||
if (use_delay_based) {
|
if (use_delay_based) {
|
||||||
bwe.UpdateDelayBasedEstimate(now_ms, kSecondRembBps);
|
bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
|
||||||
|
DataRate::bps(kSecondRembBps));
|
||||||
} else {
|
} else {
|
||||||
bwe.UpdateReceiverEstimate(now_ms, kSecondRembBps);
|
bwe.UpdateReceiverEstimate(Timestamp::ms(now_ms),
|
||||||
|
DataRate::bps(kSecondRembBps));
|
||||||
}
|
}
|
||||||
bwe.UpdateEstimate(now_ms);
|
bwe.UpdateEstimate(Timestamp::ms(now_ms));
|
||||||
bitrate = 0;
|
bitrate = 0;
|
||||||
bwe.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
|
bwe.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
|
||||||
EXPECT_EQ(kRembBps, bitrate);
|
EXPECT_EQ(kRembBps, bitrate);
|
||||||
@ -86,17 +89,18 @@ TEST(SendSideBweTest, DoesntReapplyBitrateDecreaseWithoutFollowingRemb) {
|
|||||||
.Times(1);
|
.Times(1);
|
||||||
EXPECT_CALL(event_log,
|
EXPECT_CALL(event_log,
|
||||||
LogProxy(LossBasedBweUpdateWithBitrateAndLossFraction()))
|
LogProxy(LossBasedBweUpdateWithBitrateAndLossFraction()))
|
||||||
.Times(2);
|
.Times(1);
|
||||||
SendSideBandwidthEstimation bwe(&event_log);
|
SendSideBandwidthEstimation bwe(&event_log);
|
||||||
static const int kMinBitrateBps = 100000;
|
static const int kMinBitrateBps = 100000;
|
||||||
static const int kInitialBitrateBps = 1000000;
|
static const int kInitialBitrateBps = 1000000;
|
||||||
bwe.SetMinMaxBitrate(kMinBitrateBps, 1500000);
|
int64_t now_ms = 1000;
|
||||||
bwe.SetSendBitrate(kInitialBitrateBps);
|
bwe.SetMinMaxBitrate(DataRate::bps(kMinBitrateBps), DataRate::bps(1500000));
|
||||||
|
bwe.SetSendBitrate(DataRate::bps(kInitialBitrateBps), Timestamp::ms(now_ms));
|
||||||
|
|
||||||
static const uint8_t kFractionLoss = 128;
|
static const uint8_t kFractionLoss = 128;
|
||||||
static const int64_t kRttMs = 50;
|
static const int64_t kRttMs = 50;
|
||||||
|
now_ms += 10000;
|
||||||
|
|
||||||
int64_t now_ms = 0;
|
|
||||||
int bitrate_bps;
|
int bitrate_bps;
|
||||||
uint8_t fraction_loss;
|
uint8_t fraction_loss;
|
||||||
int64_t rtt_ms;
|
int64_t rtt_ms;
|
||||||
@ -106,10 +110,11 @@ TEST(SendSideBweTest, DoesntReapplyBitrateDecreaseWithoutFollowingRemb) {
|
|||||||
EXPECT_EQ(0, rtt_ms);
|
EXPECT_EQ(0, rtt_ms);
|
||||||
|
|
||||||
// Signal heavy loss to go down in bitrate.
|
// Signal heavy loss to go down in bitrate.
|
||||||
bwe.UpdateReceiverBlock(kFractionLoss, kRttMs, 100, now_ms);
|
bwe.UpdateReceiverBlock(kFractionLoss, TimeDelta::ms(kRttMs), 100,
|
||||||
|
Timestamp::ms(now_ms));
|
||||||
// Trigger an update 2 seconds later to not be rate limited.
|
// Trigger an update 2 seconds later to not be rate limited.
|
||||||
now_ms += 1000;
|
now_ms += 1000;
|
||||||
bwe.UpdateEstimate(now_ms);
|
bwe.UpdateEstimate(Timestamp::ms(now_ms));
|
||||||
|
|
||||||
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
||||||
EXPECT_LT(bitrate_bps, kInitialBitrateBps);
|
EXPECT_LT(bitrate_bps, kInitialBitrateBps);
|
||||||
@ -127,7 +132,7 @@ TEST(SendSideBweTest, DoesntReapplyBitrateDecreaseWithoutFollowingRemb) {
|
|||||||
// Trigger an update 2 seconds later to not be rate limited (but it still
|
// Trigger an update 2 seconds later to not be rate limited (but it still
|
||||||
// shouldn't update).
|
// shouldn't update).
|
||||||
now_ms += 1000;
|
now_ms += 1000;
|
||||||
bwe.UpdateEstimate(now_ms);
|
bwe.UpdateEstimate(Timestamp::ms(now_ms));
|
||||||
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
||||||
|
|
||||||
EXPECT_EQ(last_bitrate_bps, bitrate_bps);
|
EXPECT_EQ(last_bitrate_bps, bitrate_bps);
|
||||||
@ -150,16 +155,18 @@ TEST(SendSideBweTest, SettingSendBitrateOverridesDelayBasedEstimate) {
|
|||||||
uint8_t fraction_loss;
|
uint8_t fraction_loss;
|
||||||
int64_t rtt_ms;
|
int64_t rtt_ms;
|
||||||
|
|
||||||
bwe.SetMinMaxBitrate(kMinBitrateBps, kMaxBitrateBps);
|
bwe.SetMinMaxBitrate(DataRate::bps(kMinBitrateBps),
|
||||||
bwe.SetSendBitrate(kInitialBitrateBps);
|
DataRate::bps(kMaxBitrateBps));
|
||||||
|
bwe.SetSendBitrate(DataRate::bps(kInitialBitrateBps), Timestamp::ms(now_ms));
|
||||||
|
|
||||||
bwe.UpdateDelayBasedEstimate(now_ms, kDelayBasedBitrateBps);
|
bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
|
||||||
bwe.UpdateEstimate(now_ms);
|
DataRate::bps(kDelayBasedBitrateBps));
|
||||||
|
bwe.UpdateEstimate(Timestamp::ms(now_ms));
|
||||||
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
||||||
EXPECT_GE(bitrate_bps, kInitialBitrateBps);
|
EXPECT_GE(bitrate_bps, kInitialBitrateBps);
|
||||||
EXPECT_LE(bitrate_bps, kDelayBasedBitrateBps);
|
EXPECT_LE(bitrate_bps, kDelayBasedBitrateBps);
|
||||||
|
|
||||||
bwe.SetSendBitrate(kForcedHighBitrate);
|
bwe.SetSendBitrate(DataRate::bps(kForcedHighBitrate), Timestamp::ms(now_ms));
|
||||||
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
|
||||||
EXPECT_EQ(bitrate_bps, kForcedHighBitrate);
|
EXPECT_EQ(bitrate_bps, kForcedHighBitrate);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ NetworkControlUpdate GoogCcNetworkController::OnNetworkAvailability(
|
|||||||
|
|
||||||
NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
|
NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
|
||||||
NetworkRouteChange msg) {
|
NetworkRouteChange msg) {
|
||||||
int64_t min_bitrate_bps = GetBpsOrDefault(msg.constraints.min_data_rate, -1);
|
int64_t min_bitrate_bps = GetBpsOrDefault(msg.constraints.min_data_rate, 0);
|
||||||
int64_t max_bitrate_bps = GetBpsOrDefault(msg.constraints.max_data_rate, -1);
|
int64_t max_bitrate_bps = GetBpsOrDefault(msg.constraints.max_data_rate, -1);
|
||||||
int64_t start_bitrate_bps =
|
int64_t start_bitrate_bps =
|
||||||
GetBpsOrDefault(msg.constraints.starting_rate, -1);
|
GetBpsOrDefault(msg.constraints.starting_rate, -1);
|
||||||
@ -167,8 +167,10 @@ NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
|
|||||||
|
|
||||||
bandwidth_estimation_ =
|
bandwidth_estimation_ =
|
||||||
absl::make_unique<SendSideBandwidthEstimation>(event_log_);
|
absl::make_unique<SendSideBandwidthEstimation>(event_log_);
|
||||||
bandwidth_estimation_->SetBitrates(start_bitrate_bps, min_bitrate_bps,
|
bandwidth_estimation_->SetBitrates(
|
||||||
max_bitrate_bps);
|
msg.constraints.starting_rate, DataRate::bps(min_bitrate_bps),
|
||||||
|
msg.constraints.max_data_rate.value_or(DataRate::Infinity()),
|
||||||
|
msg.at_time);
|
||||||
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(start_bitrate_bps);
|
delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
|
||||||
@ -206,7 +208,7 @@ NetworkControlUpdate GoogCcNetworkController::OnProcessInterval(
|
|||||||
initial_config_.reset();
|
initial_config_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bandwidth_estimation_->UpdateEstimate(msg.at_time.ms());
|
bandwidth_estimation_->UpdateEstimate(msg.at_time);
|
||||||
absl::optional<int64_t> start_time_ms =
|
absl::optional<int64_t> start_time_ms =
|
||||||
alr_detector_->GetApplicationLimitedRegionStartTime();
|
alr_detector_->GetApplicationLimitedRegionStartTime();
|
||||||
probe_controller_->SetAlrStartTimeMs(start_time_ms);
|
probe_controller_->SetAlrStartTimeMs(start_time_ms);
|
||||||
@ -225,8 +227,8 @@ NetworkControlUpdate GoogCcNetworkController::OnRemoteBitrateReport(
|
|||||||
RTC_LOG(LS_ERROR) << "Received REMB for packet feedback only GoogCC";
|
RTC_LOG(LS_ERROR) << "Received REMB for packet feedback only GoogCC";
|
||||||
return NetworkControlUpdate();
|
return NetworkControlUpdate();
|
||||||
}
|
}
|
||||||
bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time.ms(),
|
bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time,
|
||||||
msg.bandwidth.bps());
|
msg.bandwidth);
|
||||||
BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(),
|
BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(),
|
||||||
msg.bandwidth.bps() / 1000);
|
msg.bandwidth.bps() / 1000);
|
||||||
return NetworkControlUpdate();
|
return NetworkControlUpdate();
|
||||||
@ -239,8 +241,7 @@ NetworkControlUpdate GoogCcNetworkController::OnRoundTripTimeUpdate(
|
|||||||
if (msg.smoothed) {
|
if (msg.smoothed) {
|
||||||
delay_based_bwe_->OnRttUpdate(msg.round_trip_time.ms());
|
delay_based_bwe_->OnRttUpdate(msg.round_trip_time.ms());
|
||||||
} else {
|
} else {
|
||||||
bandwidth_estimation_->UpdateRtt(msg.round_trip_time.ms(),
|
bandwidth_estimation_->UpdateRtt(msg.round_trip_time, msg.receive_time);
|
||||||
msg.receive_time.ms());
|
|
||||||
}
|
}
|
||||||
return NetworkControlUpdate();
|
return NetworkControlUpdate();
|
||||||
}
|
}
|
||||||
@ -307,8 +308,10 @@ GoogCcNetworkController::UpdateBitrateConstraints(
|
|||||||
min_bitrate_bps, start_bitrate_bps, max_bitrate_bps,
|
min_bitrate_bps, start_bitrate_bps, max_bitrate_bps,
|
||||||
constraints.at_time.ms()));
|
constraints.at_time.ms()));
|
||||||
|
|
||||||
bandwidth_estimation_->SetBitrates(start_bitrate_bps, min_bitrate_bps,
|
bandwidth_estimation_->SetBitrates(
|
||||||
max_bitrate_bps);
|
starting_rate, DataRate::bps(min_bitrate_bps),
|
||||||
|
constraints.max_data_rate.value_or(DataRate::Infinity()),
|
||||||
|
constraints.at_time);
|
||||||
if (start_bitrate_bps > 0)
|
if (start_bitrate_bps > 0)
|
||||||
delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
|
delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
|
||||||
delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
|
delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
|
||||||
@ -322,7 +325,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportLossReport(
|
|||||||
int64_t total_packets_delta =
|
int64_t total_packets_delta =
|
||||||
msg.packets_received_delta + msg.packets_lost_delta;
|
msg.packets_received_delta + msg.packets_lost_delta;
|
||||||
bandwidth_estimation_->UpdatePacketsLost(
|
bandwidth_estimation_->UpdatePacketsLost(
|
||||||
msg.packets_lost_delta, total_packets_delta, msg.receive_time.ms());
|
msg.packets_lost_delta, total_packets_delta, msg.receive_time);
|
||||||
return NetworkControlUpdate();
|
return NetworkControlUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,8 +367,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
|||||||
feedback_min_rtt = std::min(rtt, feedback_min_rtt);
|
feedback_min_rtt = std::min(rtt, feedback_min_rtt);
|
||||||
}
|
}
|
||||||
if (feedback_min_rtt.IsFinite()) {
|
if (feedback_min_rtt.IsFinite()) {
|
||||||
bandwidth_estimation_->UpdateRtt(feedback_min_rtt.ms(),
|
bandwidth_estimation_->UpdateRtt(feedback_min_rtt, report.feedback_time);
|
||||||
report.feedback_time.ms());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_packets_since_last_loss_update_ +=
|
expected_packets_since_last_loss_update_ +=
|
||||||
@ -378,7 +380,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
|||||||
next_loss_update_ = report.feedback_time + kLossUpdateInterval;
|
next_loss_update_ = report.feedback_time + kLossUpdateInterval;
|
||||||
bandwidth_estimation_->UpdatePacketsLost(
|
bandwidth_estimation_->UpdatePacketsLost(
|
||||||
lost_packets_since_last_loss_update_,
|
lost_packets_since_last_loss_update_,
|
||||||
expected_packets_since_last_loss_update_, report.feedback_time.ms());
|
expected_packets_since_last_loss_update_, report.feedback_time);
|
||||||
expected_packets_since_last_loss_update_ = 0;
|
expected_packets_since_last_loss_update_ = 0;
|
||||||
lost_packets_since_last_loss_update_ = 0;
|
lost_packets_since_last_loss_update_ = 0;
|
||||||
}
|
}
|
||||||
@ -407,12 +409,13 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
|||||||
NetworkControlUpdate update;
|
NetworkControlUpdate update;
|
||||||
if (result.updated) {
|
if (result.updated) {
|
||||||
if (result.probe) {
|
if (result.probe) {
|
||||||
bandwidth_estimation_->SetSendBitrate(result.target_bitrate_bps);
|
bandwidth_estimation_->SetSendBitrate(
|
||||||
|
DataRate::bps(result.target_bitrate_bps), 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(report.feedback_time.ms(),
|
bandwidth_estimation_->UpdateDelayBasedEstimate(
|
||||||
result.target_bitrate_bps);
|
report.feedback_time, DataRate::bps(result.target_bitrate_bps));
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
@ -91,9 +91,10 @@ class GoogCcNetworkControllerTest : public ::testing::Test {
|
|||||||
return packet_result;
|
return packet_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkRouteChange CreateRouteChange(DataRate start_rate = DataRate::Zero(),
|
NetworkRouteChange CreateRouteChange(
|
||||||
DataRate min_rate = DataRate::Zero(),
|
absl::optional<DataRate> start_rate = absl::nullopt,
|
||||||
DataRate max_rate = DataRate::Zero()) {
|
absl::optional<DataRate> min_rate = absl::nullopt,
|
||||||
|
absl::optional<DataRate> max_rate = absl::nullopt) {
|
||||||
NetworkRouteChange route_change;
|
NetworkRouteChange route_change;
|
||||||
route_change.at_time = current_time_;
|
route_change.at_time = current_time_;
|
||||||
route_change.constraints.at_time = current_time_;
|
route_change.constraints.at_time = current_time_;
|
||||||
|
@ -41,6 +41,7 @@ rtc_static_library("remote_bitrate_estimator") {
|
|||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
"../..:webrtc_common",
|
"../..:webrtc_common",
|
||||||
|
"../../api/units:data_rate",
|
||||||
"../../modules:module_api",
|
"../../modules:module_api",
|
||||||
"../../modules/rtp_rtcp:rtp_rtcp_format",
|
"../../modules/rtp_rtcp:rtp_rtcp_format",
|
||||||
"../../rtc_base:checks",
|
"../../rtc_base:checks",
|
||||||
|
@ -26,6 +26,10 @@ int GetMinBitrateBps() {
|
|||||||
return kMinBitrateBps;
|
return kMinBitrateBps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataRate GetMinBitrate() {
|
||||||
|
return DataRate::bps(GetMinBitrateBps());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace congestion_controller
|
} // namespace congestion_controller
|
||||||
|
|
||||||
RateControlInput::RateControlInput(
|
RateControlInput::RateControlInput(
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#define MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_BWE_DEFINES_H_
|
#define MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_BWE_DEFINES_H_
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
|
#include "api/units/data_rate.h"
|
||||||
|
|
||||||
#define BWE_MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define BWE_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#define BWE_MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define BWE_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
@ -20,6 +21,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
namespace congestion_controller {
|
namespace congestion_controller {
|
||||||
int GetMinBitrateBps();
|
int GetMinBitrateBps();
|
||||||
|
DataRate GetMinBitrate();
|
||||||
} // namespace congestion_controller
|
} // namespace congestion_controller
|
||||||
|
|
||||||
static const int64_t kBitrateWindowMs = 1000;
|
static const int64_t kBitrateWindowMs = 1000;
|
||||||
|
Reference in New Issue
Block a user