Bugfix: FlexFEC causes retransmit bitrate increase.

When FlexFEC is enabled, sometimes media packet will be recovered by FEC before the actual media packet's arrival. In current implementation this will be considered as packet out of order and nack will be sent, thus cause large increase in retransmit bitrate.
This fix:
1. Avoid sending nack for packet out of order caused by "early" recovered media packets.
2. Save recovered media packet in a set, and do not send nack for these packets.

Bug: None
Change-Id: I008ef4e33668bce6d2cb9ff52b4b5c8e3f349965
Reviewed-on: https://webrtc-review.googlesource.com/c/108090
Commit-Queue: Ying Wang <yinwa@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25444}
This commit is contained in:
Ying Wang
2018-10-31 10:12:27 +01:00
committed by Commit Bot
parent 8b7d206d37
commit b32bb959c9
5 changed files with 89 additions and 47 deletions

View File

@ -40,38 +40,38 @@ class TestNackModule : public ::testing::Test,
};
TEST_F(TestNackModule, NackOnePacket) {
nack_module_.OnReceivedPacket(1, false);
nack_module_.OnReceivedPacket(3, false);
nack_module_.OnReceivedPacket(1, false, false);
nack_module_.OnReceivedPacket(3, false, false);
EXPECT_EQ(1u, sent_nacks_.size());
EXPECT_EQ(2, sent_nacks_[0]);
}
TEST_F(TestNackModule, WrappingSeqNum) {
nack_module_.OnReceivedPacket(0xfffe, false);
nack_module_.OnReceivedPacket(1, false);
nack_module_.OnReceivedPacket(0xfffe, false, false);
nack_module_.OnReceivedPacket(1, false, false);
EXPECT_EQ(2u, sent_nacks_.size());
EXPECT_EQ(0xffff, sent_nacks_[0]);
EXPECT_EQ(0, sent_nacks_[1]);
}
TEST_F(TestNackModule, WrappingSeqNumClearToKeyframe) {
nack_module_.OnReceivedPacket(0xfffe, false);
nack_module_.OnReceivedPacket(1, false);
nack_module_.OnReceivedPacket(0xfffe, false, false);
nack_module_.OnReceivedPacket(1, false, false);
EXPECT_EQ(2u, sent_nacks_.size());
EXPECT_EQ(0xffff, sent_nacks_[0]);
EXPECT_EQ(0, sent_nacks_[1]);
sent_nacks_.clear();
nack_module_.OnReceivedPacket(2, true);
nack_module_.OnReceivedPacket(2, true, false);
EXPECT_EQ(0u, sent_nacks_.size());
nack_module_.OnReceivedPacket(501, true);
nack_module_.OnReceivedPacket(501, true, false);
EXPECT_EQ(498u, sent_nacks_.size());
for (int seq_num = 3; seq_num < 501; ++seq_num)
EXPECT_EQ(seq_num, sent_nacks_[seq_num - 3]);
sent_nacks_.clear();
nack_module_.OnReceivedPacket(1001, false);
nack_module_.OnReceivedPacket(1001, false, false);
EXPECT_EQ(499u, sent_nacks_.size());
for (int seq_num = 502; seq_num < 1001; ++seq_num)
EXPECT_EQ(seq_num, sent_nacks_[seq_num - 502]);
@ -91,7 +91,7 @@ TEST_F(TestNackModule, WrappingSeqNumClearToKeyframe) {
// It will then clear all nacks up to the next keyframe (seq num 2),
// thus removing 0xffff and 0 from the nack list.
sent_nacks_.clear();
nack_module_.OnReceivedPacket(1004, false);
nack_module_.OnReceivedPacket(1004, false, false);
EXPECT_EQ(2u, sent_nacks_.size());
EXPECT_EQ(1002, sent_nacks_[0]);
EXPECT_EQ(1003, sent_nacks_[1]);
@ -107,7 +107,7 @@ TEST_F(TestNackModule, WrappingSeqNumClearToKeyframe) {
// Adding packet 1007 will cause the nack module to overflow again, thus
// clearing everything up to 501 which is the next keyframe.
nack_module_.OnReceivedPacket(1007, false);
nack_module_.OnReceivedPacket(1007, false, false);
sent_nacks_.clear();
clock_->AdvanceTimeMilliseconds(100);
nack_module_.Process();
@ -146,8 +146,8 @@ TEST_F(TestNackModule, DontBurstOnTimeSkip) {
}
TEST_F(TestNackModule, ResendNack) {
nack_module_.OnReceivedPacket(1, false);
nack_module_.OnReceivedPacket(3, false);
nack_module_.OnReceivedPacket(1, false, false);
nack_module_.OnReceivedPacket(3, false, false);
EXPECT_EQ(1u, sent_nacks_.size());
EXPECT_EQ(2, sent_nacks_[0]);
@ -169,15 +169,15 @@ TEST_F(TestNackModule, ResendNack) {
nack_module_.Process();
EXPECT_EQ(4u, sent_nacks_.size());
nack_module_.OnReceivedPacket(2, false);
nack_module_.OnReceivedPacket(2, false, false);
clock_->AdvanceTimeMilliseconds(50);
nack_module_.Process();
EXPECT_EQ(4u, sent_nacks_.size());
}
TEST_F(TestNackModule, ResendPacketMaxRetries) {
nack_module_.OnReceivedPacket(1, false);
nack_module_.OnReceivedPacket(3, false);
nack_module_.OnReceivedPacket(1, false, false);
nack_module_.OnReceivedPacket(3, false, false);
EXPECT_EQ(1u, sent_nacks_.size());
EXPECT_EQ(2, sent_nacks_[0]);
@ -193,35 +193,35 @@ TEST_F(TestNackModule, ResendPacketMaxRetries) {
}
TEST_F(TestNackModule, TooLargeNackList) {
nack_module_.OnReceivedPacket(0, false);
nack_module_.OnReceivedPacket(1001, false);
nack_module_.OnReceivedPacket(0, false, false);
nack_module_.OnReceivedPacket(1001, false, false);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(0, keyframes_requested_);
nack_module_.OnReceivedPacket(1003, false);
nack_module_.OnReceivedPacket(1003, false, false);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(1, keyframes_requested_);
nack_module_.OnReceivedPacket(1004, false);
nack_module_.OnReceivedPacket(1004, false, false);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(1, keyframes_requested_);
}
TEST_F(TestNackModule, TooLargeNackListWithKeyFrame) {
nack_module_.OnReceivedPacket(0, false);
nack_module_.OnReceivedPacket(1, true);
nack_module_.OnReceivedPacket(1001, false);
nack_module_.OnReceivedPacket(0, false, false);
nack_module_.OnReceivedPacket(1, true, false);
nack_module_.OnReceivedPacket(1001, false, false);
EXPECT_EQ(999u, sent_nacks_.size());
EXPECT_EQ(0, keyframes_requested_);
nack_module_.OnReceivedPacket(1003, false);
nack_module_.OnReceivedPacket(1003, false, false);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(0, keyframes_requested_);
nack_module_.OnReceivedPacket(1005, false);
nack_module_.OnReceivedPacket(1005, false, false);
EXPECT_EQ(1000u, sent_nacks_.size());
EXPECT_EQ(1, keyframes_requested_);
}
TEST_F(TestNackModule, ClearUpTo) {
nack_module_.OnReceivedPacket(0, false);
nack_module_.OnReceivedPacket(100, false);
nack_module_.OnReceivedPacket(0, false, false);
nack_module_.OnReceivedPacket(100, false, false);
EXPECT_EQ(99u, sent_nacks_.size());
sent_nacks_.clear();
@ -233,8 +233,8 @@ TEST_F(TestNackModule, ClearUpTo) {
}
TEST_F(TestNackModule, ClearUpToWrap) {
nack_module_.OnReceivedPacket(0xfff0, false);
nack_module_.OnReceivedPacket(0xf, false);
nack_module_.OnReceivedPacket(0xfff0, false, false);
nack_module_.OnReceivedPacket(0xf, false, false);
EXPECT_EQ(30u, sent_nacks_.size());
sent_nacks_.clear();
@ -246,20 +246,20 @@ TEST_F(TestNackModule, ClearUpToWrap) {
}
TEST_F(TestNackModule, PacketNackCount) {
EXPECT_EQ(0, nack_module_.OnReceivedPacket(0, false));
EXPECT_EQ(0, nack_module_.OnReceivedPacket(2, false));
EXPECT_EQ(1, nack_module_.OnReceivedPacket(1, false));
EXPECT_EQ(0, nack_module_.OnReceivedPacket(0, false, false));
EXPECT_EQ(0, nack_module_.OnReceivedPacket(2, false, false));
EXPECT_EQ(1, nack_module_.OnReceivedPacket(1, false, false));
sent_nacks_.clear();
nack_module_.UpdateRtt(100);
EXPECT_EQ(0, nack_module_.OnReceivedPacket(5, false));
EXPECT_EQ(0, nack_module_.OnReceivedPacket(5, false, false));
clock_->AdvanceTimeMilliseconds(100);
nack_module_.Process();
clock_->AdvanceTimeMilliseconds(100);
nack_module_.Process();
EXPECT_EQ(3, nack_module_.OnReceivedPacket(3, false));
EXPECT_EQ(3, nack_module_.OnReceivedPacket(4, false));
EXPECT_EQ(0, nack_module_.OnReceivedPacket(4, false));
EXPECT_EQ(3, nack_module_.OnReceivedPacket(3, false, false));
EXPECT_EQ(3, nack_module_.OnReceivedPacket(4, false, false));
EXPECT_EQ(0, nack_module_.OnReceivedPacket(4, false, false));
}
TEST_F(TestNackModule, NackListFullAndNoOverlapWithKeyframes) {
@ -267,14 +267,22 @@ TEST_F(TestNackModule, NackListFullAndNoOverlapWithKeyframes) {
const unsigned int kFirstGap = kMaxNackPackets - 20;
const unsigned int kSecondGap = 200;
uint16_t seq_num = 0;
nack_module_.OnReceivedPacket(seq_num++, true);
nack_module_.OnReceivedPacket(seq_num++, true, false);
seq_num += kFirstGap;
nack_module_.OnReceivedPacket(seq_num++, true);
nack_module_.OnReceivedPacket(seq_num++, true, false);
EXPECT_EQ(kFirstGap, sent_nacks_.size());
sent_nacks_.clear();
seq_num += kSecondGap;
nack_module_.OnReceivedPacket(seq_num, true);
nack_module_.OnReceivedPacket(seq_num, true, false);
EXPECT_EQ(kSecondGap, sent_nacks_.size());
}
TEST_F(TestNackModule, HandleFecRecoveredPacket) {
nack_module_.OnReceivedPacket(1, false, false);
nack_module_.OnReceivedPacket(4, false, true);
EXPECT_EQ(0u, sent_nacks_.size());
nack_module_.OnReceivedPacket(5, false, false);
EXPECT_EQ(2u, sent_nacks_.size());
}
} // namespace webrtc