record loss events when jitter buffer drops packets via high-water mark

The drop loop advanced mLastSeqno one packet at a time silently, so any
real on-wire sequence-number gaps between dropped packets disappeared
from the loss timeline. Now check the gap against the previous mLastSeqno
before each drop and emit a PacketLossEvent if needed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 13:19:14 +03:00
parent dd21bc8c35
commit 84bd523cf5
+26 -2
View File
@@ -200,9 +200,33 @@ RtpBuffer::FetchResult RtpBuffer::fetch()
ICELogMedia( << "Dropping RTP packets from jitter buffer"); ICELogMedia( << "Dropping RTP packets from jitter buffer");
total -= mPacketList.front()->timelength(); total -= mPacketList.front()->timelength();
// Before advancing mLastSeqno over the dropped packet, record a loss event for any
// sequence-number gap on the wire between the previous packet we saw and this one.
// Without this, drops silently mask real packet loss that happened between them.
auto droppingPacket = mPacketList.front();
uint32_t droppingSeq = droppingPacket->rtp()->GetExtendedSequenceNumber();
if (mLastSeqno)
{
int gap = (int64_t)droppingSeq - (int64_t)*mLastSeqno - 1;
if (gap > 0)
{
mStat.mPacketLoss += gap;
if (mStat.mPacketLossTimeline.empty() || (mStat.mPacketLossTimeline.back().mEndSeqno != droppingSeq))
{
auto gapStart = RtpHelper::toMicroseconds(*mLastReceiveTime);
auto gapEnd = RtpHelper::toMicroseconds(droppingPacket->rtp()->GetReceiveTime());
mStat.mPacketLossTimeline.emplace_back(PacketLossEvent{.mStartSeqno = *mLastSeqno,
.mEndSeqno = droppingSeq,
.mGap = gap,
.mTimestampStart = gapStart,
.mTimestampEnd = gapEnd});
}
}
}
// Save it as last packet however - to not confuse loss packet counter // Save it as last packet however - to not confuse loss packet counter
mFetchedPacket = mPacketList.front(); mFetchedPacket = droppingPacket;
mLastSeqno = mFetchedPacket->rtp()->GetExtendedSequenceNumber(); mLastSeqno = droppingSeq;
mLastReceiveTime = mFetchedPacket->rtp()->GetReceiveTime(); mLastReceiveTime = mFetchedPacket->rtp()->GetReceiveTime();
// Erase from packet list // Erase from packet list