Add options to only NACK if there is a valid RTT and if loss rate is below a configured value.

Bug: webrtc:10178
Change-Id: I16a74ed6fb380cecaf82a303bb14bf215c944a73
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/238988
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35419}
This commit is contained in:
Jakob Ivarsson
2021-11-25 15:34:57 +01:00
committed by WebRTC LUCI CQ
parent 144e5bf87d
commit e1bbef1e6b
3 changed files with 72 additions and 11 deletions

View File

@ -32,15 +32,17 @@ NackTracker::Config::Config() {
auto parser = StructParametersParser::Create(
"packet_loss_forget_factor", &packet_loss_forget_factor,
"ms_per_loss_percent", &ms_per_loss_percent, "never_nack_multiple_times",
&never_nack_multiple_times);
&never_nack_multiple_times, "require_valid_rtt", &require_valid_rtt,
"max_loss_rate", &max_loss_rate);
parser->Parse(
webrtc::field_trial::FindFullName(kNackTrackerConfigFieldTrial));
RTC_LOG(LS_INFO) << "Nack tracker config:"
" packet_loss_forget_factor="
<< packet_loss_forget_factor
<< " ms_per_loss_percent=" << ms_per_loss_percent
<< " never_nack_multiple_times="
<< never_nack_multiple_times;
<< " never_nack_multiple_times=" << never_nack_multiple_times
<< " require_valid_rtt=" << require_valid_rtt
<< " max_loss_rate=" << max_loss_rate;
}
NackTracker::NackTracker()
@ -223,6 +225,13 @@ int64_t NackTracker::TimeToPlay(uint32_t timestamp) const {
std::vector<uint16_t> NackTracker::GetNackList(int64_t round_trip_time_ms) {
RTC_DCHECK_GE(round_trip_time_ms, 0);
std::vector<uint16_t> sequence_numbers;
if (config_.require_valid_rtt && round_trip_time_ms == 0) {
return sequence_numbers;
}
if (packet_loss_rate_ >
static_cast<uint32_t>(config_.max_loss_rate * (1 << 30))) {
return sequence_numbers;
}
// The estimated packet loss is between 0 and 1, so we need to multiply by 100
// here.
int max_wait_ms =

View File

@ -109,6 +109,10 @@ class NackTracker {
int ms_per_loss_percent = 20;
// If true, never nack packets more than once.
bool never_nack_multiple_times = false;
// Only nack if the RTT is valid.
bool require_valid_rtt = false;
// Do not nack if the loss rate is above this value.
double max_loss_rate = 1.0;
};
struct NackElement {

View File

@ -480,19 +480,19 @@ TEST(NackTrackerTest, PacketLossRateCorrect) {
nack.SetMaxNackListSize(kNackListSize);
uint16_t seq_num = 0;
uint32_t timestamp = 0x87654321;
auto add_packet = [&nack, &seq_num, &timestamp] {
nack.UpdateLastReceivedPacket(seq_num, timestamp);
auto add_packet = [&nack, &seq_num, &timestamp](bool received) {
if (received) {
nack.UpdateLastReceivedPacket(seq_num, timestamp);
}
seq_num++;
timestamp += kTimestampIncrement;
};
// Add some packets, but every fourth packet is lost.
for (int i = 0; i < 300; i++) {
add_packet();
add_packet();
add_packet();
// The next packet is lost.
seq_num++;
timestamp += kTimestampIncrement;
add_packet(true);
add_packet(true);
add_packet(true);
add_packet(false);
}
// 1 << 28 is 0.25 in Q30. We expect the packet loss estimate to be within
// 0.01 of that.
@ -514,4 +514,52 @@ TEST(NackTrackerTest, DoNotNackAfterDtx) {
EXPECT_TRUE(nack.GetNackList(0).empty());
}
TEST(NackTrackerTest, DoNotNackIfLossRateIsTooHigh) {
test::ScopedFieldTrials field_trials(
"WebRTC-Audio-NetEqNackTrackerConfig/max_loss_rate:0.4/");
const int kNackListSize = 200;
NackTracker nack;
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
uint16_t seq_num = 0;
uint32_t timestamp = 0x87654321;
auto add_packet = [&nack, &seq_num, &timestamp](bool received) {
if (received) {
nack.UpdateLastReceivedPacket(seq_num, timestamp);
}
seq_num++;
timestamp += kTimestampIncrement;
};
for (int i = 0; i < 500; i++) {
add_packet(true);
add_packet(false);
}
// Expect 50% loss rate which is higher that the configured maximum 40%.
EXPECT_NEAR(nack.GetPacketLossRateForTest(), 1 << 29, (1 << 30) / 100);
EXPECT_TRUE(nack.GetNackList(0).empty());
}
TEST(NackTrackerTest, OnlyNackIfRttIsValid) {
test::ScopedFieldTrials field_trials(
"WebRTC-Audio-NetEqNackTrackerConfig/require_valid_rtt:true/");
const int kNackListSize = 200;
NackTracker nack;
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
uint16_t seq_num = 0;
uint32_t timestamp = 0x87654321;
auto add_packet = [&nack, &seq_num, &timestamp](bool received) {
if (received) {
nack.UpdateLastReceivedPacket(seq_num, timestamp);
}
seq_num++;
timestamp += kTimestampIncrement;
};
add_packet(true);
add_packet(false);
add_packet(true);
EXPECT_TRUE(nack.GetNackList(0).empty());
EXPECT_FALSE(nack.GetNackList(10).empty());
}
} // namespace webrtc