Change ReceiveStatistics reaction to large sequence numbers jumps

Consider stream restart when two sequential packets arrived far from
previous packets' sequence numbers.
instead of resetting on single one.
For packet loss calculation ignore sequence number gap during reset.

Bug: webrtc:9445, b/38179459
Change-Id: I0c2717ef8f9ec182b280ae757b5582f56d9afcef
Reviewed-on: https://webrtc-review.googlesource.com/c/111962
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25890}
This commit is contained in:
Danil Chapovalov
2018-12-04 12:19:51 +01:00
committed by Commit Bot
parent ee59a17bbb
commit c4f120130f
3 changed files with 295 additions and 61 deletions

View File

@ -295,6 +295,217 @@ TEST_F(ReceiveStatisticsTest, RtcpCallbacks) {
EXPECT_EQ(177u, statistics.jitter);
}
TEST_F(ReceiveStatisticsTest, SimpleLossComputation) {
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(3);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(4);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(5);
receive_statistics_->OnRtpPacket(packet1_);
RtcpStatistics statistics;
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
// 20% = 51/255.
EXPECT_EQ(51u, statistics.fraction_lost);
EXPECT_EQ(1, statistics.packets_lost);
}
TEST_F(ReceiveStatisticsTest, LossComputationWithReordering) {
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(3);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(2);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(5);
receive_statistics_->OnRtpPacket(packet1_);
RtcpStatistics statistics;
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
// 20% = 51/255.
EXPECT_EQ(51u, statistics.fraction_lost);
EXPECT_EQ(1, statistics.packets_lost);
}
TEST_F(ReceiveStatisticsTest, LossComputationWithDuplicates) {
// Lose 2 packets, but also receive 1 duplicate. Should actually count as
// only 1 packet being lost.
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(4);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(4);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(5);
receive_statistics_->OnRtpPacket(packet1_);
RtcpStatistics statistics;
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
// 20% = 51/255.
EXPECT_EQ(51u, statistics.fraction_lost);
EXPECT_EQ(1, statistics.packets_lost);
}
TEST_F(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) {
// First, test loss computation over a period that included a sequence number
// rollover.
packet1_.SetSequenceNumber(0xfffd);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(0);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(0xfffe);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
// Only one packet was actually lost, 0xffff.
RtcpStatistics statistics;
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
// 20% = 51/255.
EXPECT_EQ(51u, statistics.fraction_lost);
EXPECT_EQ(1, statistics.packets_lost);
// Now test losing one packet *after* the rollover.
packet1_.SetSequenceNumber(3);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
// 50% = 127/255.
EXPECT_EQ(127u, statistics.fraction_lost);
EXPECT_EQ(2, statistics.packets_lost);
}
TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(200);
packet1_.SetSequenceNumber(0);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(400);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(0, statistics.fraction_lost);
EXPECT_EQ(0, statistics.packets_lost);
packet1_.SetSequenceNumber(401);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(0, statistics.fraction_lost);
EXPECT_EQ(0, statistics.packets_lost);
}
TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(200);
packet1_.SetSequenceNumber(0);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(400);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(401);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(403);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(1, statistics.packets_lost);
}
TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(200);
packet1_.SetSequenceNumber(0xffff - 401);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(0xffff - 400);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(0xffff);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(0);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(2);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(1, statistics.packets_lost);
}
TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(200);
packet1_.SetSequenceNumber(400);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(401);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(3);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(401u, statistics.extended_highest_sequence_number);
packet1_.SetSequenceNumber(4);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(4u, statistics.extended_highest_sequence_number);
}
TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
RtcpStatistics statistics;
packet1_.SetSequenceNumber(0xffff);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(0xffffu, statistics.extended_highest_sequence_number);
// Wrap around.
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
// Should be treated as out of order; shouldn't increment highest extended
// sequence number.
packet1_.SetSequenceNumber(0x10000 - 6);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
// Receive a couple packets then wrap around again.
receive_statistics_->SetMaxReorderingThreshold(200);
for (int i = 10; i < 0xffff; i += 150) {
packet1_.SetSequenceNumber(i);
receive_statistics_->OnRtpPacket(packet1_);
}
packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true);
EXPECT_EQ(0x20001u, statistics.extended_highest_sequence_number);
}
class RtpTestCallback : public StreamDataCountersCallback {
public:
RtpTestCallback()