Skip to content

Commit

Permalink
[core] Improved input rate calculation.
Browse files Browse the repository at this point in the history
SRTO_MAXBW=0; SRTO_INPUTBW=0;
  • Loading branch information
maxsharabayko committed Jul 18, 2019
1 parent 9e34fe5 commit 274d72a
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 83 deletions.
113 changes: 53 additions & 60 deletions srtcore/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,30 +60,30 @@ modified by
using namespace std;
using namespace srt_logging;

CSndBuffer::CSndBuffer(int size, int mss):
m_BufLock(),
m_pBlock(NULL),
m_pFirstBlock(NULL),
m_pCurrBlock(NULL),
m_pLastBlock(NULL),
m_pBuffer(NULL),
m_iNextMsgNo(1),
m_iSize(size),
m_iMSS(mss),
m_iCount(0)
,m_iBytesCount(0)
,m_ullLastOriginTime_us(0)
CSndBuffer::CSndBuffer(int size, int mss)
: m_BufLock()
, m_pBlock(NULL)
, m_pFirstBlock(NULL)
, m_pCurrBlock(NULL)
, m_pLastBlock(NULL)
, m_pBuffer(NULL)
, m_iNextMsgNo(1)
, m_iSize(size)
, m_iMSS(mss)
, m_iCount(0)
, m_iBytesCount(0)
, m_ullLastOriginTime_us(0)
#ifdef SRT_ENABLE_SNDBUFSZ_MAVG
,m_LastSamplingTime(0)
,m_iCountMAvg(0)
,m_iBytesCountMAvg(0)
,m_TimespanMAvg(0)
, m_LastSamplingTime(0)
, m_iCountMAvg(0)
, m_iBytesCountMAvg(0)
, m_TimespanMAvg(0)
#endif
,m_iInRatePktsCount(0)
,m_iInRateBytesCount(0)
,m_InRateStartTime(0)
,m_InRatePeriod(CUDT::SND_INPUTRATE_FAST_START_US) // 0.5 sec (fast start)
,m_iInRateBps(CUDT::SND_INPUTRATE_INITIAL_BPS)
, m_iInRatePktsCount(0)
, m_iInRateBytesCount(0)
, m_InRateStartTime(0)
, m_InRatePeriod(INPUTRATE_FAST_START_US) // 0.5 sec (fast start)
, m_iInRateBps(INPUTRATE_INITIAL_BYTESPS)
{
// initial physical buffer of "size"
m_pBuffer = new Buffer;
Expand Down Expand Up @@ -155,7 +155,7 @@ void CSndBuffer::addBuffer(const char* data, int len, int ttl, bool order, uint6
increase();
}

uint64_t time = CTimer::getTime();
const uint64_t time = CTimer::getTime();
int32_t inorder = order ? MSGNO_PACKET_INORDER::mask : 0;

HLOGC(dlog.Debug, log << CONID() << "addBuffer: adding "
Expand Down Expand Up @@ -202,7 +202,7 @@ void CSndBuffer::addBuffer(const char* data, int len, int ttl, bool order, uint6
m_iBytesCount += len;
m_ullLastOriginTime_us = time;

updInputRate(time, size, len);
updateInputRate(time, size, len);

#ifdef SRT_ENABLE_SNDBUFSZ_MAVG
updAvgBufSize(time);
Expand All @@ -224,54 +224,47 @@ void CSndBuffer::addBuffer(const char* data, int len, int ttl, bool order, uint6

void CSndBuffer::setInputRateSmpPeriod(int period)
{
m_InRatePeriod = (uint64_t)period; //(usec) 0=no input rate calculation
LOGC(dlog.Error, log << "setInputRateSmpPeriod: " << period << " us");
m_InRatePeriod = (uint64_t)period; //(usec) 0=no input rate calculation
}

void CSndBuffer::updInputRate(uint64_t time, int pkts, int bytes)
void CSndBuffer::updateInputRate(uint64_t time, int pkts, int bytes)
{
if (m_InRatePeriod == 0)
;//no input rate calculation
else if (m_InRateStartTime == 0)
m_InRateStartTime = time;
else
{
m_iInRatePktsCount += pkts;
m_iInRateBytesCount += bytes;
if ((time - m_InRateStartTime) > m_InRatePeriod) {
//Required Byte/sec rate (payload + headers)
m_iInRateBytesCount += (m_iInRatePktsCount * CPacket::SRT_DATA_HDR_SIZE);
m_iInRateBps = (int)(((int64_t)m_iInRateBytesCount * 1000000) / (time - m_InRateStartTime));
HLOGC(dlog.Debug, log << "updInputRate: pkts:" << m_iInRateBytesCount << " bytes:" << m_iInRatePktsCount
<< " rate=" << (m_iInRateBps*8)/1000
<< "kbps interval=" << (time - m_InRateStartTime));
m_iInRatePktsCount = 0;
m_iInRateBytesCount = 0;
m_InRateStartTime = time;
}
}
}
//no input rate calculation
if (m_InRatePeriod == 0)
return;

int CSndBuffer::getInputRate(ref_t<uint64_t> r_period)
{
uint64_t& period = *r_period;
uint64_t time = CTimer::getTime();
if (m_InRateStartTime == 0)
{
m_InRateStartTime = time;
return;
}

m_iInRatePktsCount += pkts;
m_iInRateBytesCount += bytes;

// Trigger early update in fast start mode
const bool early_update = (m_InRatePeriod < INPUTRATE_RUNNING_US)
&& (m_iInRatePktsCount > INPUTRATE_MAX_PACKETS);

if ((m_InRatePeriod != 0)
&& (m_InRateStartTime != 0)
&& ((time - m_InRateStartTime) > m_InRatePeriod))
const uint64_t period_us = (time - m_InRateStartTime);
if (early_update || period_us > m_InRatePeriod)
{
//include packet headers: SRT + UDP + IP
int64_t llBytesCount = (int64_t)m_iInRateBytesCount + (m_iInRatePktsCount * (CPacket::HDR_SIZE + CPacket::UDP_HDR_SIZE));
//Byte/sec rate
m_iInRateBps = (int)((llBytesCount * 1000000) / (time - m_InRateStartTime));
//Required Byte/sec rate (payload + headers)
m_iInRateBytesCount += (m_iInRatePktsCount * CPacket::SRT_DATA_HDR_SIZE);
m_iInRateBps = (int)(((int64_t)m_iInRateBytesCount * 1000000) / period_us);
LOGC(dlog.Error, log << "updateInputRate: pkts:" << m_iInRateBytesCount << " bytes:" << m_iInRatePktsCount
<< " rate=" << (m_iInRateBps*8)/1000
<< "kbps interval=" << period_us);
m_iInRatePktsCount = 0;
m_iInRateBytesCount = 0;
m_InRateStartTime = time;

setInputRateSmpPeriod(INPUTRATE_RUNNING_US);
}
period = m_InRatePeriod;
return(m_iInRateBps);
}


int CSndBuffer::addBufferFromFile(fstream& ifs, int len)
{
int size = len / m_iMSS;
Expand Down
31 changes: 28 additions & 3 deletions srtcore/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,37 @@ class CSndBuffer
#endif /* SRT_ENABLE_SNDBUFSZ_MAVG */
int getCurrBufSize(ref_t<int> bytes, ref_t<int> timespan);

int getInputRate(ref_t<uint64_t> period);
void updInputRate(uint64_t time, int pkts, int bytes);
void setInputRateSmpPeriod(int period);
uint64_t getInRatePeriod() const { return m_InRatePeriod; }

/// Retrieve input bitrate in bytes per second
int getInputRate() const { return m_iInRateBps; }

/// Update input rate calculation.
/// @param [in] time current time in microseconds
/// @param [in] pkts number of packets newly added to the buffer
/// @param [in] bytes number of payload bytes in those newly added packets
///
/// @return Current size of the data in the sending list.
void updateInputRate(uint64_t time, int pkts = 0, int bytes = 0);


void resetInputRateSmpPeriod(bool disable = false)
{
setInputRateSmpPeriod(disable ? 0 : INPUTRATE_FAST_START_US);
}


private:

void increase();
void setInputRateSmpPeriod(int period);

private: // Constants

static const uint64_t INPUTRATE_FAST_START_US = 500000; // 500 ms
static const uint64_t INPUTRATE_RUNNING_US = 1000000; // 1000 ms
static const int64_t INPUTRATE_MAX_PACKETS = 2000; // ~ 21 Mbps of 1316 bytes payload
static const int INPUTRATE_INITIAL_BYTESPS = BW_INFINITE;

private:
pthread_mutex_t m_BufLock; // used to synchronize buffer operation
Expand Down
3 changes: 2 additions & 1 deletion srtcore/congctl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ class LiveCC: public SrtCongestionControlBase
// packet = payload + header
const double pktsize = (double) m_zSndAvgPayloadSize + CPacket::SRT_DATA_HDR_SIZE;
m_dPktSndPeriod = 1000 * 1000.0 * (pktsize / m_llSndMaxBW);
HLOGC(mglog.Debug, log << "LiveCC: sending period updated: " << m_zSndAvgPayloadSize);
LOGC(mglog.Error, log << "LiveCC: sending period updated: " << m_dPktSndPeriod
<< " (pktsize=" << pktsize << ", bw=" << m_llSndMaxBW);
}

void setMaxBW(int64_t maxbw)
Expand Down
19 changes: 6 additions & 13 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6250,7 +6250,9 @@ void CUDT::updateCC(ETransmissionEvent evt, EventVariant arg)
}
else
{
m_pSndBuffer->setInputRateSmpPeriod(bw == 0 ? SND_INPUTRATE_FAST_START_US: 0);
// No need to calculate input reate if the bandwidth is set
const bool disable_in_rate_calc = (bw != 0);
m_pSndBuffer->resetInputRateSmpPeriod(disable_in_rate_calc);
}

HLOGC(mglog.Debug, log << "updateCC/TEV_INIT: updating BW=" << m_llMaxBW
Expand All @@ -6267,13 +6269,9 @@ void CUDT::updateCC(ETransmissionEvent evt, EventVariant arg)
// This requests internal input rate sampling.
if (m_llMaxBW == 0 && m_llInputBW == 0)
{
uint64_t period;
int64_t inputbw = m_pSndBuffer->getInputRate(Ref(period)); //Auto input rate

// NOTE:
// 'period' here is set to the value that was previously set by
// m_pSndBuffer->setInputRateSmpPeriod().

// Get auto-calculated input rate, Bytes per second
const int64_t inputbw = m_pSndBuffer->getInputRate();
LOGC(mglog.Error, log << "udpateCC: inputbw:" << inputbw);
/*
* On blocked transmitter (tx full) and until connection closes,
* auto input rate falls to 0 but there may be still lot of packet to retransmit
Expand All @@ -6283,11 +6281,6 @@ void CUDT::updateCC(ETransmissionEvent evt, EventVariant arg)
*/
if (inputbw != 0)
m_CongCtl->updateBandwidth(0, withOverhead(inputbw)); //Bytes/sec

CGuard::enterCS(m_StatsLock);
if ((m_stats.sentTotal > SND_INPUTRATE_MAX_PACKETS) && (period < SND_INPUTRATE_RUNNING_US))
m_pSndBuffer->setInputRateSmpPeriod(SND_INPUTRATE_RUNNING_US); //1 sec period after fast start
CGuard::leaveCS(m_StatsLock);
}
}

Expand Down
8 changes: 2 additions & 6 deletions srtcore/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,8 @@ class CUDT
static const uint64_t COMM_KEEPALIVE_PERIOD_US = 1*1000*1000;
static const int32_t COMM_SYN_INTERVAL_US = 10*1000;

// Input rate constants
static const uint64_t
SND_INPUTRATE_FAST_START_US = 500*1000,
SND_INPUTRATE_RUNNING_US = 1*1000*1000;
static const int64_t SND_INPUTRATE_MAX_PACKETS = 2000;
static const int SND_INPUTRATE_INITIAL_BPS = 10000000/8; // 10 Mbps (1.25 MBps)
//
static const int SND_INPUTRATE_INITIAL_BPS = BW_INFINITE * 8;

int handshakeVersion()
{
Expand Down

0 comments on commit 274d72a

Please sign in to comment.