Skip to content

Commit

Permalink
Refax: moved buffer tools to a separate file (#2499)
Browse files Browse the repository at this point in the history
Co-authored-by: Mikołaj Małecki <mmalecki@haivision.com>
  • Loading branch information
ethouris and Mikołaj Małecki authored Oct 26, 2022
1 parent 8e9958a commit fda7441
Show file tree
Hide file tree
Showing 7 changed files with 354 additions and 176 deletions.
45 changes: 45 additions & 0 deletions srtcore/buffer_rcv.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
/*
* SRT - Secure, Reliable, Transport
* Copyright (c) 2018 Haivision Systems Inc.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/

/*****************************************************************************
Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the
above copyright notice, this list of conditions
and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the University of Illinois
nor the names of its contributors may be used to
endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/

#include <cmath>
#include <limits>
#include "buffer_rcv.h"
Expand Down
2 changes: 1 addition & 1 deletion srtcore/buffer_rcv.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#ifndef INC_SRT_BUFFER_RCV_H
#define INC_SRT_BUFFER_RCV_H

#include "buffer_snd.h" // AvgBufSize
#include "buffer_tools.h" // AvgBufSize
#include "common.h"
#include "queue.h"
#include "sync.h"
Expand Down
105 changes: 7 additions & 98 deletions srtcore/buffer_snd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ modified by

#include "platform_sys.h"

#include <cstring>
#include <cmath>
#include "buffer_snd.h"
#include "packet.h"
Expand All @@ -65,103 +64,6 @@ using namespace std;
using namespace srt_logging;
using namespace sync;

// You can change this value at build config by using "ENFORCE" options.
#if !defined(SRT_MAVG_SAMPLING_RATE)
#define SRT_MAVG_SAMPLING_RATE 40
#endif

bool AvgBufSize::isTimeToUpdate(const time_point& now) const
{
const int usMAvgBasePeriod = 1000000; // 1s in microseconds
const int us2ms = 1000;
const int msMAvgPeriod = (usMAvgBasePeriod / SRT_MAVG_SAMPLING_RATE) / us2ms;
const uint64_t elapsed_ms = count_milliseconds(now - m_tsLastSamplingTime); // ms since last sampling
return (elapsed_ms >= msMAvgPeriod);
}

void AvgBufSize::update(const steady_clock::time_point& now, int pkts, int bytes, int timespan_ms)
{
const uint64_t elapsed_ms = count_milliseconds(now - m_tsLastSamplingTime); // ms since last sampling
m_tsLastSamplingTime = now;
const uint64_t one_second_in_ms = 1000;
if (elapsed_ms > one_second_in_ms)
{
// No sampling in last 1 sec, initialize average
m_dCountMAvg = pkts;
m_dBytesCountMAvg = bytes;
m_dTimespanMAvg = timespan_ms;
return;
}

//
// weight last average value between -1 sec and last sampling time (LST)
// and new value between last sampling time and now
// |elapsed_ms|
// +----------------------------------+-------+
// -1 LST 0(now)
//
m_dCountMAvg = avg_iir_w<1000, double>(m_dCountMAvg, pkts, elapsed_ms);
m_dBytesCountMAvg = avg_iir_w<1000, double>(m_dBytesCountMAvg, bytes, elapsed_ms);
m_dTimespanMAvg = avg_iir_w<1000, double>(m_dTimespanMAvg, timespan_ms, elapsed_ms);
}

int round_val(double val)
{
return static_cast<int>(round(val));
}

CRateEstimator::CRateEstimator()
: m_iInRatePktsCount(0)
, m_iInRateBytesCount(0)
, m_InRatePeriod(INPUTRATE_FAST_START_US) // 0.5 sec (fast start)
, m_iInRateBps(INPUTRATE_INITIAL_BYTESPS)
{}

void CRateEstimator::setInputRateSmpPeriod(int period)
{
m_InRatePeriod = (uint64_t)period; //(usec) 0=no input rate calculation
}

void CRateEstimator::updateInputRate(const time_point& time, int pkts, int bytes)
{
// no input rate calculation
if (m_InRatePeriod == 0)
return;

if (is_zero(m_tsInRateStartTime))
{
m_tsInRateStartTime = time;
return;
}
else if (time < m_tsInRateStartTime)
{
// Old packets are being submitted for estimation, e.g. during the backup link activation.
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);

const uint64_t period_us = count_microseconds(time - m_tsInRateStartTime);
if (early_update || period_us > 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) / period_us);
HLOGC(bslog.Debug,
log << "updateInputRate: pkts:" << m_iInRateBytesCount << " bytes:" << m_iInRatePktsCount
<< " rate=" << (m_iInRateBps * 8) / 1000 << "kbps interval=" << period_us);
m_iInRatePktsCount = 0;
m_iInRateBytesCount = 0;
m_tsInRateStartTime = time;

setInputRateSmpPeriod(INPUTRATE_RUNNING_US);
}
}

CSndBuffer::CSndBuffer(int size, int maxpld, int authtag)
: m_BufLock()
, m_pBlock(NULL)
Expand Down Expand Up @@ -654,6 +556,13 @@ int CSndBuffer::getCurrBufSize() const
return m_iCount;
}

namespace {
int round_val(double val)
{
return static_cast<int>(round(val));
}
}

int CSndBuffer::getAvgBufSize(int& w_bytes, int& w_tsp)
{
ScopedLock bufferguard(m_BufLock); /* Consistency of pkts vs. bytes vs. spantime */
Expand Down
82 changes: 5 additions & 77 deletions srtcore/buffer_snd.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,12 @@ modified by
Haivision Systems Inc.
*****************************************************************************/

#ifndef INC_SRT_BUFFER_H
#define INC_SRT_BUFFER_H
#ifndef INC_SRT_BUFFER_SND_H
#define INC_SRT_BUFFER_SND_H

#include "udt.h"
#include "list.h"
#include "queue.h"
#include "tsbpd_time.h"
#include "utilities.h"
#include "srt.h"
#include "packet.h"
#include "buffer_tools.h"

// The notation used for "circular numbers" in comments:
// The "cicrular numbers" are numbers that when increased up to the
Expand All @@ -73,76 +71,6 @@ modified by

namespace srt {

/// The AvgBufSize class is used to calculate moving average of the buffer (RCV or SND)
class AvgBufSize
{
typedef sync::steady_clock::time_point time_point;

public:
AvgBufSize()
: m_dBytesCountMAvg(0.0)
, m_dCountMAvg(0.0)
, m_dTimespanMAvg(0.0)
{
}

public:
bool isTimeToUpdate(const time_point& now) const;
void update(const time_point& now, int pkts, int bytes, int timespan_ms);

public:
inline double pkts() const { return m_dCountMAvg; }
inline double timespan_ms() const { return m_dTimespanMAvg; }
inline double bytes() const { return m_dBytesCountMAvg; }

private:
time_point m_tsLastSamplingTime;
double m_dBytesCountMAvg;
double m_dCountMAvg;
double m_dTimespanMAvg;
};

/// The class to estimate source bitrate based on samples submitted to the buffer.
/// Is currently only used by the CSndBuffer.
class CRateEstimator
{
typedef sync::steady_clock::time_point time_point;
typedef sync::steady_clock::duration duration;
public:
CRateEstimator();

public:
uint64_t getInRatePeriod() const { return m_InRatePeriod; }

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

void setInputRateSmpPeriod(int period);

/// 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(const time_point& time, int pkts = 0, int bytes = 0);

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

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:
int m_iInRatePktsCount; // number of payload bytes added since InRateStartTime
int m_iInRateBytesCount; // number of payload bytes added since InRateStartTime
time_point m_tsInRateStartTime;
uint64_t m_InRatePeriod; // usec
int m_iInRateBps; // Input Rate in Bytes/sec
};

class CSndBuffer
{
typedef sync::steady_clock::time_point time_point;
Expand Down
Loading

0 comments on commit fda7441

Please sign in to comment.