xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/nack_tracker_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_coding/neteq/nack_tracker.h"
12 
13 #include <stdint.h>
14 
15 #include <algorithm>
16 #include <memory>
17 
18 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
19 #include "test/field_trial.h"
20 #include "test/gtest.h"
21 
22 namespace webrtc {
23 namespace {
24 
25 const int kSampleRateHz = 16000;
26 const int kPacketSizeMs = 30;
27 const uint32_t kTimestampIncrement = 480;  // 30 ms.
28 const int64_t kShortRoundTripTimeMs = 1;
29 
IsNackListCorrect(const std::vector<uint16_t> & nack_list,const uint16_t * lost_sequence_numbers,size_t num_lost_packets)30 bool IsNackListCorrect(const std::vector<uint16_t>& nack_list,
31                        const uint16_t* lost_sequence_numbers,
32                        size_t num_lost_packets) {
33   if (nack_list.size() != num_lost_packets)
34     return false;
35 
36   if (num_lost_packets == 0)
37     return true;
38 
39   for (size_t k = 0; k < nack_list.size(); ++k) {
40     int seq_num = nack_list[k];
41     bool seq_num_matched = false;
42     for (size_t n = 0; n < num_lost_packets; ++n) {
43       if (seq_num == lost_sequence_numbers[n]) {
44         seq_num_matched = true;
45         break;
46       }
47     }
48     if (!seq_num_matched)
49       return false;
50   }
51   return true;
52 }
53 
54 }  // namespace
55 
TEST(NackTrackerTest,EmptyListWhenNoPacketLoss)56 TEST(NackTrackerTest, EmptyListWhenNoPacketLoss) {
57   NackTracker nack;
58   nack.UpdateSampleRate(kSampleRateHz);
59 
60   int seq_num = 1;
61   uint32_t timestamp = 0;
62 
63   std::vector<uint16_t> nack_list;
64   for (int n = 0; n < 100; n++) {
65     nack.UpdateLastReceivedPacket(seq_num, timestamp);
66     nack_list = nack.GetNackList(kShortRoundTripTimeMs);
67     seq_num++;
68     timestamp += kTimestampIncrement;
69     nack_list = nack.GetNackList(kShortRoundTripTimeMs);
70     EXPECT_TRUE(nack_list.empty());
71   }
72 }
73 
TEST(NackTrackerTest,LatePacketsMovedToNackThenNackListDoesNotChange)74 TEST(NackTrackerTest, LatePacketsMovedToNackThenNackListDoesNotChange) {
75   const uint16_t kSequenceNumberLostPackets[] = {2, 3, 4, 5, 6, 7, 8, 9};
76   static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) /
77                                         sizeof(kSequenceNumberLostPackets[0]);
78 
79   for (int k = 0; k < 2; k++) {  // Two iteration with/without wrap around.
80     NackTracker nack;
81     nack.UpdateSampleRate(kSampleRateHz);
82 
83     uint16_t sequence_num_lost_packets[kNumAllLostPackets];
84     for (int n = 0; n < kNumAllLostPackets; n++) {
85       sequence_num_lost_packets[n] =
86           kSequenceNumberLostPackets[n] +
87           k * 65531;  // Have wrap around in sequence numbers for |k == 1|.
88     }
89     uint16_t seq_num = sequence_num_lost_packets[0] - 1;
90 
91     uint32_t timestamp = 0;
92     std::vector<uint16_t> nack_list;
93 
94     nack.UpdateLastReceivedPacket(seq_num, timestamp);
95     nack_list = nack.GetNackList(kShortRoundTripTimeMs);
96     EXPECT_TRUE(nack_list.empty());
97 
98     seq_num = sequence_num_lost_packets[kNumAllLostPackets - 1] + 1;
99     timestamp += kTimestampIncrement * (kNumAllLostPackets + 1);
100     int num_lost_packets = std::max(0, kNumAllLostPackets);
101 
102     nack.UpdateLastReceivedPacket(seq_num, timestamp);
103     nack_list = nack.GetNackList(kShortRoundTripTimeMs);
104     EXPECT_TRUE(IsNackListCorrect(nack_list, sequence_num_lost_packets,
105                                   num_lost_packets));
106     seq_num++;
107     timestamp += kTimestampIncrement;
108     num_lost_packets++;
109 
110     for (int n = 0; n < 100; ++n) {
111       nack.UpdateLastReceivedPacket(seq_num, timestamp);
112       nack_list = nack.GetNackList(kShortRoundTripTimeMs);
113       EXPECT_TRUE(IsNackListCorrect(nack_list, sequence_num_lost_packets,
114                                     kNumAllLostPackets));
115       seq_num++;
116       timestamp += kTimestampIncrement;
117     }
118   }
119 }
120 
TEST(NackTrackerTest,ArrivedPacketsAreRemovedFromNackList)121 TEST(NackTrackerTest, ArrivedPacketsAreRemovedFromNackList) {
122   const uint16_t kSequenceNumberLostPackets[] = {2, 3, 4, 5, 6, 7, 8, 9};
123   static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) /
124                                         sizeof(kSequenceNumberLostPackets[0]);
125 
126   for (int k = 0; k < 2; ++k) {  // Two iteration with/without wrap around.
127     NackTracker nack;
128     nack.UpdateSampleRate(kSampleRateHz);
129 
130     uint16_t sequence_num_lost_packets[kNumAllLostPackets];
131     for (int n = 0; n < kNumAllLostPackets; ++n) {
132       sequence_num_lost_packets[n] = kSequenceNumberLostPackets[n] +
133                                      k * 65531;  // Wrap around for |k == 1|.
134     }
135 
136     uint16_t seq_num = sequence_num_lost_packets[0] - 1;
137     uint32_t timestamp = 0;
138 
139     nack.UpdateLastReceivedPacket(seq_num, timestamp);
140     std::vector<uint16_t> nack_list = nack.GetNackList(kShortRoundTripTimeMs);
141     EXPECT_TRUE(nack_list.empty());
142 
143     size_t index_retransmitted_rtp = 0;
144     uint32_t timestamp_retransmitted_rtp = timestamp + kTimestampIncrement;
145 
146     seq_num = sequence_num_lost_packets[kNumAllLostPackets - 1] + 1;
147     timestamp += kTimestampIncrement * (kNumAllLostPackets + 1);
148     size_t num_lost_packets = kNumAllLostPackets;
149     for (int n = 0; n < kNumAllLostPackets; ++n) {
150       // Number of lost packets does not change for the first
151       // |kNackThreshold + 1| packets, one is added to the list and one is
152       // removed. Thereafter, the list shrinks every iteration.
153       if (n >= 1)
154         num_lost_packets--;
155 
156       nack.UpdateLastReceivedPacket(seq_num, timestamp);
157       nack_list = nack.GetNackList(kShortRoundTripTimeMs);
158       EXPECT_TRUE(IsNackListCorrect(
159           nack_list, &sequence_num_lost_packets[index_retransmitted_rtp],
160           num_lost_packets));
161       seq_num++;
162       timestamp += kTimestampIncrement;
163 
164       // Retransmission of a lost RTP.
165       nack.UpdateLastReceivedPacket(
166           sequence_num_lost_packets[index_retransmitted_rtp],
167           timestamp_retransmitted_rtp);
168       index_retransmitted_rtp++;
169       timestamp_retransmitted_rtp += kTimestampIncrement;
170 
171       nack_list = nack.GetNackList(kShortRoundTripTimeMs);
172       EXPECT_TRUE(IsNackListCorrect(
173           nack_list, &sequence_num_lost_packets[index_retransmitted_rtp],
174           num_lost_packets - 1));  // One less lost packet in the list.
175     }
176     ASSERT_TRUE(nack_list.empty());
177   }
178 }
179 
180 // Assess if estimation of timestamps and time-to-play is correct. Introduce all
181 // combinations that timestamps and sequence numbers might have wrap around.
TEST(NackTrackerTest,EstimateTimestampAndTimeToPlay)182 TEST(NackTrackerTest, EstimateTimestampAndTimeToPlay) {
183   const uint16_t kLostPackets[] = {2, 3,  4,  5,  6,  7,  8,
184                                    9, 10, 11, 12, 13, 14, 15};
185   static const int kNumAllLostPackets =
186       sizeof(kLostPackets) / sizeof(kLostPackets[0]);
187 
188   for (int k = 0; k < 4; ++k) {
189     NackTracker nack;
190     nack.UpdateSampleRate(kSampleRateHz);
191 
192     // Sequence number wrap around if `k` is 2 or 3;
193     int seq_num_offset = (k < 2) ? 0 : 65531;
194 
195     // Timestamp wrap around if `k` is 1 or 3.
196     uint32_t timestamp_offset =
197         (k & 0x1) ? static_cast<uint32_t>(0xffffffff) - 6 : 0;
198 
199     uint32_t timestamp_lost_packets[kNumAllLostPackets];
200     uint16_t seq_num_lost_packets[kNumAllLostPackets];
201     for (int n = 0; n < kNumAllLostPackets; ++n) {
202       timestamp_lost_packets[n] =
203           timestamp_offset + kLostPackets[n] * kTimestampIncrement;
204       seq_num_lost_packets[n] = seq_num_offset + kLostPackets[n];
205     }
206 
207     // We and to push two packets before lost burst starts.
208     uint16_t seq_num = seq_num_lost_packets[0] - 2;
209     uint32_t timestamp = timestamp_lost_packets[0] - 2 * kTimestampIncrement;
210 
211     const uint16_t first_seq_num = seq_num;
212     const uint32_t first_timestamp = timestamp;
213 
214     // Two consecutive packets to have a correct estimate of timestamp increase.
215     nack.UpdateLastReceivedPacket(seq_num, timestamp);
216     seq_num++;
217     timestamp += kTimestampIncrement;
218     nack.UpdateLastReceivedPacket(seq_num, timestamp);
219 
220     // A packet after the last one which is supposed to be lost.
221     seq_num = seq_num_lost_packets[kNumAllLostPackets - 1] + 1;
222     timestamp =
223         timestamp_lost_packets[kNumAllLostPackets - 1] + kTimestampIncrement;
224     nack.UpdateLastReceivedPacket(seq_num, timestamp);
225 
226     NackTracker::NackList nack_list = nack.GetNackList();
227     EXPECT_EQ(static_cast<size_t>(kNumAllLostPackets), nack_list.size());
228 
229     // Pretend the first packet is decoded.
230     nack.UpdateLastDecodedPacket(first_seq_num, first_timestamp);
231     nack_list = nack.GetNackList();
232 
233     NackTracker::NackList::iterator it = nack_list.begin();
234     while (it != nack_list.end()) {
235       seq_num = it->first - seq_num_offset;
236       int index = seq_num - kLostPackets[0];
237       EXPECT_EQ(timestamp_lost_packets[index], it->second.estimated_timestamp);
238       EXPECT_EQ((index + 2) * kPacketSizeMs, it->second.time_to_play_ms);
239       ++it;
240     }
241 
242     // Pretend 10 ms is passed, and we had pulled audio from NetEq, it still
243     // reports the same sequence number as decoded, time-to-play should be
244     // updated by 10 ms.
245     nack.UpdateLastDecodedPacket(first_seq_num, first_timestamp);
246     nack_list = nack.GetNackList();
247     it = nack_list.begin();
248     while (it != nack_list.end()) {
249       seq_num = it->first - seq_num_offset;
250       int index = seq_num - kLostPackets[0];
251       EXPECT_EQ((index + 2) * kPacketSizeMs - 10, it->second.time_to_play_ms);
252       ++it;
253     }
254   }
255 }
256 
TEST(NackTrackerTest,MissingPacketsPriorToLastDecodedRtpShouldNotBeInNackList)257 TEST(NackTrackerTest,
258      MissingPacketsPriorToLastDecodedRtpShouldNotBeInNackList) {
259   for (int m = 0; m < 2; ++m) {
260     uint16_t seq_num_offset = (m == 0) ? 0 : 65531;  // Wrap around if `m` is 1.
261     NackTracker nack;
262     nack.UpdateSampleRate(kSampleRateHz);
263 
264     // Two consecutive packets to have a correct estimate of timestamp increase.
265     uint16_t seq_num = 0;
266     nack.UpdateLastReceivedPacket(seq_num_offset + seq_num,
267                                   seq_num * kTimestampIncrement);
268     seq_num++;
269     nack.UpdateLastReceivedPacket(seq_num_offset + seq_num,
270                                   seq_num * kTimestampIncrement);
271 
272     // Skip 10 packets (larger than NACK threshold).
273     const int kNumLostPackets = 10;
274     seq_num += kNumLostPackets + 1;
275     nack.UpdateLastReceivedPacket(seq_num_offset + seq_num,
276                                   seq_num * kTimestampIncrement);
277 
278     const size_t kExpectedListSize = kNumLostPackets;
279     std::vector<uint16_t> nack_list = nack.GetNackList(kShortRoundTripTimeMs);
280     EXPECT_EQ(kExpectedListSize, nack_list.size());
281 
282     for (int k = 0; k < 2; ++k) {
283       // Decoding of the first and the second arrived packets.
284       for (int n = 0; n < kPacketSizeMs / 10; ++n) {
285         nack.UpdateLastDecodedPacket(seq_num_offset + k,
286                                      k * kTimestampIncrement);
287         nack_list = nack.GetNackList(kShortRoundTripTimeMs);
288         EXPECT_EQ(kExpectedListSize, nack_list.size());
289       }
290     }
291 
292     // Decoding of the last received packet.
293     nack.UpdateLastDecodedPacket(seq_num + seq_num_offset,
294                                  seq_num * kTimestampIncrement);
295     nack_list = nack.GetNackList(kShortRoundTripTimeMs);
296     EXPECT_TRUE(nack_list.empty());
297 
298     // Make sure list of late packets is also empty. To check that, push few
299     // packets, if the late list is not empty its content will pop up in NACK
300     // list.
301     for (int n = 0; n < 10; ++n) {
302       seq_num++;
303       nack.UpdateLastReceivedPacket(seq_num_offset + seq_num,
304                                     seq_num * kTimestampIncrement);
305       nack_list = nack.GetNackList(kShortRoundTripTimeMs);
306       EXPECT_TRUE(nack_list.empty());
307     }
308   }
309 }
310 
TEST(NackTrackerTest,Reset)311 TEST(NackTrackerTest, Reset) {
312   NackTracker nack;
313   nack.UpdateSampleRate(kSampleRateHz);
314 
315   // Two consecutive packets to have a correct estimate of timestamp increase.
316   uint16_t seq_num = 0;
317   nack.UpdateLastReceivedPacket(seq_num, seq_num * kTimestampIncrement);
318   seq_num++;
319   nack.UpdateLastReceivedPacket(seq_num, seq_num * kTimestampIncrement);
320 
321   // Skip 10 packets (larger than NACK threshold).
322   const int kNumLostPackets = 10;
323   seq_num += kNumLostPackets + 1;
324   nack.UpdateLastReceivedPacket(seq_num, seq_num * kTimestampIncrement);
325 
326   const size_t kExpectedListSize = kNumLostPackets;
327   std::vector<uint16_t> nack_list = nack.GetNackList(kShortRoundTripTimeMs);
328   EXPECT_EQ(kExpectedListSize, nack_list.size());
329 
330   nack.Reset();
331   nack_list = nack.GetNackList(kShortRoundTripTimeMs);
332   EXPECT_TRUE(nack_list.empty());
333 }
334 
TEST(NackTrackerTest,ListSizeAppliedFromBeginning)335 TEST(NackTrackerTest, ListSizeAppliedFromBeginning) {
336   const size_t kNackListSize = 10;
337   for (int m = 0; m < 2; ++m) {
338     uint16_t seq_num_offset = (m == 0) ? 0 : 65525;  // Wrap around if `m` is 1.
339     NackTracker nack;
340     nack.UpdateSampleRate(kSampleRateHz);
341     nack.SetMaxNackListSize(kNackListSize);
342 
343     uint16_t seq_num = seq_num_offset;
344     uint32_t timestamp = 0x12345678;
345     nack.UpdateLastReceivedPacket(seq_num, timestamp);
346 
347     // Packet lost more than NACK-list size limit.
348     uint16_t num_lost_packets = kNackListSize + 5;
349 
350     seq_num += num_lost_packets + 1;
351     timestamp += (num_lost_packets + 1) * kTimestampIncrement;
352     nack.UpdateLastReceivedPacket(seq_num, timestamp);
353 
354     std::vector<uint16_t> nack_list = nack.GetNackList(kShortRoundTripTimeMs);
355     EXPECT_EQ(kNackListSize, nack_list.size());
356   }
357 }
358 
TEST(NackTrackerTest,ChangeOfListSizeAppliedAndOldElementsRemoved)359 TEST(NackTrackerTest, ChangeOfListSizeAppliedAndOldElementsRemoved) {
360   const size_t kNackListSize = 10;
361   for (int m = 0; m < 2; ++m) {
362     uint16_t seq_num_offset = (m == 0) ? 0 : 65525;  // Wrap around if `m` is 1.
363     NackTracker nack;
364     nack.UpdateSampleRate(kSampleRateHz);
365 
366     uint16_t seq_num = seq_num_offset;
367     uint32_t timestamp = 0x87654321;
368     nack.UpdateLastReceivedPacket(seq_num, timestamp);
369 
370     // Packet lost more than NACK-list size limit.
371     uint16_t num_lost_packets = kNackListSize + 5;
372 
373     std::unique_ptr<uint16_t[]> seq_num_lost(new uint16_t[num_lost_packets]);
374     for (int n = 0; n < num_lost_packets; ++n) {
375       seq_num_lost[n] = ++seq_num;
376     }
377 
378     ++seq_num;
379     timestamp += (num_lost_packets + 1) * kTimestampIncrement;
380     nack.UpdateLastReceivedPacket(seq_num, timestamp);
381     size_t expected_size = num_lost_packets;
382 
383     std::vector<uint16_t> nack_list = nack.GetNackList(kShortRoundTripTimeMs);
384     EXPECT_EQ(expected_size, nack_list.size());
385 
386     nack.SetMaxNackListSize(kNackListSize);
387     expected_size = kNackListSize;
388     nack_list = nack.GetNackList(kShortRoundTripTimeMs);
389     EXPECT_TRUE(IsNackListCorrect(
390         nack_list, &seq_num_lost[num_lost_packets - kNackListSize],
391         expected_size));
392 
393     // NACK list should shrink.
394     for (size_t n = 1; n < kNackListSize; ++n) {
395       ++seq_num;
396       timestamp += kTimestampIncrement;
397       nack.UpdateLastReceivedPacket(seq_num, timestamp);
398       --expected_size;
399       nack_list = nack.GetNackList(kShortRoundTripTimeMs);
400       EXPECT_TRUE(IsNackListCorrect(
401           nack_list, &seq_num_lost[num_lost_packets - kNackListSize + n],
402           expected_size));
403     }
404 
405     // After this packet, NACK list should be empty.
406     ++seq_num;
407     timestamp += kTimestampIncrement;
408     nack.UpdateLastReceivedPacket(seq_num, timestamp);
409     nack_list = nack.GetNackList(kShortRoundTripTimeMs);
410     EXPECT_TRUE(nack_list.empty());
411   }
412 }
413 
TEST(NackTrackerTest,RoudTripTimeIsApplied)414 TEST(NackTrackerTest, RoudTripTimeIsApplied) {
415   const int kNackListSize = 200;
416   NackTracker nack;
417   nack.UpdateSampleRate(kSampleRateHz);
418   nack.SetMaxNackListSize(kNackListSize);
419 
420   uint16_t seq_num = 0;
421   uint32_t timestamp = 0x87654321;
422   nack.UpdateLastReceivedPacket(seq_num, timestamp);
423 
424   // Packet lost more than NACK-list size limit.
425   uint16_t kNumLostPackets = 5;
426 
427   seq_num += (1 + kNumLostPackets);
428   timestamp += (1 + kNumLostPackets) * kTimestampIncrement;
429   nack.UpdateLastReceivedPacket(seq_num, timestamp);
430 
431   // Expected time-to-play are:
432   // kPacketSizeMs - 10, 2*kPacketSizeMs - 10, 3*kPacketSizeMs - 10, ...
433   //
434   // sequence number:  1,  2,  3,   4,   5
435   // time-to-play:    20, 50, 80, 110, 140
436   //
437   std::vector<uint16_t> nack_list = nack.GetNackList(100);
438   ASSERT_EQ(2u, nack_list.size());
439   EXPECT_EQ(4, nack_list[0]);
440   EXPECT_EQ(5, nack_list[1]);
441 }
442 
443 // Set never_nack_multiple_times to true with a field trial and verify that
444 // packets are not nacked multiple times.
TEST(NackTrackerTest,DoNotNackMultipleTimes)445 TEST(NackTrackerTest, DoNotNackMultipleTimes) {
446   test::ScopedFieldTrials field_trials(
447       "WebRTC-Audio-NetEqNackTrackerConfig/"
448       "packet_loss_forget_factor:0.996,ms_per_loss_percent:20,"
449       "never_nack_multiple_times:true/");
450   const int kNackListSize = 200;
451   NackTracker nack;
452   nack.UpdateSampleRate(kSampleRateHz);
453   nack.SetMaxNackListSize(kNackListSize);
454 
455   uint16_t seq_num = 0;
456   uint32_t timestamp = 0x87654321;
457   nack.UpdateLastReceivedPacket(seq_num, timestamp);
458 
459   uint16_t kNumLostPackets = 3;
460 
461   seq_num += (1 + kNumLostPackets);
462   timestamp += (1 + kNumLostPackets) * kTimestampIncrement;
463   nack.UpdateLastReceivedPacket(seq_num, timestamp);
464 
465   std::vector<uint16_t> nack_list = nack.GetNackList(10);
466   ASSERT_EQ(3u, nack_list.size());
467   EXPECT_EQ(1, nack_list[0]);
468   EXPECT_EQ(2, nack_list[1]);
469   EXPECT_EQ(3, nack_list[2]);
470   // When we get the nack list again, it should be empty.
471   std::vector<uint16_t> nack_list2 = nack.GetNackList(10);
472   EXPECT_TRUE(nack_list2.empty());
473 }
474 
475 // Test if estimated packet loss rate is correct.
TEST(NackTrackerTest,PacketLossRateCorrect)476 TEST(NackTrackerTest, PacketLossRateCorrect) {
477   const int kNackListSize = 200;
478   NackTracker nack;
479   nack.UpdateSampleRate(kSampleRateHz);
480   nack.SetMaxNackListSize(kNackListSize);
481   uint16_t seq_num = 0;
482   uint32_t timestamp = 0x87654321;
483   auto add_packet = [&nack, &seq_num, &timestamp](bool received) {
484     if (received) {
485       nack.UpdateLastReceivedPacket(seq_num, timestamp);
486     }
487     seq_num++;
488     timestamp += kTimestampIncrement;
489   };
490   // Add some packets, but every fourth packet is lost.
491   for (int i = 0; i < 300; i++) {
492     add_packet(true);
493     add_packet(true);
494     add_packet(true);
495     add_packet(false);
496   }
497   // 1 << 28 is 0.25 in Q30. We expect the packet loss estimate to be within
498   // 0.01 of that.
499   EXPECT_NEAR(nack.GetPacketLossRateForTest(), 1 << 28, (1 << 30) / 100);
500 }
501 
TEST(NackTrackerTest,DoNotNackAfterDtx)502 TEST(NackTrackerTest, DoNotNackAfterDtx) {
503   const int kNackListSize = 200;
504   NackTracker nack;
505   nack.UpdateSampleRate(kSampleRateHz);
506   nack.SetMaxNackListSize(kNackListSize);
507   uint16_t seq_num = 0;
508   uint32_t timestamp = 0x87654321;
509   nack.UpdateLastReceivedPacket(seq_num, timestamp);
510   EXPECT_TRUE(nack.GetNackList(0).empty());
511   constexpr int kDtxPeriod = 400;
512   nack.UpdateLastReceivedPacket(seq_num + 2,
513                                 timestamp + kDtxPeriod * kSampleRateHz / 1000);
514   EXPECT_TRUE(nack.GetNackList(0).empty());
515 }
516 
TEST(NackTrackerTest,DoNotNackIfLossRateIsTooHigh)517 TEST(NackTrackerTest, DoNotNackIfLossRateIsTooHigh) {
518   test::ScopedFieldTrials field_trials(
519       "WebRTC-Audio-NetEqNackTrackerConfig/max_loss_rate:0.4/");
520   const int kNackListSize = 200;
521   NackTracker nack;
522   nack.UpdateSampleRate(kSampleRateHz);
523   nack.SetMaxNackListSize(kNackListSize);
524   uint16_t seq_num = 0;
525   uint32_t timestamp = 0x87654321;
526   auto add_packet = [&nack, &seq_num, &timestamp](bool received) {
527     if (received) {
528       nack.UpdateLastReceivedPacket(seq_num, timestamp);
529     }
530     seq_num++;
531     timestamp += kTimestampIncrement;
532   };
533   for (int i = 0; i < 500; i++) {
534     add_packet(true);
535     add_packet(false);
536   }
537   // Expect 50% loss rate which is higher that the configured maximum 40%.
538   EXPECT_NEAR(nack.GetPacketLossRateForTest(), 1 << 29, (1 << 30) / 100);
539   EXPECT_TRUE(nack.GetNackList(0).empty());
540 }
541 
TEST(NackTrackerTest,OnlyNackIfRttIsValid)542 TEST(NackTrackerTest, OnlyNackIfRttIsValid) {
543   test::ScopedFieldTrials field_trials(
544       "WebRTC-Audio-NetEqNackTrackerConfig/require_valid_rtt:true/");
545   const int kNackListSize = 200;
546   NackTracker nack;
547   nack.UpdateSampleRate(kSampleRateHz);
548   nack.SetMaxNackListSize(kNackListSize);
549   uint16_t seq_num = 0;
550   uint32_t timestamp = 0x87654321;
551   auto add_packet = [&nack, &seq_num, &timestamp](bool received) {
552     if (received) {
553       nack.UpdateLastReceivedPacket(seq_num, timestamp);
554     }
555     seq_num++;
556     timestamp += kTimestampIncrement;
557   };
558   add_packet(true);
559   add_packet(false);
560   add_packet(true);
561   EXPECT_TRUE(nack.GetNackList(0).empty());
562   EXPECT_FALSE(nack.GetNackList(10).empty());
563 }
564 
565 }  // namespace webrtc
566