Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] Use SND buffer delay for TL Packet Drop instead of the timespan #2230

Merged
merged 2 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions srtcore/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ int CSndBuffer::readData(CPacket& w_packet, steady_clock::time_point& w_srctime,
int readlen = 0;
w_seqnoinc = 0;

ScopedLock bufferguard(m_BufLock);
while (m_pCurrBlock != m_pLastBlock)
{
// Make the packet REFLECT the data stored in the buffer.
Expand Down Expand Up @@ -686,10 +687,14 @@ int CSndBuffer::getCurrBufSize(int& w_bytes, int& w_timespan)
return m_iCount;
}

CSndBuffer::time_point CSndBuffer::getOldestTime() const
CSndBuffer::duration CSndBuffer::getBufferingDelay(const time_point& tnow) const
{
ScopedLock lck(m_BufLock);
SRT_ASSERT(m_pFirstBlock);
return m_pFirstBlock->m_tsOriginTime;
if (m_iCount == 0)
return duration(0);

return tnow - m_pFirstBlock->m_tsOriginTime;
}

int CSndBuffer::dropLateData(int& w_bytes, int32_t& w_first_msgno, const steady_clock::time_point& too_late_time)
Expand Down
15 changes: 12 additions & 3 deletions srtcore/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,14 @@ class CSndBuffer
/// @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);

/// 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);

/// Find data position to pack a DATA packet from the furthest reading point.
Expand All @@ -147,6 +149,7 @@ class CSndBuffer
/// @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);

/// Find data position to pack a DATA packet for a retransmission.
Expand All @@ -155,12 +158,14 @@ class CSndBuffer
/// @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);

/// 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);

/// Update the ACK point and may release/unmap/return the user data according to the flag.
Expand All @@ -173,13 +178,17 @@ class CSndBuffer
/// @return Current size of the data in the sending list.
int getCurrBufSize() const;

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);

time_point getOldestTime() const;
/// @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_InRatePeriod; }

Expand Down Expand Up @@ -207,7 +216,7 @@ class CSndBuffer
static const int INPUTRATE_INITIAL_BYTESPS = BW_INFINITE;

private:
sync::Mutex m_BufLock; // used to synchronize buffer operation
mutable sync::Mutex m_BufLock; // used to synchronize buffer operation

struct Block
{
Expand All @@ -216,7 +225,7 @@ class CSndBuffer

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 equials the time a message was submitted for sending.
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)

Expand Down
25 changes: 11 additions & 14 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6338,31 +6338,28 @@ bool srt::CUDT::checkNeedDrop()
throw CUDTException(MJ_NOTSUP, MN_INVALBUFFERAPI, 0);
}

int bytes, timespan_ms;
// (returns buffer size in buffer units, ignored)
m_pSndBuffer->getCurrBufSize((bytes), (timespan_ms));
const time_point tnow = steady_clock::now();
const int buffdelay_ms = count_milliseconds(m_pSndBuffer->getBufferingDelay(tnow));

// high threshold (msec) at tsbpd_delay plus sender/receiver reaction time (2 * 10ms)
// Minimum value must accomodate an I-Frame (~8 x average frame size)
// >>need picture rate or app to set min treshold
// >>using 1 sec for worse case 1 frame using all bit budget.
// picture rate would be useful in auto SRT setting for min latency
// XXX Make SRT_TLPKTDROP_MINTHRESHOLD_MS option-configurable
int threshold_ms = 0;
if (m_config.iSndDropDelay >= 0)
{
threshold_ms = std::max(m_iPeerTsbPdDelay_ms + m_config.iSndDropDelay, +SRT_TLPKTDROP_MINTHRESHOLD_MS) +
(2 * COMM_SYN_INTERVAL_US / 1000);
}
const int threshold_ms = (m_config.iSndDropDelay >= 0)
? std::max(m_iPeerTsbPdDelay_ms + m_config.iSndDropDelay, +SRT_TLPKTDROP_MINTHRESHOLD_MS)
+ (2 * COMM_SYN_INTERVAL_US / 1000)
: 0;

bool bCongestion = false;
if (threshold_ms && timespan_ms > threshold_ms)
if (threshold_ms && buffdelay_ms > threshold_ms)
{
// protect packet retransmission
enterCS(m_RecvAckLock);
int dbytes;
int32_t first_msgno;
int dpkts = m_pSndBuffer->dropLateData((dbytes), (first_msgno), steady_clock::now() - milliseconds_from(threshold_ms));
int dpkts = m_pSndBuffer->dropLateData((dbytes), (first_msgno), tnow - milliseconds_from(threshold_ms));
if (dpkts > 0)
{
enterCS(m_StatsLock);
Expand All @@ -6385,7 +6382,7 @@ bool srt::CUDT::checkNeedDrop()
}

HLOGC(aslog.Debug, log << "SND-DROP: %(" << realack << "-" << m_iSndCurrSeqNo << ") n="
<< dpkts << "pkt " << dbytes << "B, span=" << timespan_ms << " ms, FIRST #" << first_msgno);
<< dpkts << "pkt " << dbytes << "B, span=" << buffdelay_ms << " ms, FIRST #" << first_msgno);

#if ENABLE_EXPERIMENTAL_BONDING
// This is done with a presumption that the group
Expand Down Expand Up @@ -6413,10 +6410,10 @@ bool srt::CUDT::checkNeedDrop()
bCongestion = true;
leaveCS(m_RecvAckLock);
}
else if (timespan_ms > (m_iPeerTsbPdDelay_ms / 2))
else if (buffdelay_ms > (m_iPeerTsbPdDelay_ms / 2))
{
HLOGC(aslog.Debug,
log << "cong, BYTES " << bytes << ", TMSPAN " << timespan_ms << "ms");
log << "cong TIMESPAN " << buffdelay_ms << "ms");

bCongestion = true;
}
Expand Down