1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-12-12 17:17:24 +01:00
libtgvoip/CongestionControl.cpp

143 lines
3.3 KiB
C++
Raw Normal View History

2017-02-02 17:24:40 +01:00
//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//
#include "CongestionControl.h"
#include "VoIPController.h"
#include "logging.h"
2017-03-30 16:06:59 +02:00
#include "VoIPServerConfig.h"
2018-06-04 21:37:43 +02:00
#include "PrivateDefines.h"
2017-02-02 17:24:40 +01:00
#include <math.h>
#include <assert.h>
using namespace tgvoip;
CongestionControl::CongestionControl(){
memset(inflightPackets, 0, sizeof(inflightPackets));
2017-02-02 17:24:40 +01:00
tmpRtt=0;
tmpRttCount=0;
lastSentSeq=0;
lastActionTime=0;
lastActionRtt=0;
stateTransitionTime=0;
inflightDataSize=0;
lossCount=0;
cwnd=(size_t) ServerConfig::GetSharedInstance()->GetInt("audio_congestion_window", 1024);
2017-02-02 17:24:40 +01:00
}
CongestionControl::~CongestionControl(){
2017-02-02 17:24:40 +01:00
}
size_t CongestionControl::GetAcknowledgedDataSize(){
2017-02-02 17:24:40 +01:00
return 0;
}
double CongestionControl::GetAverageRTT(){
return rttHistory.NonZeroAverage();
2017-02-02 17:24:40 +01:00
}
size_t CongestionControl::GetInflightDataSize(){
return inflightHistory.Average();
2017-02-02 17:24:40 +01:00
}
size_t CongestionControl::GetCongestionWindow(){
2017-02-02 17:24:40 +01:00
return cwnd;
}
double CongestionControl::GetMinimumRTT(){
return rttHistory.Min();
2017-02-02 17:24:40 +01:00
}
void CongestionControl::PacketAcknowledged(uint32_t seq){
MutexGuard sync(mutex);
2017-02-02 17:24:40 +01:00
int i;
for(i=0;i<100;i++){
if(inflightPackets[i].seq==seq && inflightPackets[i].sendTime>0){
tmpRtt+=(VoIPController::GetCurrentTime()-inflightPackets[i].sendTime);
2017-02-02 17:24:40 +01:00
tmpRttCount++;
inflightPackets[i].sendTime=0;
inflightDataSize-=inflightPackets[i].size;
break;
}
}
}
void CongestionControl::PacketSent(uint32_t seq, size_t size){
2017-02-02 17:24:40 +01:00
if(!seqgt(seq, lastSentSeq) || seq==lastSentSeq){
LOGW("Duplicate outgoing seq %u", seq);
return;
}
lastSentSeq=seq;
MutexGuard sync(mutex);
2017-02-02 17:24:40 +01:00
double smallestSendTime=INFINITY;
tgvoip_congestionctl_packet_t* slot=NULL;
int i;
for(i=0;i<100;i++){
if(inflightPackets[i].sendTime==0){
slot=&inflightPackets[i];
break;
}
if(smallestSendTime>inflightPackets[i].sendTime){
slot=&inflightPackets[i];
smallestSendTime=slot->sendTime;
}
}
assert(slot!=NULL);
if(slot->sendTime>0){
inflightDataSize-=slot->size;
lossCount++;
LOGD("Packet with seq %u was not acknowledged", slot->seq);
}
slot->seq=seq;
slot->size=size;
slot->sendTime=VoIPController::GetCurrentTime();
2017-02-02 17:24:40 +01:00
inflightDataSize+=size;
}
void CongestionControl::Tick(){
2017-02-02 17:24:40 +01:00
tickCount++;
MutexGuard sync(mutex);
2017-02-02 17:24:40 +01:00
if(tmpRttCount>0){
rttHistory.Add(tmpRtt/tmpRttCount);
2017-02-02 17:24:40 +01:00
tmpRtt=0;
tmpRttCount=0;
}
int i;
for(i=0;i<100;i++){
if(inflightPackets[i].sendTime!=0 && VoIPController::GetCurrentTime()-inflightPackets[i].sendTime>2){
2017-02-02 17:24:40 +01:00
inflightPackets[i].sendTime=0;
inflightDataSize-=inflightPackets[i].size;
lossCount++;
LOGD("Packet with seq %u was not acknowledged", inflightPackets[i].seq);
}
}
inflightHistory.Add(inflightDataSize);
2017-02-02 17:24:40 +01:00
}
int CongestionControl::GetBandwidthControlAction(){
if(VoIPController::GetCurrentTime()-lastActionTime<1)
2017-02-02 17:24:40 +01:00
return TGVOIP_CONCTL_ACT_NONE;
size_t inflightAvg=GetInflightDataSize();
size_t max=cwnd+cwnd/10;
size_t min=cwnd-cwnd/10;
if(inflightAvg<min){
lastActionTime=VoIPController::GetCurrentTime();
2017-02-02 17:24:40 +01:00
return TGVOIP_CONCTL_ACT_INCREASE;
}
if(inflightAvg>max){
lastActionTime=VoIPController::GetCurrentTime();
2017-02-02 17:24:40 +01:00
return TGVOIP_CONCTL_ACT_DECREASE;
}
return TGVOIP_CONCTL_ACT_NONE;
}
uint32_t CongestionControl::GetSendLossCount(){
2017-02-02 17:24:40 +01:00
return lossCount;
}