mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
SRT: Upgrade libsrt from 1.4.1 to 1.5.1. v6.0.12 (#3362)
Co-authored-by: winlin <winlin@vip.126.com>
This commit is contained in:
parent
7a56208f2f
commit
fe086dfc31
143 changed files with 38185 additions and 15108 deletions
867
trunk/3rdparty/srt-1-fit/srtcore/buffer.h
vendored
867
trunk/3rdparty/srt-1-fit/srtcore/buffer.h
vendored
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* 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/.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -50,461 +50,562 @@ modified by
|
|||
Haivision Systems Inc.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_BUFFER_H__
|
||||
#define __UDT_BUFFER_H__
|
||||
|
||||
#ifndef INC_SRT_BUFFER_H
|
||||
#define INC_SRT_BUFFER_H
|
||||
|
||||
#include "udt.h"
|
||||
#include "list.h"
|
||||
#include "queue.h"
|
||||
#include "tsbpd_time.h"
|
||||
#include "utilities.h"
|
||||
#include <fstream>
|
||||
|
||||
class CSndBuffer
|
||||
// The notation used for "circular numbers" in comments:
|
||||
// The "cicrular numbers" are numbers that when increased up to the
|
||||
// maximum become zero, and similarly, when the zero value is decreased,
|
||||
// it turns into the maximum value minus one. This wrapping works the
|
||||
// same for adding and subtracting. Circular numbers cannot be multiplied.
|
||||
|
||||
// Operations done on these numbers are marked with additional % character:
|
||||
// a %> b : a is later than b
|
||||
// a ++% (++%a) : shift a by 1 forward
|
||||
// a +% b : shift a by b
|
||||
// a == b : equality is same as for just numbers
|
||||
|
||||
namespace srt {
|
||||
|
||||
/// The AvgBufSize class is used to calculate moving average of the buffer (RCV or SND)
|
||||
class AvgBufSize
|
||||
{
|
||||
public:
|
||||
|
||||
// XXX There's currently no way to access the socket ID set for
|
||||
// whatever the buffer is currently working for. Required to find
|
||||
// some way to do this, possibly by having a "reverse pointer".
|
||||
// Currently just "unimplemented".
|
||||
std::string CONID() const { return ""; }
|
||||
|
||||
CSndBuffer(int size = 32, int mss = 1500);
|
||||
~CSndBuffer();
|
||||
typedef sync::steady_clock::time_point time_point;
|
||||
|
||||
public:
|
||||
AvgBufSize()
|
||||
: m_dBytesCountMAvg(0.0)
|
||||
, m_dCountMAvg(0.0)
|
||||
, m_dTimespanMAvg(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Insert a user buffer into the sending list.
|
||||
/// @param [in] data pointer to the user data block.
|
||||
/// @param [in] len size of the block.
|
||||
/// @param [in] ttl time to live in milliseconds
|
||||
/// @param [in] order if the block should be delivered in order, for DGRAM only
|
||||
|
||||
void addBuffer(const char* data, int len, int ttl, bool order, uint64_t srctime, ref_t<int32_t> r_msgno);
|
||||
|
||||
/// Read a block of data from file and insert it into the sending list.
|
||||
/// @param [in] ifs input file stream.
|
||||
/// @param [in] len size of the block.
|
||||
/// @return actual size of data added from the file.
|
||||
|
||||
int addBufferFromFile(std::fstream& ifs, int len);
|
||||
|
||||
/// Find data position to pack a DATA packet from the furthest reading point.
|
||||
/// @param [out] data the pointer to the data position.
|
||||
/// @param [out] msgno message number of the packet.
|
||||
/// @param [out] origintime origin time stamp of the message
|
||||
/// @param [in] kflags Odd|Even crypto key flag
|
||||
/// @return Actual length of data read.
|
||||
|
||||
int readData(char** data, int32_t& msgno, uint64_t& origintime, int kflgs);
|
||||
|
||||
|
||||
/// Find data position to pack a DATA packet for a retransmission.
|
||||
/// @param [out] data the pointer to the data position.
|
||||
/// @param [in] offset offset from the last ACK point.
|
||||
/// @param [out] msgno message number of the packet.
|
||||
/// @param [out] origintime origin time stamp of the message
|
||||
/// @param [out] msglen length of the message
|
||||
/// @return Actual length of data read.
|
||||
|
||||
int readData(char** data, const int offset, int32_t& msgno, uint64_t& origintime, int& msglen);
|
||||
|
||||
/// Update the ACK point and may release/unmap/return the user data according to the flag.
|
||||
/// @param [in] offset number of packets acknowledged.
|
||||
|
||||
void ackData(int offset);
|
||||
|
||||
/// Read size of data still in the sending list.
|
||||
/// @return Current size of the data in the sending list.
|
||||
|
||||
int getCurrBufSize() const;
|
||||
|
||||
int dropLateData(int &bytes, uint64_t latetime);
|
||||
|
||||
#ifdef SRT_ENABLE_SNDBUFSZ_MAVG
|
||||
void updAvgBufSize(uint64_t time);
|
||||
int getAvgBufSize(ref_t<int> bytes, ref_t<int> timespan);
|
||||
#endif /* SRT_ENABLE_SNDBUFSZ_MAVG */
|
||||
int getCurrBufSize(ref_t<int> bytes, ref_t<int> timespan);
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
||||
void increase();
|
||||
void setInputRateSmpPeriod(int period);
|
||||
/// 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();
|
||||
|
||||
private: // Constants
|
||||
public:
|
||||
uint64_t getInRatePeriod() const { return m_InRatePeriod; }
|
||||
|
||||
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
|
||||
/// 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:
|
||||
pthread_mutex_t m_BufLock; // used to synchronize buffer operation
|
||||
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
|
||||
};
|
||||
|
||||
struct Block
|
||||
{
|
||||
char* m_pcData; // pointer to the data block
|
||||
int m_iLength; // length of the block
|
||||
class CSndBuffer
|
||||
{
|
||||
typedef sync::steady_clock::time_point time_point;
|
||||
typedef sync::steady_clock::duration duration;
|
||||
|
||||
int32_t m_iMsgNoBitset; // message number
|
||||
uint64_t m_ullOriginTime_us; // original request time
|
||||
uint64_t m_ullSourceTime_us;
|
||||
int m_iTTL; // time to live (milliseconds)
|
||||
public:
|
||||
// XXX There's currently no way to access the socket ID set for
|
||||
// whatever the buffer is currently working for. Required to find
|
||||
// some way to do this, possibly by having a "reverse pointer".
|
||||
// Currently just "unimplemented".
|
||||
std::string CONID() const { return ""; }
|
||||
|
||||
Block* m_pNext; // next block
|
||||
/// @brief CSndBuffer constructor.
|
||||
/// @param size initial number of blocks (each block to store one packet payload).
|
||||
/// @param maxpld maximum packet payload.
|
||||
CSndBuffer(int size = 32, int maxpld = 1500);
|
||||
~CSndBuffer();
|
||||
|
||||
int32_t getMsgSeq()
|
||||
{
|
||||
// NOTE: this extracts message ID with regard to REXMIT flag.
|
||||
// This is valid only for message ID that IS GENERATED in this instance,
|
||||
// not provided by the peer. This can be otherwise sent to the peer - it doesn't matter
|
||||
// for the peer that it uses LESS bits to represent the message.
|
||||
return m_iMsgNoBitset & MSGNO_SEQ::mask;
|
||||
}
|
||||
public:
|
||||
/// Insert a user buffer into the sending list.
|
||||
/// For @a w_mctrl the following fields are used:
|
||||
/// INPUT:
|
||||
/// - msgttl: timeout for retransmitting the message, if lost
|
||||
/// - inorder: request to deliver the message in order of sending
|
||||
/// - srctime: local time as a base for packet's timestamp (0 if unused)
|
||||
/// - pktseq: sequence number to be stamped on the packet (-1 if unused)
|
||||
/// - msgno: message number to be stamped on the packet (-1 if unused)
|
||||
/// OUTPUT:
|
||||
/// - srctime: local time stamped on the packet (same as input, if input wasn't 0)
|
||||
/// - pktseq: sequence number to be stamped on the next packet
|
||||
/// - msgno: message number stamped on the packet
|
||||
/// @param [in] data pointer to the user data block.
|
||||
/// @param [in] len size of the block.
|
||||
/// @param [inout] w_mctrl Message control data
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
void addBuffer(const char* data, int len, SRT_MSGCTRL& w_mctrl);
|
||||
|
||||
} *m_pBlock, *m_pFirstBlock, *m_pCurrBlock, *m_pLastBlock;
|
||||
/// Read a block of data from file and insert it into the sending list.
|
||||
/// @param [in] ifs input file stream.
|
||||
/// @param [in] len size of the block.
|
||||
/// @return actual size of data added from the file.
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
int addBufferFromFile(std::fstream& ifs, int len);
|
||||
|
||||
// m_pBlock: The head pointer
|
||||
// m_pFirstBlock: The first block
|
||||
// m_pCurrBlock: The current block
|
||||
// m_pLastBlock: The last block (if first == last, buffer is empty)
|
||||
/// Find data position to pack a DATA packet from the furthest reading point.
|
||||
/// @param [out] packet the packet to read.
|
||||
/// @param [out] origintime origin time stamp of the message
|
||||
/// @param [in] kflags Odd|Even crypto key flag
|
||||
/// @param [out] seqnoinc the number of packets skipped due to TTL, so that seqno should be incremented.
|
||||
/// @return Actual length of data read.
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
int readData(CPacket& w_packet, time_point& w_origintime, int kflgs, int& w_seqnoinc);
|
||||
|
||||
struct Buffer
|
||||
{
|
||||
char* m_pcData; // buffer
|
||||
int m_iSize; // size
|
||||
Buffer* m_pNext; // next buffer
|
||||
} *m_pBuffer; // physical buffer
|
||||
/// Peek an information on the next original data packet to send.
|
||||
/// @return origin time stamp of the next packet; epoch start time otherwise.
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
time_point peekNextOriginal() const;
|
||||
|
||||
int32_t m_iNextMsgNo; // next message number
|
||||
/// Find data position to pack a DATA packet for a retransmission.
|
||||
/// @param [in] offset offset from the last ACK point (backward sequence number difference)
|
||||
/// @param [out] packet the packet to read.
|
||||
/// @param [out] origintime origin time stamp of the message
|
||||
/// @param [out] msglen length of the message
|
||||
/// @return Actual length of data read (return 0 if offset too large, -1 if TTL exceeded).
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
int readData(const int offset, CPacket& w_packet, time_point& w_origintime, int& w_msglen);
|
||||
|
||||
int m_iSize; // buffer size (number of packets)
|
||||
int m_iMSS; // maximum seqment/packet size
|
||||
/// Get the time of the last retransmission (if any) of the DATA packet.
|
||||
/// @param [in] offset offset from the last ACK point (backward sequence number difference)
|
||||
///
|
||||
/// @return Last time of the last retransmission event for the corresponding DATA packet.
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
time_point getPacketRexmitTime(const int offset);
|
||||
|
||||
int m_iCount; // number of used blocks
|
||||
/// Update the ACK point and may release/unmap/return the user data according to the flag.
|
||||
/// @param [in] offset number of packets acknowledged.
|
||||
int32_t getMsgNoAt(const int offset);
|
||||
|
||||
int m_iBytesCount; // number of payload bytes in queue
|
||||
uint64_t m_ullLastOriginTime_us;
|
||||
void ackData(int offset);
|
||||
|
||||
#ifdef SRT_ENABLE_SNDBUFSZ_MAVG
|
||||
uint64_t m_LastSamplingTime;
|
||||
int m_iCountMAvg;
|
||||
int m_iBytesCountMAvg;
|
||||
int m_TimespanMAvg;
|
||||
#endif /* SRT_ENABLE_SNDBUFSZ_MAVG */
|
||||
/// Read size of data still in the sending list.
|
||||
/// @return Current size of the data in the sending list.
|
||||
int getCurrBufSize() const;
|
||||
|
||||
int m_iInRatePktsCount; // number of payload bytes added since InRateStartTime
|
||||
int m_iInRateBytesCount; // number of payload bytes added since InRateStartTime
|
||||
uint64_t m_InRateStartTime;
|
||||
uint64_t m_InRatePeriod; // usec
|
||||
int m_iInRateBps; // Input Rate in Bytes/sec
|
||||
int m_iAvgPayloadSz; // Average packet payload size
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
int dropLateData(int& bytes, int32_t& w_first_msgno, const time_point& too_late_time);
|
||||
|
||||
void updAvgBufSize(const time_point& time);
|
||||
int getAvgBufSize(int& bytes, int& timespan);
|
||||
int getCurrBufSize(int& bytes, int& timespan);
|
||||
|
||||
/// @brief Get the buffering delay of the oldest message in the buffer.
|
||||
/// @return the delay value.
|
||||
SRT_ATTR_EXCLUDES(m_BufLock)
|
||||
duration getBufferingDelay(const time_point& tnow) const;
|
||||
|
||||
uint64_t getInRatePeriod() const { return m_rateEstimator.getInRatePeriod(); }
|
||||
|
||||
/// Retrieve input bitrate in bytes per second
|
||||
int getInputRate() const { return m_rateEstimator.getInputRate(); }
|
||||
|
||||
void resetInputRateSmpPeriod(bool disable = false) { m_rateEstimator.resetInputRateSmpPeriod(disable); }
|
||||
|
||||
const CRateEstimator& getRateEstimator() const { return m_rateEstimator; }
|
||||
|
||||
void setRateEstimator(const CRateEstimator& other) { m_rateEstimator = other; }
|
||||
|
||||
private:
|
||||
CSndBuffer(const CSndBuffer&);
|
||||
CSndBuffer& operator=(const CSndBuffer&);
|
||||
void increase();
|
||||
|
||||
private:
|
||||
mutable sync::Mutex m_BufLock; // used to synchronize buffer operation
|
||||
|
||||
struct Block
|
||||
{
|
||||
char* m_pcData; // pointer to the data block
|
||||
int m_iLength; // payload length of the block.
|
||||
|
||||
int32_t m_iMsgNoBitset; // message number
|
||||
int32_t m_iSeqNo; // sequence number for scheduling
|
||||
time_point m_tsOriginTime; // block origin time (either provided from above or equals the time a message was submitted for sending.
|
||||
time_point m_tsRexmitTime; // packet retransmission time
|
||||
int m_iTTL; // time to live (milliseconds)
|
||||
|
||||
Block* m_pNext; // next block
|
||||
|
||||
int32_t getMsgSeq()
|
||||
{
|
||||
// NOTE: this extracts message ID with regard to REXMIT flag.
|
||||
// This is valid only for message ID that IS GENERATED in this instance,
|
||||
// not provided by the peer. This can be otherwise sent to the peer - it doesn't matter
|
||||
// for the peer that it uses LESS bits to represent the message.
|
||||
return m_iMsgNoBitset & MSGNO_SEQ::mask;
|
||||
}
|
||||
|
||||
} * m_pBlock, *m_pFirstBlock, *m_pCurrBlock, *m_pLastBlock;
|
||||
|
||||
// m_pBlock: The head pointer
|
||||
// m_pFirstBlock: The first block
|
||||
// m_pCurrBlock: The current block
|
||||
// m_pLastBlock: The last block (if first == last, buffer is empty)
|
||||
|
||||
struct Buffer
|
||||
{
|
||||
char* m_pcData; // buffer
|
||||
int m_iSize; // size
|
||||
Buffer* m_pNext; // next buffer
|
||||
} * m_pBuffer; // physical buffer
|
||||
|
||||
int32_t m_iNextMsgNo; // next message number
|
||||
|
||||
int m_iSize; // buffer size (number of packets)
|
||||
const int m_iBlockLen; // maximum length of a block holding packet payload (excluding packet header).
|
||||
int m_iCount; // number of used blocks
|
||||
|
||||
int m_iBytesCount; // number of payload bytes in queue
|
||||
time_point m_tsLastOriginTime;
|
||||
|
||||
AvgBufSize m_mavg;
|
||||
CRateEstimator m_rateEstimator;
|
||||
|
||||
private:
|
||||
CSndBuffer(const CSndBuffer&);
|
||||
CSndBuffer& operator=(const CSndBuffer&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if (!ENABLE_NEW_RCVBUFFER)
|
||||
|
||||
class CRcvBuffer
|
||||
{
|
||||
public:
|
||||
typedef sync::steady_clock::time_point time_point;
|
||||
typedef sync::steady_clock::duration duration;
|
||||
|
||||
public:
|
||||
// XXX There's currently no way to access the socket ID set for
|
||||
// whatever the queue is currently working for. Required to find
|
||||
// some way to do this, possibly by having a "reverse pointer".
|
||||
// Currently just "unimplemented".
|
||||
std::string CONID() const { return ""; }
|
||||
|
||||
|
||||
/// Construct the buffer.
|
||||
/// @param [in] queue CUnitQueue that actually holds the units (packets)
|
||||
/// @param [in] bufsize_pkts in units (packets)
|
||||
CRcvBuffer(CUnitQueue* queue, int bufsize_pkts = 65536);
|
||||
~CRcvBuffer();
|
||||
|
||||
static const int DEFAULT_SIZE = 65536;
|
||||
/// Construct the buffer.
|
||||
/// @param [in] queue CUnitQueue that actually holds the units (packets)
|
||||
/// @param [in] bufsize_pkts in units (packets)
|
||||
CRcvBuffer(CUnitQueue* queue, int bufsize_pkts = DEFAULT_SIZE);
|
||||
~CRcvBuffer();
|
||||
|
||||
public:
|
||||
/// Write data into the buffer.
|
||||
/// @param [in] unit pointer to a data unit containing new packet
|
||||
/// @param [in] offset offset from last ACK point.
|
||||
/// @return 0 is success, -1 if data is repeated.
|
||||
int addData(CUnit* unit, int offset);
|
||||
|
||||
/// Write data into the buffer.
|
||||
/// @param [in] unit pointer to a data unit containing new packet
|
||||
/// @param [in] offset offset from last ACK point.
|
||||
/// @return 0 is success, -1 if data is repeated.
|
||||
/// Read data into a user buffer.
|
||||
/// @param [in] data pointer to user buffer.
|
||||
/// @param [in] len length of user buffer.
|
||||
/// @return size of data read.
|
||||
int readBuffer(char* data, int len);
|
||||
|
||||
int addData(CUnit* unit, int offset);
|
||||
/// Read data directly into file.
|
||||
/// @param [in] file C++ file stream.
|
||||
/// @param [in] len expected length of data to write into the file.
|
||||
/// @return size of data read.
|
||||
int readBufferToFile(std::fstream& ofs, int len);
|
||||
|
||||
/// Read data into a user buffer.
|
||||
/// @param [in] data pointer to user buffer.
|
||||
/// @param [in] len length of user buffer.
|
||||
/// @return size of data read.
|
||||
/// Update the ACK point of the buffer.
|
||||
/// @param [in] len number of units to be acknowledged.
|
||||
/// @return 1 if a user buffer is fulfilled, otherwise 0.
|
||||
int ackData(int len);
|
||||
|
||||
int readBuffer(char* data, int len);
|
||||
/// Query how many buffer space left for data receiving.
|
||||
/// Actually only acknowledged packets, that are still in the buffer,
|
||||
/// are considered to take buffer space.
|
||||
///
|
||||
/// @return size of available buffer space (including user buffer) for data receiving.
|
||||
/// Not counting unacknowledged packets.
|
||||
int getAvailBufSize() const;
|
||||
|
||||
/// Read data directly into file.
|
||||
/// @param [in] file C++ file stream.
|
||||
/// @param [in] len expected length of data to write into the file.
|
||||
/// @return size of data read.
|
||||
/// Query how many data has been continuously received (for reading) and ready to play (tsbpdtime < now).
|
||||
/// @return size of valid (continous) data for reading.
|
||||
int getRcvDataSize() const;
|
||||
|
||||
int readBufferToFile(std::fstream& ofs, int len);
|
||||
/// Query how many data was received and acknowledged.
|
||||
/// @param [out] bytes bytes
|
||||
/// @param [out] spantime spantime
|
||||
/// @return size in pkts of acked data.
|
||||
int getRcvDataSize(int& bytes, int& spantime);
|
||||
|
||||
/// Update the ACK point of the buffer.
|
||||
/// @param [in] len number of units to be acknowledged.
|
||||
/// @return 1 if a user buffer is fulfilled, otherwise 0.
|
||||
/// Query a 1 sec moving average of how many data was received and acknowledged.
|
||||
/// @param [out] bytes bytes
|
||||
/// @param [out] spantime spantime
|
||||
/// @return size in pkts of acked data.
|
||||
int getRcvAvgDataSize(int& bytes, int& spantime);
|
||||
|
||||
void ackData(int len);
|
||||
/// Query how many data of the receive buffer is acknowledged.
|
||||
/// @param [in] now current time in us.
|
||||
/// @return none.
|
||||
void updRcvAvgDataSize(const time_point& now);
|
||||
|
||||
/// Query how many buffer space left for data receiving.
|
||||
/// Actually only acknowledged packets, that are still in the buffer,
|
||||
/// are considered to take buffer space.
|
||||
///
|
||||
/// @return size of available buffer space (including user buffer) for data receiving.
|
||||
/// Not counting unacknowledged packets.
|
||||
/// Query the received average payload size.
|
||||
/// @return size (bytes) of payload size
|
||||
unsigned getRcvAvgPayloadSize() const;
|
||||
|
||||
int getAvailBufSize() const;
|
||||
struct ReadingState
|
||||
{
|
||||
time_point tsStart;
|
||||
time_point tsLastAck;
|
||||
time_point tsEnd;
|
||||
int iNumAcknowledged;
|
||||
int iNumUnacknowledged;
|
||||
};
|
||||
|
||||
/// Query how many data has been continuously received (for reading) and ready to play (tsbpdtime < now).
|
||||
/// @return size of valid (continous) data for reading.
|
||||
ReadingState debugGetReadingState() const;
|
||||
|
||||
int getRcvDataSize() const;
|
||||
/// Form a string of the current buffer fullness state.
|
||||
/// number of packets acknowledged, TSBPD readiness, etc.
|
||||
std::string strFullnessState(const time_point& tsNow) const;
|
||||
|
||||
/// Query how many data was received and acknowledged.
|
||||
/// @param [out] bytes bytes
|
||||
/// @param [out] spantime spantime
|
||||
/// @return size in pkts of acked data.
|
||||
/// Mark the message to be dropped from the message list.
|
||||
/// @param [in] msgno message number.
|
||||
/// @param [in] using_rexmit_flag whether the MSGNO field uses rexmit flag (if not, one more bit is part of the
|
||||
/// msgno value)
|
||||
void dropMsg(int32_t msgno, bool using_rexmit_flag);
|
||||
|
||||
int getRcvDataSize(int &bytes, int &spantime);
|
||||
#if SRT_ENABLE_RCVBUFSZ_MAVG
|
||||
|
||||
/// Query a 1 sec moving average of how many data was received and acknowledged.
|
||||
/// @param [out] bytes bytes
|
||||
/// @param [out] spantime spantime
|
||||
/// @return size in pkts of acked data.
|
||||
|
||||
int getRcvAvgDataSize(int &bytes, int &spantime);
|
||||
|
||||
/// Query how many data of the receive buffer is acknowledged.
|
||||
/// @param [in] now current time in us.
|
||||
/// @return none.
|
||||
|
||||
void updRcvAvgDataSize(uint64_t now);
|
||||
#endif /* SRT_ENABLE_RCVBUFSZ_MAVG */
|
||||
|
||||
/// Query the received average payload size.
|
||||
/// @return size (bytes) of payload size
|
||||
|
||||
int getRcvAvgPayloadSize() const;
|
||||
|
||||
|
||||
/// Mark the message to be dropped from the message list.
|
||||
/// @param [in] msgno message number.
|
||||
/// @param [in] using_rexmit_flag whether the MSGNO field uses rexmit flag (if not, one more bit is part of the msgno value)
|
||||
|
||||
void dropMsg(int32_t msgno, bool using_rexmit_flag);
|
||||
|
||||
/// read a message.
|
||||
/// @param [out] data buffer to write the message into.
|
||||
/// @param [in] len size of the buffer.
|
||||
/// @return actuall size of data read.
|
||||
|
||||
int readMsg(char* data, int len);
|
||||
|
||||
/// read a message.
|
||||
/// @param [out] data buffer to write the message into.
|
||||
/// @param [in] len size of the buffer.
|
||||
/// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay
|
||||
/// @return actuall size of data read.
|
||||
|
||||
int readMsg(char* data, int len, ref_t<SRT_MSGCTRL> mctrl);
|
||||
|
||||
/// Query if data is ready to read (tsbpdtime <= now if TsbPD is active).
|
||||
/// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay
|
||||
/// of next packet in recv buffer, ready or not.
|
||||
/// @param [out] curpktseq Sequence number of the packet if there is one ready to play
|
||||
/// @return true if ready to play, false otherwise (tsbpdtime may be !0 in
|
||||
/// both cases).
|
||||
|
||||
bool isRcvDataReady(ref_t<uint64_t> tsbpdtime, ref_t<int32_t> curpktseq);
|
||||
bool isRcvDataReady();
|
||||
bool isRcvDataAvailable()
|
||||
{
|
||||
return m_iLastAckPos != m_iStartPos;
|
||||
}
|
||||
CPacket* getRcvReadyPacket();
|
||||
|
||||
/// Set TimeStamp-Based Packet Delivery Rx Mode
|
||||
/// @param [in] timebase localtime base (uSec) of packet time stamps including buffering delay
|
||||
/// @param [in] delay aggreed TsbPD delay
|
||||
/// @return 0
|
||||
|
||||
int setRcvTsbPdMode(uint64_t timebase, uint32_t delay);
|
||||
|
||||
/// Add packet timestamp for drift caclculation and compensation
|
||||
/// @param [in] timestamp packet time stamp
|
||||
/// @param [ref] lock Mutex that should be locked for the operation
|
||||
|
||||
void addRcvTsbPdDriftSample(uint32_t timestamp, pthread_mutex_t& lock);
|
||||
|
||||
#ifdef SRT_DEBUG_TSBPD_DRIFT
|
||||
void printDriftHistogram(int64_t iDrift);
|
||||
void printDriftOffset(int tsbPdOffset, int tsbPdDriftAvg);
|
||||
#endif
|
||||
|
||||
/// Get information on the 1st message in queue.
|
||||
// Parameters (of the 1st packet queue, ready to play or not):
|
||||
/// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if none
|
||||
/// @param [out] passack true if 1st ready packet is not yet acknowleged (allowed to be delivered to the app)
|
||||
/// @param [out] skipseqno -1 or seq number of 1st unacknowledged pkt ready to play preceeded by missing packets.
|
||||
/// @retval true 1st packet ready to play (tsbpdtime <= now). Not yet acknowledged if passack == true
|
||||
/// @retval false IF tsbpdtime = 0: rcv buffer empty; ELSE:
|
||||
/// IF skipseqno != -1, packet ready to play preceeded by missing packets.;
|
||||
/// IF skipseqno == -1, no missing packet but 1st not ready to play.
|
||||
|
||||
|
||||
bool getRcvFirstMsg(ref_t<uint64_t> tsbpdtime, ref_t<bool> passack, ref_t<int32_t> skipseqno, ref_t<int32_t> curpktseq);
|
||||
|
||||
/// Update the ACK point of the buffer.
|
||||
/// @param [in] len size of data to be skip & acknowledged.
|
||||
|
||||
void skipData(int len);
|
||||
/// read a message.
|
||||
/// @param [out] data buffer to write the message into.
|
||||
/// @param [in] len size of the buffer.
|
||||
/// @return actuall size of data read.
|
||||
int readMsg(char* data, int len);
|
||||
|
||||
#if ENABLE_HEAVY_LOGGING
|
||||
void reportBufferStats(); // Heavy logging Debug only
|
||||
void readMsgHeavyLogging(int p);
|
||||
#endif
|
||||
|
||||
private:
|
||||
/// Adjust receive queue to 1st ready to play message (tsbpdtime < now).
|
||||
// Parameters (of the 1st packet queue, ready to play or not):
|
||||
/// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if none
|
||||
/// @retval true 1st packet ready to play without discontinuity (no hole)
|
||||
/// @retval false tsbpdtime = 0: no packet ready to play
|
||||
/// read a message.
|
||||
/// @param [out] data buffer to write the message into.
|
||||
/// @param [in] len size of the buffer.
|
||||
/// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay
|
||||
/// @return actuall size of data read.
|
||||
int readMsg(char* data, int len, SRT_MSGCTRL& w_mctrl, int upto);
|
||||
|
||||
|
||||
bool getRcvReadyMsg(ref_t<uint64_t> tsbpdtime, ref_t<int32_t> curpktseq);
|
||||
|
||||
public:
|
||||
|
||||
// (This is exposed as used publicly in logs)
|
||||
/// Get packet delivery local time base (adjusted for wrap around)
|
||||
/// @param [in] timestamp packet timestamp (relative to peer StartTime), wrapping around every ~72 min
|
||||
/// @return local delivery time (usec)
|
||||
uint64_t getTsbPdTimeBase(uint32_t timestamp_us);
|
||||
|
||||
/// Get packet local delivery time
|
||||
/// @param [in] timestamp packet timestamp (relative to peer StartTime), wrapping around every ~72 min
|
||||
/// @return local delivery time (usec)
|
||||
|
||||
public:
|
||||
uint64_t getPktTsbPdTime(uint32_t timestamp);
|
||||
int debugGetSize() const;
|
||||
bool empty() const;
|
||||
|
||||
// Required by PacketFilter facility to use as a storage
|
||||
// for provided packets
|
||||
CUnitQueue* getUnitQueue()
|
||||
{
|
||||
return m_pUnitQueue;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// thread safe bytes counter of the Recv & Ack buffer
|
||||
/// @param [in] pkts acked or removed pkts from rcv buffer (used with acked = true)
|
||||
/// @param [in] bytes number of bytes added/delete (if negative) to/from rcv buffer.
|
||||
/// @param [in] acked true when adding new pkt in RcvBuffer; false when acking/removing pkts to/from buffer
|
||||
|
||||
void countBytes(int pkts, int bytes, bool acked = false);
|
||||
|
||||
private:
|
||||
bool scanMsg(ref_t<int> start, ref_t<int> end, ref_t<bool> passack);
|
||||
|
||||
private:
|
||||
CUnit** m_pUnit; // pointer to the protocol buffer (array of CUnit* items)
|
||||
const int m_iSize; // size of the array of CUnit* items
|
||||
CUnitQueue* m_pUnitQueue; // the shared unit queue
|
||||
|
||||
int m_iStartPos; // the head position for I/O (inclusive)
|
||||
int m_iLastAckPos; // the last ACKed position (exclusive)
|
||||
// EMPTY: m_iStartPos = m_iLastAckPos FULL: m_iStartPos = m_iLastAckPos + 1
|
||||
int m_iMaxPos; // the furthest data position
|
||||
|
||||
int m_iNotch; // the starting read point of the first unit
|
||||
|
||||
pthread_mutex_t m_BytesCountLock; // used to protect counters operations
|
||||
int m_iBytesCount; // Number of payload bytes in the buffer
|
||||
int m_iAckedPktsCount; // Number of acknowledged pkts in the buffer
|
||||
int m_iAckedBytesCount; // Number of acknowledged payload bytes in the buffer
|
||||
int m_iAvgPayloadSz; // Average payload size for dropped bytes estimation
|
||||
|
||||
bool m_bTsbPdMode; // true: apply TimeStamp-Based Rx Mode
|
||||
uint32_t m_uTsbPdDelay; // aggreed delay
|
||||
uint64_t m_ullTsbPdTimeBase; // localtime base for TsbPd mode
|
||||
// Note: m_ullTsbPdTimeBase cumulates values from:
|
||||
// 1. Initial SRT_CMD_HSREQ packet returned value diff to current time:
|
||||
// == (NOW - PACKET_TIMESTAMP), at the time of HSREQ reception
|
||||
// 2. Timestamp overflow (@c CRcvBuffer::getTsbPdTimeBase), when overflow on packet detected
|
||||
// += CPacket::MAX_TIMESTAMP+1 (it's a hex round value, usually 0x1*e8).
|
||||
// 3. Time drift (CRcvBuffer::addRcvTsbPdDriftSample, executed exclusively
|
||||
// from UMSG_ACKACK handler). This is updated with (positive or negative) TSBPD_DRIFT_MAX_VALUE
|
||||
// once the value of average drift exceeds this value in whatever direction.
|
||||
// += (+/-)CRcvBuffer::TSBPD_DRIFT_MAX_VALUE
|
||||
//
|
||||
// XXX Application-supplied timestamps won't work therefore. This requires separate
|
||||
// calculation of all these things above.
|
||||
|
||||
bool m_bTsbPdWrapCheck; // true: check packet time stamp wrap around
|
||||
static const uint32_t TSBPD_WRAP_PERIOD = (30*1000000); //30 seconds (in usec)
|
||||
|
||||
static const int TSBPD_DRIFT_MAX_VALUE = 5000; // Max drift (usec) above which TsbPD Time Offset is adjusted
|
||||
static const int TSBPD_DRIFT_MAX_SAMPLES = 1000; // Number of samples (UMSG_ACKACK packets) to perform drift caclulation and compensation
|
||||
//int m_iTsbPdDrift; // recent drift in the packet time stamp
|
||||
//int64_t m_TsbPdDriftSum; // Sum of sampled drift
|
||||
//int m_iTsbPdDriftNbSamples; // Number of samples in sum and histogram
|
||||
DriftTracer<TSBPD_DRIFT_MAX_SAMPLES, TSBPD_DRIFT_MAX_VALUE> m_DriftTracer;
|
||||
#ifdef SRT_ENABLE_RCVBUFSZ_MAVG
|
||||
uint64_t m_LastSamplingTime;
|
||||
int m_TimespanMAvg;
|
||||
int m_iCountMAvg;
|
||||
int m_iBytesCountMAvg;
|
||||
#endif /* SRT_ENABLE_RCVBUFSZ_MAVG */
|
||||
#ifdef SRT_DEBUG_TSBPD_DRIFT
|
||||
int m_TsbPdDriftHisto100us[22]; // Histogram of 100us TsbPD drift (-1.0 .. +1.0 ms in 0.1ms increment)
|
||||
int m_TsbPdDriftHisto1ms[22]; // Histogram of TsbPD drift (-10.0 .. +10.0 ms, in 1.0 ms increment)
|
||||
static const int TSBPD_DRIFT_PRT_SAMPLES = 200; // Number of samples (UMSG_ACKACK packets) to print hostogram
|
||||
#endif /* SRT_DEBUG_TSBPD_DRIFT */
|
||||
/// Query if data is ready to read (tsbpdtime <= now if TsbPD is active).
|
||||
/// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay
|
||||
/// of next packet in recv buffer, ready or not.
|
||||
/// @param [out] curpktseq Sequence number of the packet if there is one ready to play
|
||||
/// @return true if ready to play, false otherwise (tsbpdtime may be !0 in
|
||||
/// both cases).
|
||||
bool isRcvDataReady(time_point& w_tsbpdtime, int32_t& w_curpktseq, int32_t seqdistance);
|
||||
|
||||
#ifdef SRT_DEBUG_TSBPD_OUTJITTER
|
||||
unsigned long m_ulPdHisto[4][10];
|
||||
#endif /* SRT_DEBUG_TSBPD_OUTJITTER */
|
||||
void debugTraceJitter(time_point t);
|
||||
#else
|
||||
void debugTraceJitter(time_point) {}
|
||||
#endif /* SRT_DEBUG_TSBPD_OUTJITTER */
|
||||
|
||||
bool isRcvDataReady();
|
||||
bool isRcvDataAvailable() { return m_iLastAckPos != m_iStartPos; }
|
||||
CPacket* getRcvReadyPacket(int32_t seqdistance);
|
||||
|
||||
/// Set TimeStamp-Based Packet Delivery Rx Mode
|
||||
/// @param [in] timebase localtime base (uSec) of packet time stamps including buffering delay
|
||||
/// @param [in] delay aggreed TsbPD delay
|
||||
void setRcvTsbPdMode(const time_point& timebase, const duration& delay);
|
||||
|
||||
/// Add packet timestamp for drift caclculation and compensation
|
||||
/// @param [in] timestamp packet time stamp
|
||||
/// @param [in] tsPktArrival arrival time of the packet used to extract the drift sample.
|
||||
/// @param [in] rtt RTT sample
|
||||
bool addRcvTsbPdDriftSample(uint32_t timestamp, const time_point& tsPktArrival, int rtt);
|
||||
|
||||
#ifdef SRT_DEBUG_TSBPD_DRIFT
|
||||
void printDriftHistogram(int64_t iDrift);
|
||||
void printDriftOffset(int tsbPdOffset, int tsbPdDriftAvg);
|
||||
#endif
|
||||
|
||||
/// Get information on the 1st message in queue.
|
||||
// Parameters (of the 1st packet queue, ready to play or not):
|
||||
/// @param [out] w_tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0
|
||||
/// if none
|
||||
/// @param [out] w_passack true if 1st ready packet is not yet acknowleged (allowed to be delivered to the app)
|
||||
/// @param [out] w_skipseqno SRT_SEQNO_NONE or seq number of 1st unacknowledged pkt ready to play preceeded by
|
||||
/// missing packets.
|
||||
/// @param base_seq SRT_SEQNO_NONE or desired, ignore seq smaller than base if exist packet ready-to-play
|
||||
/// and larger than base
|
||||
/// @retval true 1st packet ready to play (tsbpdtime <= now). Not yet acknowledged if passack == true
|
||||
/// @retval false IF tsbpdtime = 0: rcv buffer empty; ELSE:
|
||||
/// IF skipseqno != SRT_SEQNO_NONE, packet ready to play preceeded by missing packets.;
|
||||
/// IF skipseqno == SRT_SEQNO_NONE, no missing packet but 1st not ready to play.
|
||||
bool getRcvFirstMsg(time_point& w_tsbpdtime,
|
||||
bool& w_passack,
|
||||
int32_t& w_skipseqno,
|
||||
int32_t& w_curpktseq,
|
||||
int32_t base_seq = SRT_SEQNO_NONE);
|
||||
|
||||
/// Update the ACK point of the buffer.
|
||||
/// @param [in] len size of data to be skip & acknowledged.
|
||||
void skipData(int len);
|
||||
|
||||
#if ENABLE_HEAVY_LOGGING
|
||||
void reportBufferStats() const; // Heavy logging Debug only
|
||||
#endif
|
||||
bool empty() const
|
||||
{
|
||||
// This will not always return the intended value,
|
||||
// that is, it may return false when the buffer really is
|
||||
// empty - but it will return true then in one of next calls.
|
||||
// This function will be always called again at some point
|
||||
// if it returned false, and on true the connection
|
||||
// is going to be broken - so this behavior is acceptable.
|
||||
return m_iStartPos == m_iLastAckPos;
|
||||
}
|
||||
bool full() const { return m_iStartPos == (m_iLastAckPos + 1) % m_iSize; }
|
||||
int capacity() const { return m_iSize; }
|
||||
|
||||
private:
|
||||
CRcvBuffer();
|
||||
CRcvBuffer(const CRcvBuffer&);
|
||||
CRcvBuffer& operator=(const CRcvBuffer&);
|
||||
/// This gives up unit at index p. The unit is given back to the
|
||||
/// free unit storage for further assignment for the new incoming
|
||||
/// data.
|
||||
size_t freeUnitAt(size_t p)
|
||||
{
|
||||
CUnit* u = m_pUnit[p];
|
||||
m_pUnit[p] = NULL;
|
||||
size_t rmbytes = u->m_Packet.getLength();
|
||||
m_pUnitQueue->makeUnitFree(u);
|
||||
return rmbytes;
|
||||
}
|
||||
|
||||
/// Adjust receive queue to 1st ready to play message (tsbpdtime < now).
|
||||
/// Parameters (of the 1st packet queue, ready to play or not):
|
||||
/// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if
|
||||
/// none
|
||||
/// @param base_seq SRT_SEQNO_NONE or desired, ignore seq smaller than base
|
||||
/// @retval true 1st packet ready to play without discontinuity (no hole)
|
||||
/// @retval false tsbpdtime = 0: no packet ready to play
|
||||
bool getRcvReadyMsg(time_point& w_tsbpdtime, int32_t& w_curpktseq, int upto, int base_seq = SRT_SEQNO_NONE);
|
||||
|
||||
public:
|
||||
/// @brief Get clock drift in microseconds.
|
||||
int64_t getDrift() const { return m_tsbpd.drift(); }
|
||||
|
||||
public:
|
||||
int32_t getTopMsgno() const;
|
||||
|
||||
void getInternalTimeBase(time_point& w_tb, bool& w_wrp, duration& w_udrift);
|
||||
|
||||
void applyGroupTime(const time_point& timebase, bool wrapcheck, uint32_t delay, const duration& udrift);
|
||||
void applyGroupDrift(const time_point& timebase, bool wrapcheck, const duration& udrift);
|
||||
time_point getPktTsbPdTime(uint32_t timestamp);
|
||||
int debugGetSize() const;
|
||||
time_point debugGetDeliveryTime(int offset);
|
||||
|
||||
size_t dropData(int len);
|
||||
|
||||
private:
|
||||
int extractData(char* data, int len, int p, int q, bool passack);
|
||||
bool accessMsg(int& w_p, int& w_q, bool& w_passack, int64_t& w_playtime, int upto);
|
||||
|
||||
/// Describes the state of the first N packets
|
||||
std::string debugTimeState(size_t first_n_pkts) const;
|
||||
|
||||
/// thread safe bytes counter of the Recv & Ack buffer
|
||||
/// @param [in] pkts acked or removed pkts from rcv buffer (used with acked = true)
|
||||
/// @param [in] bytes number of bytes added/delete (if negative) to/from rcv buffer.
|
||||
/// @param [in] acked true when adding new pkt in RcvBuffer; false when acking/removing pkts to/from buffer
|
||||
void countBytes(int pkts, int bytes, bool acked = false);
|
||||
|
||||
private:
|
||||
bool scanMsg(int& w_start, int& w_end, bool& w_passack);
|
||||
|
||||
int shift(int basepos, int shift) const { return (basepos + shift) % m_iSize; }
|
||||
|
||||
/// Simplified versions with ++ and --; avoid using division instruction
|
||||
int shiftFwd(int basepos) const
|
||||
{
|
||||
if (++basepos == m_iSize)
|
||||
return 0;
|
||||
return basepos;
|
||||
}
|
||||
|
||||
int shiftBack(int basepos) const
|
||||
{
|
||||
if (basepos == 0)
|
||||
return m_iSize - 1;
|
||||
return --basepos;
|
||||
}
|
||||
|
||||
private:
|
||||
CUnit** m_pUnit; // Array of pointed units collected in the buffer
|
||||
const int m_iSize; // Size of the internal array of CUnit* items
|
||||
CUnitQueue* m_pUnitQueue; // the shared unit queue
|
||||
|
||||
int m_iStartPos; // HEAD: first packet available for reading
|
||||
int m_iLastAckPos; // the last ACKed position (exclusive), follows the last readable
|
||||
// EMPTY: m_iStartPos = m_iLastAckPos FULL: m_iStartPos = m_iLastAckPos + 1
|
||||
int m_iMaxPos; // delta between acked-TAIL and reception-TAIL
|
||||
|
||||
int m_iNotch; // the starting read point of the first unit
|
||||
// (this is required for stream reading mode; it's
|
||||
// the position in the first unit in the list
|
||||
// up to which data are already retrieved;
|
||||
// in message reading mode it's unused and always 0)
|
||||
|
||||
sync::Mutex m_BytesCountLock; // used to protect counters operations
|
||||
int m_iBytesCount; // Number of payload bytes in the buffer
|
||||
int m_iAckedPktsCount; // Number of acknowledged pkts in the buffer
|
||||
int m_iAckedBytesCount; // Number of acknowledged payload bytes in the buffer
|
||||
unsigned m_uAvgPayloadSz; // Average payload size for dropped bytes estimation
|
||||
|
||||
CTsbpdTime m_tsbpd;
|
||||
|
||||
AvgBufSize m_mavg;
|
||||
|
||||
private:
|
||||
CRcvBuffer();
|
||||
CRcvBuffer(const CRcvBuffer&);
|
||||
CRcvBuffer& operator=(const CRcvBuffer&);
|
||||
};
|
||||
|
||||
#endif // !ENABLE_NEW_RCVBUFFER
|
||||
|
||||
} // namespace srt
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue