This source file includes following definitions.
- last_delay_event_
- GetInterArrivalState
- IncreaseBitrateDecision
- DecreaseBitrateDecision
- set_rtt
- PacketLossEvent
- IncreasingDelayEvent
#include "net/quic/congestion_control/inter_arrival_state_machine.h"
#include "base/logging.h"
namespace {
const int kIncreaseEventsBeforeDowngradingState = 5;
const int kDecreaseEventsBeforeUpgradingState = 2;
const int kLossEventsBeforeUpgradingState = 2;
const int kEventTimeoutMs = 10000;
const int kInitialRttMs = 80;
}
namespace net {
InterArrivalStateMachine::InterArrivalStateMachine(const QuicClock* clock)
: clock_(clock),
current_state_(kInterArrivalStateStable),
smoothed_rtt_(QuicTime::Delta::FromMilliseconds(kInitialRttMs)),
decrease_event_count_(0),
last_decrease_event_(QuicTime::Zero()),
increase_event_count_(0),
last_increase_event_(QuicTime::Zero()),
loss_event_count_(0),
last_loss_event_(QuicTime::Zero()),
delay_event_count_(0),
last_delay_event_(QuicTime::Zero()) {
}
InterArrivalState InterArrivalStateMachine::GetInterArrivalState() {
return current_state_;
}
void InterArrivalStateMachine::IncreaseBitrateDecision() {
QuicTime current_time = clock_->ApproximateNow();
if (current_time.Subtract(last_increase_event_) < smoothed_rtt_) {
return;
}
last_increase_event_ = current_time;
increase_event_count_++;
decrease_event_count_ = 0;
if (increase_event_count_ < kIncreaseEventsBeforeDowngradingState) {
return;
}
increase_event_count_ = 0;
switch (current_state_) {
case kInterArrivalStateStable:
break;
case kInterArrivalStatePacketLoss:
current_state_ = kInterArrivalStateStable;
break;
case kInterArrivalStateDelay:
current_state_ = kInterArrivalStateStable;
break;
case kInterArrivalStateCompetingFlow:
current_state_ = kInterArrivalStateDelay;
break;
case kInterArrivalStateCompetingTcpFLow:
current_state_ = kInterArrivalStateDelay;
break;
}
}
void InterArrivalStateMachine::DecreaseBitrateDecision() {
DCHECK(kDecreaseEventsBeforeUpgradingState >=
kLossEventsBeforeUpgradingState);
QuicTime current_time = clock_->ApproximateNow();
if (current_time.Subtract(last_decrease_event_) < smoothed_rtt_) {
return;
}
last_decrease_event_ = current_time;
decrease_event_count_++;
increase_event_count_ = 0;
if (decrease_event_count_ < kDecreaseEventsBeforeUpgradingState) {
return;
}
decrease_event_count_ = 0;
switch (current_state_) {
case kInterArrivalStateStable:
if (delay_event_count_ == 0 && loss_event_count_ > 0) {
current_state_ = kInterArrivalStatePacketLoss;
} else {
current_state_ = kInterArrivalStateDelay;
}
break;
case kInterArrivalStatePacketLoss:
break;
case kInterArrivalStateDelay:
if (loss_event_count_ >= kLossEventsBeforeUpgradingState) {
current_state_ = kInterArrivalStateCompetingTcpFLow;
} else {
current_state_ = kInterArrivalStateCompetingFlow;
}
break;
case kInterArrivalStateCompetingFlow:
if (loss_event_count_ >= kLossEventsBeforeUpgradingState) {
current_state_ = kInterArrivalStateCompetingTcpFLow;
}
break;
case kInterArrivalStateCompetingTcpFLow:
break;
}
}
void InterArrivalStateMachine::set_rtt(QuicTime::Delta rtt) {
smoothed_rtt_ = rtt;
}
bool InterArrivalStateMachine::PacketLossEvent() {
QuicTime current_time = clock_->ApproximateNow();
if (current_time.Subtract(last_loss_event_) < smoothed_rtt_) {
return false;
}
last_loss_event_ = current_time;
loss_event_count_++;
if (current_time.Subtract(last_delay_event_) >
QuicTime::Delta::FromMilliseconds(kEventTimeoutMs)) {
delay_event_count_ = 0;
}
return true;
}
bool InterArrivalStateMachine::IncreasingDelayEvent() {
QuicTime current_time = clock_->ApproximateNow();
if (current_time.Subtract(last_delay_event_) < smoothed_rtt_) {
return false;
}
last_delay_event_ = current_time;
delay_event_count_++;
if (current_time.Subtract(last_loss_event_) >
QuicTime::Delta::FromMilliseconds(kEventTimeoutMs)) {
loss_event_count_ = 0;
}
return true;
}
}