diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 635d71687..6752d7e9f 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -5576,7 +5576,7 @@ void * srt::CUDT::tsbpd(void* param) return NULL; } -int srt::CUDT::rcvDropTooLateUpTo(int seqno) +int srt::CUDT::rcvDropTooLateUpTo(int seqno, DropReason reason) { // Make sure that it would not drop over m_iRcvCurrSeqNo, which may break senders. if (CSeqNo::seqcmp(seqno, CSeqNo::incseq(m_iRcvCurrSeqNo)) > 0) @@ -5588,12 +5588,15 @@ int srt::CUDT::rcvDropTooLateUpTo(int seqno) const int iDropCnt = iDropDiscardedPkts.first; const int iDiscardedCnt = iDropDiscardedPkts.second; const int iDropCntTotal = iDropCnt + iDiscardedCnt; - if (iDropCnt > 0) + + // In case of DROP_TOO_LATE discarded packets should also be counted because they are not read from another member socket. + const int iDropStatCnt = (reason == DROP_DISCARD) ? iDropCnt : iDropCntTotal; + if (iDropStatCnt > 0) { enterCS(m_StatsLock); // Estimate dropped bytes from average payload size. const uint64_t avgpayloadsz = m_pRcvBuffer->getRcvAvgPayloadSize(); - m_stats.rcvr.dropped.count(stats::BytesPackets(iDropCnt * avgpayloadsz, (uint32_t) iDropCnt)); + m_stats.rcvr.dropped.count(stats::BytesPackets(iDropStatCnt * avgpayloadsz, (uint32_t)iDropStatCnt)); leaveCS(m_StatsLock); } return iDropCntTotal; @@ -7838,7 +7841,7 @@ void srt::CUDT::dropToGroupRecvBase() return; ScopedLock lck(m_RcvBufferLock); - int cnt = rcvDropTooLateUpTo(CSeqNo::incseq(group_recv_base)); + const int cnt = rcvDropTooLateUpTo(CSeqNo::incseq(group_recv_base), DROP_DISCARD); if (cnt > 0) { HLOGC(grlog.Debug, @@ -8066,6 +8069,7 @@ int srt::CUDT::sendCtrlAck(CPacket& ctrlpkt, int size) string reason; // just for "a reason" of giving particular % for ACK #if ENABLE_BONDING + // TODO: The group drops other members upon reading, maybe no longer needed here? dropToGroupRecvBase(); #endif diff --git a/srtcore/core.h b/srtcore/core.h index 10746c8c9..73b053197 100644 --- a/srtcore/core.h +++ b/srtcore/core.h @@ -755,11 +755,18 @@ class CUDT // TSBPD thread main function. static void* tsbpd(void* param); + enum DropReason + { + DROP_TOO_LATE, //< Drop to keep up to the live pace (TLPKTDROP). + DROP_DISCARD //< Drop because another group member already provided these packets. + }; + /// Drop too late packets (receiver side). Update loss lists and ACK positions. /// The @a seqno packet itself is not dropped. /// @param seqno [in] The sequence number of the first packets following those to be dropped. + /// @param reason A reason for dropping (see @a DropReason). /// @return The number of packets dropped. - int rcvDropTooLateUpTo(int seqno); + int rcvDropTooLateUpTo(int seqno, DropReason reason = DROP_TOO_LATE); static loss_seqs_t defaultPacketArrival(void* vself, CPacket& pkt); static loss_seqs_t groupPacketArrival(void* vself, CPacket& pkt); diff --git a/srtcore/group.cpp b/srtcore/group.cpp index 1539245a0..0491a7296 100644 --- a/srtcore/group.cpp +++ b/srtcore/group.cpp @@ -2324,7 +2324,7 @@ int CUDTGroup::recv(char* buf, int len, SRT_MSGCTRL& w_mc) ScopedLock lg(ps->core().m_RcvBufferLock); if (m_RcvBaseSeqNo != SRT_SEQNO_NONE) { - const int cnt = ps->core().rcvDropTooLateUpTo(CSeqNo::incseq(m_RcvBaseSeqNo)); + const int cnt = ps->core().rcvDropTooLateUpTo(CSeqNo::incseq(m_RcvBaseSeqNo), CUDT::DROP_DISCARD); if (cnt > 0) { HLOGC(grlog.Debug,