Skip to content

Commit 1111cbd

Browse files
[core] Fixed RCV TL drop of packets dropped by SND (#2214)
Moved the TL drop logic from the TSBPD thread to a dedicated function.
1 parent 5f7bc23 commit 1111cbd

File tree

5 files changed

+43
-28
lines changed

5 files changed

+43
-28
lines changed

docs/API/statistics.md

+2
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ where `SRTO_PEERLATENCY` is the configured SRT latency, `SRTO_SNDDROPDELAY` adds
235235
The total number of _dropped_ by the SRT receiver and, as a result, not delivered to the upstream application DATA packets (refer to [TLPKTDROP](https://github.com/Haivision/srt-rfc/blob/master/draft-sharabayko-mops-srt.md#too-late-packet-drop-too-late-packet-drop) mechanism). Available for receiver.
236236

237237
This statistic counts
238+
239+
- not arrived packets including those signalled for dropping by the sender, that were dropped in favor of the subsequent existing packets,
238240
- arrived too late packets (retransmitted or original packets arrived out of order),
239241
- arrived in time packets, but decrypted with errors (see also [pktRcvUndecryptTotal](#pktRcvUndecryptTotal) statistic).
240242

srtcore/buffer_rcv.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ int CRcvBufferNew::insert(CUnit* unit)
159159
return 0;
160160
}
161161

162-
void CRcvBufferNew::dropUpTo(int32_t seqno)
162+
int CRcvBufferNew::dropUpTo(int32_t seqno)
163163
{
164164
// Can drop only when nothing to read, and
165165
// first unacknowledged packet is missing.
@@ -173,17 +173,15 @@ void CRcvBufferNew::dropUpTo(int32_t seqno)
173173
if (len <= 0)
174174
{
175175
IF_RCVBUF_DEBUG(scoped_log.ss << ". Nothing to drop.");
176-
return;
176+
return 0;
177177
}
178178

179-
/*LOGC(rbuflog.Warn, log << "CRcvBufferNew.dropUpTo(): seqno=" << seqno << ", pkts=" << len
180-
<< ". Buffer start " << m_iStartSeqNo << ".");*/
181-
182179
m_iMaxPosInc -= len;
183180
if (m_iMaxPosInc < 0)
184181
m_iMaxPosInc = 0;
185182

186183
// Check that all packets being dropped are missing.
184+
const int iDropCnt = len;
187185
while (len > 0)
188186
{
189187
if (m_entries[m_iStartPos].pUnit != NULL)
@@ -210,6 +208,7 @@ void CRcvBufferNew::dropUpTo(int32_t seqno)
210208
// because start position was increased, and preceeding packets are invalid.
211209
m_iFirstNonreadPos = m_iStartPos;
212210
updateNonreadPos();
211+
return iDropCnt;
213212
}
214213

215214
void CRcvBufferNew::dropMessage(int32_t seqnolo, int32_t seqnohi, int32_t msgno)

srtcore/buffer_rcv.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ class CRcvBufferNew
6969

7070
/// Drop packets in the receiver buffer from the current position up to the seqno (excluding seqno).
7171
/// @param [in] seqno drop units up to this sequence number
72+
/// @return number of dropped packets.
7273
///
73-
void dropUpTo(int32_t seqno);
74+
int dropUpTo(int32_t seqno);
7475

7576
/// @brief Drop the whole message from the buffer.
7677
/// If message number is 0, then use sequence numbers to locate sequence range to drop [seqnolo, seqnohi].

srtcore/core.cpp

+29-22
Original file line numberDiff line numberDiff line change
@@ -5174,39 +5174,21 @@ void * srt::CUDT::tsbpd(void* param)
51745174
rxready = true;
51755175
if (info.seq_gap)
51765176
{
5177-
const int seq_gap_len = CSeqNo::seqoff(self->m_iRcvLastSkipAck, info.seqno);
5178-
SRT_ASSERT(seq_gap_len > 0);
5179-
/*if (!info.seq_gap)
5180-
{
5181-
LOGC(brlog.Warn, log << "TSBPD worker: no gap. pktseqno=" << info.seqno
5182-
<< ", m_iRcvLastSkipAck=" << self->m_iRcvLastSkipAck
5183-
<< ", RBuffer start seqno=" << self->m_pRcvBuffer->getStartSeqNo()
5184-
<< ", m_iRcvLastAck=" << self->m_iRcvLastAck
5185-
<< ", init seqnoo=" << self->m_iISN);
5186-
}*/
5187-
5188-
// Drop too late packets
5189-
self->updateForgotten(seq_gap_len, self->m_iRcvLastSkipAck, info.seqno);
5190-
//if (info.seq_gap) // If there is no sequence gap, we are reading ahead of ACK.
5191-
//{
5192-
self->m_pRcvBuffer->dropUpTo(info.seqno);
5193-
//}
5194-
5195-
self->m_iRcvLastSkipAck = info.seqno;
5177+
const int iDropCnt SRT_ATR_UNUSED = self->dropTooLateUpTo(info.seqno);
5178+
51965179
#if ENABLE_EXPERIMENTAL_BONDING
51975180
shall_update_group = true;
51985181
#endif
51995182

52005183
#if ENABLE_LOGGING
52015184
const int64_t timediff_us = count_microseconds(tnow - info.tsbpd_time);
5202-
// TODO: seq_gap_len is not the actual number of packets dropped.
52035185
#if ENABLE_HEAVY_LOGGING
52045186
HLOGC(tslog.Debug,
52055187
log << self->CONID() << "tsbpd: DROPSEQ: up to seqno %" << CSeqNo::decseq(info.seqno) << " ("
5206-
<< seq_gap_len << " packets) playable at " << FormatTime(info.tsbpd_time) << " delayed "
5188+
<< iDropCnt << " packets) playable at " << FormatTime(info.tsbpd_time) << " delayed "
52075189
<< (timediff_us / 1000) << "." << std::setw(3) << std::setfill('0') << (timediff_us % 1000) << " ms");
52085190
#endif
5209-
LOGC(brlog.Warn, log << self->CONID() << "RCV-DROPPED " << seq_gap_len << " packet(s), packet seqno %" << info.seqno
5191+
LOGC(brlog.Warn, log << self->CONID() << "RCV-DROPPED " << iDropCnt << " packet(s). Packet seqno %" << info.seqno
52105192
<< " delayed for " << (timediff_us / 1000) << "." << std::setw(3) << std::setfill('0')
52115193
<< (timediff_us % 1000) << " ms");
52125194
#endif
@@ -5539,6 +5521,30 @@ void * srt::CUDT::tsbpd(void *param)
55395521
}
55405522
#endif // ENABLE_NEW_RCVBUFFER
55415523

5524+
int srt::CUDT::dropTooLateUpTo(int seqno)
5525+
{
5526+
const int seq_gap_len = CSeqNo::seqoff(m_iRcvLastSkipAck, seqno);
5527+
5528+
// seq_gap_len can be <= 0 if a packet has been dropped by the sender.
5529+
if (seq_gap_len > 0)
5530+
{
5531+
// Remove [from,to-inclusive]
5532+
dropFromLossLists(m_iRcvLastSkipAck, CSeqNo::decseq(seqno));
5533+
m_iRcvLastSkipAck = seqno;
5534+
}
5535+
5536+
const int iDropCnt = m_pRcvBuffer->dropUpTo(seqno);
5537+
if (iDropCnt > 0)
5538+
{
5539+
enterCS(m_StatsLock);
5540+
// Estimate dropped bytes from average payload size.
5541+
const uint64_t avgpayloadsz = m_pRcvBuffer->getRcvAvgPayloadSize();
5542+
m_stats.rcvr.dropped.count(stats::BytesPackets(iDropCnt * avgpayloadsz, (size_t) iDropCnt));
5543+
leaveCS(m_StatsLock);
5544+
}
5545+
return iDropCnt;
5546+
}
5547+
55425548
void srt::CUDT::updateForgotten(int seqlen, int32_t lastack, int32_t skiptoseqno)
55435549
{
55445550
enterCS(m_StatsLock);
@@ -7898,6 +7904,7 @@ int srt::CUDT::sendCtrlAck(CPacket& ctrlpkt, int size)
78987904
// If there is no loss, the ACK is the current largest sequence number plus 1;
78997905
// Otherwise it is the smallest sequence number in the receiver loss list.
79007906
ScopedLock lock(m_RcvLossLock);
7907+
// TODO: Consider the Fresh Loss list as well!!!
79017908
ack = m_pRcvLossList->getFirstLostSeq();
79027909
}
79037910

srtcore/core.h

+6
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,12 @@ class CUDT
705705
// TSBPD thread main function.
706706
static void* tsbpd(void* param);
707707

708+
/// Drop too late packets. Updaet loss lists and ACK positions.
709+
/// The @a seqno packet itself is not dropped.
710+
/// @param seqno [in] The sequence number of the first packets following those to be dropped.
711+
/// @return The number of packets dropped.
712+
int dropTooLateUpTo(int seqno);
713+
708714
void updateForgotten(int seqlen, int32_t lastack, int32_t skiptoseqno);
709715

710716
static loss_seqs_t defaultPacketArrival(void* vself, CPacket& pkt);

0 commit comments

Comments
 (0)