This source file includes following definitions.
- sorted_bitrate_estimates_
- OnAcknowledgedPacket
- GetChannelEstimate
- UpdateFilter
#include "net/quic/congestion_control/channel_estimator.h"
static const int kInterarrivalRatioThresholdForBandwidthEstimation = 5;
static const size_t kMinNumberOfSamples = 10;
static const size_t kMaxNumberOfSamples = 100;
namespace net {
ChannelEstimator::ChannelEstimator()
: last_sequence_number_(0),
last_send_time_(QuicTime::Zero()),
last_receive_time_(QuicTime::Zero()),
sorted_bitrate_estimates_(kMaxNumberOfSamples) {
}
ChannelEstimator::~ChannelEstimator() {
}
void ChannelEstimator::OnAcknowledgedPacket(
QuicPacketSequenceNumber sequence_number,
QuicByteCount packet_size,
QuicTime send_time,
QuicTime receive_time) {
if (last_sequence_number_ > sequence_number) {
return;
}
if (last_sequence_number_ != sequence_number - 1) {
DVLOG(1) << "Skip channel estimator due to lost packet(s)";
} else if (last_send_time_.IsInitialized()) {
QuicTime::Delta sent_delta = send_time.Subtract(last_send_time_);
QuicTime::Delta received_delta = receive_time.Subtract(last_receive_time_);
if (received_delta.ToMicroseconds() >
kInterarrivalRatioThresholdForBandwidthEstimation *
sent_delta.ToMicroseconds()) {
UpdateFilter(received_delta, packet_size, sequence_number);
}
}
last_sequence_number_ = sequence_number;
last_send_time_ = send_time;
last_receive_time_ = receive_time;
}
ChannelEstimateState ChannelEstimator::GetChannelEstimate(
QuicBandwidth* estimate) const {
if (sorted_bitrate_estimates_.Size() < kMinNumberOfSamples) {
return kChannelEstimateUnknown;
}
size_t beginning_window = sorted_bitrate_estimates_.Size() / 4;
size_t median = sorted_bitrate_estimates_.Size() / 2;
size_t end_window = sorted_bitrate_estimates_.Size() - beginning_window;
QuicBandwidth bitrate_25th_percentile = QuicBandwidth::Zero();
QuicBandwidth median_bitrate = QuicBandwidth::Zero();
QuicBandwidth bitrate_75th_percentile = QuicBandwidth::Zero();
QuicMaxSizedMap<QuicBandwidth, QuicPacketSequenceNumber>::ConstIterator it =
sorted_bitrate_estimates_.Begin();
for (size_t i = 0; i <= end_window; ++i, ++it) {
DCHECK(it != sorted_bitrate_estimates_.End());
if (i == beginning_window) {
bitrate_25th_percentile = it->first;
}
if (i == median) {
median_bitrate = it->first;
}
if (i == end_window) {
bitrate_75th_percentile = it->first;
}
}
*estimate = median_bitrate;
DVLOG(1) << "Channel estimate is:"
<< median_bitrate.ToKBitsPerSecond() << " Kbit/s";
if (bitrate_75th_percentile.Subtract(bitrate_25th_percentile) >
median_bitrate.Scale(0.25f)) {
return kChannelEstimateUncertain;
}
return kChannelEstimateGood;
}
void ChannelEstimator::UpdateFilter(QuicTime::Delta received_delta,
QuicByteCount size_delta,
QuicPacketSequenceNumber sequence_number) {
QuicBandwidth estimate =
QuicBandwidth::FromBytesAndTimeDelta(size_delta, received_delta);
sorted_bitrate_estimates_.Insert(estimate, sequence_number);
}
}