tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nack_tracker_unittest.cc (20484B)


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