/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// Unit tests for PacketBuffer class.

#include "modules/audio_coding/neteq/packet_buffer.h"

#include <memory>

#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/neteq/tick_timer.h"
#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
#include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
#include "modules/audio_coding/neteq/packet.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"

using ::testing::_;
using ::testing::InSequence;
using ::testing::MockFunction;
using ::testing::Return;
using ::testing::StrictMock;

namespace {
class MockEncodedAudioFrame : public webrtc::AudioDecoder::EncodedAudioFrame {
 public:
  MOCK_METHOD(size_t, Duration, (), (const, override));

  MOCK_METHOD(bool, IsDtxPacket, (), (const, override));

  MOCK_METHOD(absl::optional<DecodeResult>,
              Decode,
              (rtc::ArrayView<int16_t> decoded),
              (const, override));
};

// Helper class to generate packets. Packets must be deleted by the user.
class PacketGenerator {
 public:
  PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
  virtual ~PacketGenerator() {}
  void Reset(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
  webrtc::Packet NextPacket(
      int payload_size_bytes,
      std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame);

  uint16_t seq_no_;
  uint32_t ts_;
  uint8_t pt_;
  int frame_size_;
};

PacketGenerator::PacketGenerator(uint16_t seq_no,
                                 uint32_t ts,
                                 uint8_t pt,
                                 int frame_size) {
  Reset(seq_no, ts, pt, frame_size);
}

void PacketGenerator::Reset(uint16_t seq_no,
                            uint32_t ts,
                            uint8_t pt,
                            int frame_size) {
  seq_no_ = seq_no;
  ts_ = ts;
  pt_ = pt;
  frame_size_ = frame_size;
}

webrtc::Packet PacketGenerator::NextPacket(
    int payload_size_bytes,
    std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame) {
  webrtc::Packet packet;
  packet.sequence_number = seq_no_;
  packet.timestamp = ts_;
  packet.payload_type = pt_;
  packet.payload.SetSize(payload_size_bytes);
  ++seq_no_;
  ts_ += frame_size_;
  packet.frame = std::move(audio_frame);
  return packet;
}

struct PacketsToInsert {
  uint16_t sequence_number;
  uint32_t timestamp;
  uint8_t payload_type;
  bool primary;
  // Order of this packet to appear upon extraction, after inserting a series
  // of packets. A negative number means that it should have been discarded
  // before extraction.
  int extract_order;
};

}  // namespace

namespace webrtc {

// Start of test definitions.

TEST(PacketBuffer, CreateAndDestroy) {
  TickTimer tick_timer;
  PacketBuffer* buffer = new PacketBuffer(10, &tick_timer);  // 10 packets.
  EXPECT_TRUE(buffer->Empty());
  delete buffer;
}

TEST(PacketBuffer, InsertPacket) {
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  PacketGenerator gen(17u, 4711u, 0, 10);
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  const int payload_len = 100;
  const Packet packet = gen.NextPacket(payload_len, nullptr);
  EXPECT_EQ(0, buffer.InsertPacket(/*packet=*/packet.Clone(),
                                   /*stats=*/&mock_stats,
                                   /*last_decoded_length=*/payload_len,
                                   /*sample_rate=*/10000,
                                   /*target_level_ms=*/60,
                                   /*decoder_database=*/decoder_database));
  uint32_t next_ts;
  EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
  EXPECT_EQ(4711u, next_ts);
  EXPECT_FALSE(buffer.Empty());
  EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
  const Packet* next_packet = buffer.PeekNextPacket();
  EXPECT_EQ(packet, *next_packet);       // Compare contents.
  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.

  // Do not explicitly flush buffer or delete packet to test that it is deleted
  // with the buffer. (Tested with Valgrind or similar tool.)
}

// Test to flush buffer.
TEST(PacketBuffer, FlushBuffer) {
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  PacketGenerator gen(0, 0, 0, 10);
  const int payload_len = 10;
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  // Insert 10 small packets; should be ok.
  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(
        PacketBuffer::kOK,
        buffer.InsertPacket(/*packet=*/gen.NextPacket(payload_len, nullptr),
                            /*stats=*/&mock_stats,
                            /*last_decoded_length=*/payload_len,
                            /*sample_rate=*/1000,
                            /*target_level_ms=*/60,
                            /*decoder_database=*/decoder_database));
  }
  EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
  EXPECT_FALSE(buffer.Empty());

  EXPECT_CALL(mock_stats, PacketsDiscarded(1)).Times(10);
  buffer.Flush(&mock_stats);
  // Buffer should delete the payloads itself.
  EXPECT_EQ(0u, buffer.NumPacketsInBuffer());
  EXPECT_TRUE(buffer.Empty());
  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

// Test to fill the buffer over the limits, and verify that it flushes.
TEST(PacketBuffer, OverfillBuffer) {
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  PacketGenerator gen(0, 0, 0, 10);
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  // Insert 10 small packets; should be ok.
  const int payload_len = 10;
  int i;
  for (i = 0; i < 10; ++i) {
    EXPECT_EQ(
        PacketBuffer::kOK,
        buffer.InsertPacket(/*packet=*/gen.NextPacket(payload_len, nullptr),
                            /*stats=*/&mock_stats,
                            /*last_decoded_length=*/payload_len,
                            /*sample_rate=*/1000,
                            /*target_level_ms=*/60,
                            /*decoder_database=*/decoder_database));
  }
  EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
  uint32_t next_ts;
  EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
  EXPECT_EQ(0u, next_ts);  // Expect first inserted packet to be first in line.

  EXPECT_CALL(mock_stats, PacketsDiscarded(1)).Times(10);
  const Packet packet = gen.NextPacket(payload_len, nullptr);
  // Insert 11th packet; should flush the buffer and insert it after flushing.
  EXPECT_EQ(PacketBuffer::kFlushed,
            buffer.InsertPacket(/*packet=*/packet.Clone(),
                                /*stats=*/&mock_stats,
                                /*last_decoded_length=*/payload_len,
                                /*sample_rate=*/1000,
                                /*target_level_ms=*/60,
                                /*decoder_database=*/decoder_database));
  EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
  EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
  // Expect last inserted packet to be first in line.
  EXPECT_EQ(packet.timestamp, next_ts);

  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

// Test a partial buffer flush.
TEST(PacketBuffer, PartialFlush) {
  // Use a field trial to configure smart flushing.
  test::ScopedFieldTrials field_trials(
      "WebRTC-Audio-NetEqSmartFlushing/enabled:true,"
      "target_level_threshold_ms:0,target_level_multiplier:2/");
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  PacketGenerator gen(0, 0, 0, 10);
  const int payload_len = 10;
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  // Insert 10 small packets; should be ok.
  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(
        PacketBuffer::kOK,
        buffer.InsertPacket(/*packet=*/gen.NextPacket(payload_len, nullptr),
                            /*stats=*/&mock_stats,
                            /*last_decoded_length=*/payload_len,
                            /*sample_rate=*/1000,
                            /*target_level_ms=*/100,
                            /*decoder_database=*/decoder_database));
  }
  EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
  EXPECT_FALSE(buffer.Empty());

  EXPECT_CALL(mock_stats, PacketsDiscarded(1)).Times(7);
  buffer.PartialFlush(/*target_level_ms=*/30,
                      /*sample_rate=*/1000,
                      /*last_decoded_length=*/payload_len,
                      /*stats=*/&mock_stats);
  // There should still be some packets left in the buffer.
  EXPECT_EQ(3u, buffer.NumPacketsInBuffer());
  EXPECT_FALSE(buffer.Empty());
  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

// Test to fill the buffer over the limits, and verify that the smart flush
// functionality works as expected.
TEST(PacketBuffer, SmartFlushOverfillBuffer) {
  // Use a field trial to configure smart flushing.
  test::ScopedFieldTrials field_trials(
      "WebRTC-Audio-NetEqSmartFlushing/enabled:true,"
      "target_level_threshold_ms:0,target_level_multiplier:2/");
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  PacketGenerator gen(0, 0, 0, 10);
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  // Insert 10 small packets; should be ok.
  const int payload_len = 10;
  int i;
  for (i = 0; i < 10; ++i) {
    EXPECT_EQ(
        PacketBuffer::kOK,
        buffer.InsertPacket(/*packet=*/gen.NextPacket(payload_len, nullptr),
                            /*stats=*/&mock_stats,
                            /*last_decoded_length=*/payload_len,
                            /*sample_rate=*/1000,
                            /*target_level_ms=*/100,
                            /*decoder_database=*/decoder_database));
  }
  EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
  uint32_t next_ts;
  EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
  EXPECT_EQ(0u, next_ts);  // Expect first inserted packet to be first in line.

  const Packet packet = gen.NextPacket(payload_len, nullptr);
  EXPECT_CALL(mock_stats, PacketsDiscarded(1)).Times(6);
  // Insert 11th packet; should cause a partial flush and insert the packet
  // after flushing.
  EXPECT_EQ(PacketBuffer::kPartialFlush,
            buffer.InsertPacket(/*packet=*/packet.Clone(),
                                /*stats=*/&mock_stats,
                                /*last_decoded_length=*/payload_len,
                                /*sample_rate=*/1000,
                                /*target_level_ms=*/40,
                                /*decoder_database=*/decoder_database));
  EXPECT_EQ(5u, buffer.NumPacketsInBuffer());
  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

// Test inserting a list of packets.
TEST(PacketBuffer, InsertPacketList) {
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  PacketGenerator gen(0, 0, 0, 10);
  PacketList list;
  const int payload_len = 10;

  // Insert 10 small packets.
  for (int i = 0; i < 10; ++i) {
    list.push_back(gen.NextPacket(payload_len, nullptr));
  }

  MockDecoderDatabase decoder_database;
  auto factory = CreateBuiltinAudioDecoderFactory();
  const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
                                          absl::nullopt, factory.get());
  EXPECT_CALL(decoder_database, GetDecoderInfo(0))
      .WillRepeatedly(Return(&info));

  StrictMock<MockStatisticsCalculator> mock_stats;

  absl::optional<uint8_t> current_pt;
  absl::optional<uint8_t> current_cng_pt;
  EXPECT_EQ(
      PacketBuffer::kOK,
      buffer.InsertPacketList(/*packet_list=*/&list,
                              /*decoder_database=*/decoder_database,
                              /*current_rtp_payload_type=*/&current_pt,
                              /*current_cng_rtp_payload_type=*/&current_cng_pt,
                              /*stats=*/&mock_stats,
                              /*last_decoded_length=*/payload_len,
                              /*sample_rate=*/1000,
                              /*target_level_ms=*/30));
  EXPECT_TRUE(list.empty());  // The PacketBuffer should have depleted the list.
  EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
  EXPECT_EQ(0, current_pt);  // Current payload type changed to 0.
  EXPECT_EQ(absl::nullopt, current_cng_pt);  // CNG payload type not changed.

  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

// Test inserting a list of packets. Last packet is of a different payload type.
// Expecting the buffer to flush.
// TODO(hlundin): Remove this test when legacy operation is no longer needed.
TEST(PacketBuffer, InsertPacketListChangePayloadType) {
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  PacketGenerator gen(0, 0, 0, 10);
  PacketList list;
  const int payload_len = 10;

  // Insert 10 small packets.
  for (int i = 0; i < 10; ++i) {
    list.push_back(gen.NextPacket(payload_len, nullptr));
  }
  // Insert 11th packet of another payload type (not CNG).
  {
    Packet packet = gen.NextPacket(payload_len, nullptr);
    packet.payload_type = 1;
    list.push_back(std::move(packet));
  }

  MockDecoderDatabase decoder_database;
  auto factory = CreateBuiltinAudioDecoderFactory();
  const DecoderDatabase::DecoderInfo info0(SdpAudioFormat("pcmu", 8000, 1),
                                           absl::nullopt, factory.get());
  EXPECT_CALL(decoder_database, GetDecoderInfo(0))
      .WillRepeatedly(Return(&info0));
  const DecoderDatabase::DecoderInfo info1(SdpAudioFormat("pcma", 8000, 1),
                                           absl::nullopt, factory.get());
  EXPECT_CALL(decoder_database, GetDecoderInfo(1))
      .WillRepeatedly(Return(&info1));

  StrictMock<MockStatisticsCalculator> mock_stats;

  absl::optional<uint8_t> current_pt;
  absl::optional<uint8_t> current_cng_pt;
  EXPECT_CALL(mock_stats, PacketsDiscarded(1)).Times(10);
  EXPECT_EQ(
      PacketBuffer::kFlushed,
      buffer.InsertPacketList(/*packet_list=*/&list,
                              /*decoder_database=*/decoder_database,
                              /*current_rtp_payload_type=*/&current_pt,
                              /*current_cng_rtp_payload_type=*/&current_cng_pt,
                              /*stats=*/&mock_stats,
                              /*last_decoded_length=*/payload_len,
                              /*sample_rate=*/1000,
                              /*target_level_ms=*/30));
  EXPECT_TRUE(list.empty());  // The PacketBuffer should have depleted the list.
  EXPECT_EQ(1u, buffer.NumPacketsInBuffer());  // Only the last packet.
  EXPECT_EQ(1, current_pt);  // Current payload type changed to 1.
  EXPECT_EQ(absl::nullopt, current_cng_pt);  // CNG payload type not changed.

  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

TEST(PacketBuffer, ExtractOrderRedundancy) {
  TickTimer tick_timer;
  PacketBuffer buffer(100, &tick_timer);  // 100 packets.
  const int kPackets = 18;
  const int kFrameSize = 10;
  const int kPayloadLength = 10;

  PacketsToInsert packet_facts[kPackets] = {
      {0xFFFD, 0xFFFFFFD7, 0, true, 0},   {0xFFFE, 0xFFFFFFE1, 0, true, 1},
      {0xFFFE, 0xFFFFFFD7, 1, false, -1}, {0xFFFF, 0xFFFFFFEB, 0, true, 2},
      {0xFFFF, 0xFFFFFFE1, 1, false, -1}, {0x0000, 0xFFFFFFF5, 0, true, 3},
      {0x0000, 0xFFFFFFEB, 1, false, -1}, {0x0001, 0xFFFFFFFF, 0, true, 4},
      {0x0001, 0xFFFFFFF5, 1, false, -1}, {0x0002, 0x0000000A, 0, true, 5},
      {0x0002, 0xFFFFFFFF, 1, false, -1}, {0x0003, 0x0000000A, 1, false, -1},
      {0x0004, 0x0000001E, 0, true, 7},   {0x0004, 0x00000014, 1, false, 6},
      {0x0005, 0x0000001E, 0, true, -1},  {0x0005, 0x00000014, 1, false, -1},
      {0x0006, 0x00000028, 0, true, 8},   {0x0006, 0x0000001E, 1, false, -1},
  };
  MockDecoderDatabase decoder_database;

  const size_t kExpectPacketsInBuffer = 9;

  std::vector<Packet> expect_order(kExpectPacketsInBuffer);

  PacketGenerator gen(0, 0, 0, kFrameSize);

  StrictMock<MockStatisticsCalculator> mock_stats;

  // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
  // check ensures that exactly one call to PacketsDiscarded happens in each
  // DiscardNextPacket call.
  InSequence s;
  MockFunction<void(int check_point_id)> check;
  for (int i = 0; i < kPackets; ++i) {
    gen.Reset(packet_facts[i].sequence_number, packet_facts[i].timestamp,
              packet_facts[i].payload_type, kFrameSize);
    Packet packet = gen.NextPacket(kPayloadLength, nullptr);
    packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
    if (packet_facts[i].extract_order < 0) {
      if (packet.priority.codec_level > 0) {
        EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
      } else {
        EXPECT_CALL(mock_stats, PacketsDiscarded(1));
      }
    }
    EXPECT_CALL(check, Call(i));
    EXPECT_EQ(PacketBuffer::kOK,
              buffer.InsertPacket(/*packet=*/packet.Clone(),
                                  /*stats=*/&mock_stats,
                                  /*last_decoded_length=*/kPayloadLength,
                                  /*sample_rate=*/1000,
                                  /*target_level_ms=*/60,
                                  /*decoder_database=*/decoder_database));
    if (packet_facts[i].extract_order >= 0) {
      expect_order[packet_facts[i].extract_order] = std::move(packet);
    }
    check.Call(i);
  }

  EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());

  for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
    const absl::optional<Packet> packet = buffer.GetNextPacket();
    EXPECT_EQ(packet, expect_order[i]);  // Compare contents.
  }
  EXPECT_TRUE(buffer.Empty());
  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

TEST(PacketBuffer, DiscardPackets) {
  TickTimer tick_timer;
  PacketBuffer buffer(100, &tick_timer);  // 100 packets.
  const uint16_t start_seq_no = 17;
  const uint32_t start_ts = 4711;
  const uint32_t ts_increment = 10;
  PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
  PacketList list;
  const int payload_len = 10;
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  constexpr int kTotalPackets = 10;
  // Insert 10 small packets.
  for (int i = 0; i < kTotalPackets; ++i) {
    buffer.InsertPacket(/*packet=*/gen.NextPacket(payload_len, nullptr),
                        /*stats=*/&mock_stats,
                        /*last_decoded_length=*/payload_len,
                        /*sample_rate=*/1000,
                        /*target_level_ms=*/60,
                        /*decoder_database=*/decoder_database);
  }
  EXPECT_EQ(10u, buffer.NumPacketsInBuffer());

  uint32_t current_ts = start_ts;

  // Discard them one by one and make sure that the right packets are at the
  // front of the buffer.
  constexpr int kDiscardPackets = 5;

  // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
  // check ensures that exactly one call to PacketsDiscarded happens in each
  // DiscardNextPacket call.
  InSequence s;
  MockFunction<void(int check_point_id)> check;
  for (int i = 0; i < kDiscardPackets; ++i) {
    uint32_t ts;
    EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
    EXPECT_EQ(current_ts, ts);
    EXPECT_CALL(mock_stats, PacketsDiscarded(1));
    EXPECT_CALL(check, Call(i));
    EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
    current_ts += ts_increment;
    check.Call(i);
  }

  constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
  // This will discard all remaining packets but one. The oldest packet is older
  // than the indicated horizon_samples, and will thus be left in the buffer.
  constexpr size_t kSkipPackets = 1;
  EXPECT_CALL(mock_stats, PacketsDiscarded(1))
      .Times(kRemainingPackets - kSkipPackets);
  EXPECT_CALL(check, Call(17));  // Arbitrary id number.
  buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
                           kRemainingPackets * ts_increment, &mock_stats);
  check.Call(17);  // Same arbitrary id number.

  EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
  uint32_t ts;
  EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
  EXPECT_EQ(current_ts, ts);

  // Discard all remaining packets.
  EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
  buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
                              &mock_stats);

  EXPECT_TRUE(buffer.Empty());
  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

TEST(PacketBuffer, Reordering) {
  TickTimer tick_timer;
  PacketBuffer buffer(100, &tick_timer);  // 100 packets.
  const uint16_t start_seq_no = 17;
  const uint32_t start_ts = 4711;
  const uint32_t ts_increment = 10;
  PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
  const int payload_len = 10;

  // Generate 10 small packets and insert them into a PacketList. Insert every
  // odd packet to the front, and every even packet to the back, thus creating
  // a (rather strange) reordering.
  PacketList list;
  for (int i = 0; i < 10; ++i) {
    Packet packet = gen.NextPacket(payload_len, nullptr);
    if (i % 2) {
      list.push_front(std::move(packet));
    } else {
      list.push_back(std::move(packet));
    }
  }

  MockDecoderDatabase decoder_database;
  auto factory = CreateBuiltinAudioDecoderFactory();
  const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
                                          absl::nullopt, factory.get());
  EXPECT_CALL(decoder_database, GetDecoderInfo(0))
      .WillRepeatedly(Return(&info));
  absl::optional<uint8_t> current_pt;
  absl::optional<uint8_t> current_cng_pt;

  StrictMock<MockStatisticsCalculator> mock_stats;

  EXPECT_EQ(
      PacketBuffer::kOK,
      buffer.InsertPacketList(/*packet_list=*/&list,
                              /*decoder_database=*/decoder_database,
                              /*current_rtp_payload_type=*/&current_pt,
                              /*current_cng_rtp_payload_type=*/&current_cng_pt,
                              /*stats=*/&mock_stats,
                              /*last_decoded_length=*/payload_len,
                              /*sample_rate=*/1000,
                              /*target_level_ms=*/30));
  EXPECT_EQ(10u, buffer.NumPacketsInBuffer());

  // Extract them and make sure that come out in the right order.
  uint32_t current_ts = start_ts;
  for (int i = 0; i < 10; ++i) {
    const absl::optional<Packet> packet = buffer.GetNextPacket();
    ASSERT_TRUE(packet);
    EXPECT_EQ(current_ts, packet->timestamp);
    current_ts += ts_increment;
  }
  EXPECT_TRUE(buffer.Empty());

  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

// The test first inserts a packet with narrow-band CNG, then a packet with
// wide-band speech. The expected behavior of the packet buffer is to detect a
// change in sample rate, even though no speech packet has been inserted before,
// and flush out the CNG packet.
TEST(PacketBuffer, CngFirstThenSpeechWithNewSampleRate) {
  TickTimer tick_timer;
  PacketBuffer buffer(10, &tick_timer);  // 10 packets.
  const uint8_t kCngPt = 13;
  const int kPayloadLen = 10;
  const uint8_t kSpeechPt = 100;

  MockDecoderDatabase decoder_database;
  auto factory = CreateBuiltinAudioDecoderFactory();
  const DecoderDatabase::DecoderInfo info_cng(SdpAudioFormat("cn", 8000, 1),
                                              absl::nullopt, factory.get());
  EXPECT_CALL(decoder_database, GetDecoderInfo(kCngPt))
      .WillRepeatedly(Return(&info_cng));
  const DecoderDatabase::DecoderInfo info_speech(
      SdpAudioFormat("l16", 16000, 1), absl::nullopt, factory.get());
  EXPECT_CALL(decoder_database, GetDecoderInfo(kSpeechPt))
      .WillRepeatedly(Return(&info_speech));

  // Insert first packet, which is narrow-band CNG.
  PacketGenerator gen(0, 0, kCngPt, 10);
  PacketList list;
  list.push_back(gen.NextPacket(kPayloadLen, nullptr));
  absl::optional<uint8_t> current_pt;
  absl::optional<uint8_t> current_cng_pt;

  StrictMock<MockStatisticsCalculator> mock_stats;

  EXPECT_EQ(
      PacketBuffer::kOK,
      buffer.InsertPacketList(/*packet_list=*/&list,
                              /*decoder_database=*/decoder_database,
                              /*current_rtp_payload_type=*/&current_pt,
                              /*current_cng_rtp_payload_type=*/&current_cng_pt,
                              /*stats=*/&mock_stats,
                              /*last_decoded_length=*/kPayloadLen,
                              /*sample_rate=*/1000,
                              /*target_level_ms=*/30));
  EXPECT_TRUE(list.empty());
  EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
  ASSERT_TRUE(buffer.PeekNextPacket());
  EXPECT_EQ(kCngPt, buffer.PeekNextPacket()->payload_type);
  EXPECT_EQ(current_pt, absl::nullopt);  // Current payload type not set.
  EXPECT_EQ(kCngPt, current_cng_pt);     // CNG payload type set.

  // Insert second packet, which is wide-band speech.
  {
    Packet packet = gen.NextPacket(kPayloadLen, nullptr);
    packet.payload_type = kSpeechPt;
    list.push_back(std::move(packet));
  }
  // Expect the buffer to flush out the CNG packet, since it does not match the
  // new speech sample rate.
  EXPECT_CALL(mock_stats, PacketsDiscarded(1));
  EXPECT_EQ(
      PacketBuffer::kFlushed,
      buffer.InsertPacketList(/*packet_list=*/&list,
                              /*decoder_database=*/decoder_database,
                              /*current_rtp_payload_type=*/&current_pt,
                              /*current_cng_rtp_payload_type=*/&current_cng_pt,
                              /*stats=*/&mock_stats,
                              /*last_decoded_length=*/kPayloadLen,
                              /*sample_rate=*/1000,
                              /*target_level_ms=*/30));
  EXPECT_TRUE(list.empty());
  EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
  ASSERT_TRUE(buffer.PeekNextPacket());
  EXPECT_EQ(kSpeechPt, buffer.PeekNextPacket()->payload_type);

  EXPECT_EQ(kSpeechPt, current_pt);          // Current payload type set.
  EXPECT_EQ(absl::nullopt, current_cng_pt);  // CNG payload type reset.

  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

TEST(PacketBuffer, Failures) {
  const uint16_t start_seq_no = 17;
  const uint32_t start_ts = 4711;
  const uint32_t ts_increment = 10;
  int payload_len = 100;
  PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
  TickTimer tick_timer;
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  PacketBuffer* buffer = new PacketBuffer(100, &tick_timer);  // 100 packets.
  {
    Packet packet = gen.NextPacket(payload_len, nullptr);
    packet.payload.Clear();
    EXPECT_EQ(PacketBuffer::kInvalidPacket,
              buffer->InsertPacket(/*packet=*/std::move(packet),
                                   /*stats=*/&mock_stats,
                                   /*last_decoded_length=*/payload_len,
                                   /*sample_rate=*/1000,
                                   /*target_level_ms=*/60,
                                   /*decoder_database=*/decoder_database));
  }
  // Buffer should still be empty. Test all empty-checks.
  uint32_t temp_ts;
  EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->NextTimestamp(&temp_ts));
  EXPECT_EQ(PacketBuffer::kBufferEmpty,
            buffer->NextHigherTimestamp(0, &temp_ts));
  EXPECT_EQ(NULL, buffer->PeekNextPacket());
  EXPECT_FALSE(buffer->GetNextPacket());

  // Discarding packets will not invoke mock_stats.PacketDiscarded() because the
  // packet buffer is empty.
  EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket(&mock_stats));
  buffer->DiscardAllOldPackets(0, &mock_stats);

  // Insert one packet to make the buffer non-empty.
  EXPECT_EQ(
      PacketBuffer::kOK,
      buffer->InsertPacket(/*packet=*/gen.NextPacket(payload_len, nullptr),
                           /*stats=*/&mock_stats,
                           /*last_decoded_length=*/payload_len,
                           /*sample_rate=*/1000,
                           /*target_level_ms=*/60,
                           /*decoder_database=*/decoder_database));
  EXPECT_EQ(PacketBuffer::kInvalidPointer, buffer->NextTimestamp(NULL));
  EXPECT_EQ(PacketBuffer::kInvalidPointer,
            buffer->NextHigherTimestamp(0, NULL));
  delete buffer;

  // Insert packet list of three packets, where the second packet has an invalid
  // payload.  Expect first packet to be inserted, and the remaining two to be
  // discarded.
  buffer = new PacketBuffer(100, &tick_timer);  // 100 packets.
  PacketList list;
  list.push_back(gen.NextPacket(payload_len, nullptr));  // Valid packet.
  {
    Packet packet = gen.NextPacket(payload_len, nullptr);
    packet.payload.Clear();  // Invalid.
    list.push_back(std::move(packet));
  }
  list.push_back(gen.NextPacket(payload_len, nullptr));  // Valid packet.
  auto factory = CreateBuiltinAudioDecoderFactory();
  const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
                                          absl::nullopt, factory.get());
  EXPECT_CALL(decoder_database, GetDecoderInfo(0))
      .WillRepeatedly(Return(&info));
  absl::optional<uint8_t> current_pt;
  absl::optional<uint8_t> current_cng_pt;
  EXPECT_EQ(
      PacketBuffer::kInvalidPacket,
      buffer->InsertPacketList(/*packet_list=*/&list,
                               /*decoder_database=*/decoder_database,
                               /*current_rtp_payload_type=*/&current_pt,
                               /*current_cng_rtp_payload_type=*/&current_cng_pt,
                               /*stats=*/&mock_stats,
                               /*last_decoded_length=*/payload_len,
                               /*sample_rate=*/1000,
                               /*target_level_ms=*/30));
  EXPECT_TRUE(list.empty());  // The PacketBuffer should have depleted the list.
  EXPECT_EQ(1u, buffer->NumPacketsInBuffer());
  delete buffer;
  EXPECT_CALL(decoder_database, Die());  // Called when object is deleted.
}

// Test packet comparison function.
// The function should return true if the first packet "goes before" the second.
TEST(PacketBuffer, ComparePackets) {
  PacketGenerator gen(0, 0, 0, 10);
  Packet a(gen.NextPacket(10, nullptr));  // SN = 0, TS = 0.
  Packet b(gen.NextPacket(10, nullptr));  // SN = 1, TS = 10.
  EXPECT_FALSE(a == b);
  EXPECT_TRUE(a != b);
  EXPECT_TRUE(a < b);
  EXPECT_FALSE(a > b);
  EXPECT_TRUE(a <= b);
  EXPECT_FALSE(a >= b);

  // Testing wrap-around case; 'a' is earlier but has a larger timestamp value.
  a.timestamp = 0xFFFFFFFF - 10;
  EXPECT_FALSE(a == b);
  EXPECT_TRUE(a != b);
  EXPECT_TRUE(a < b);
  EXPECT_FALSE(a > b);
  EXPECT_TRUE(a <= b);
  EXPECT_FALSE(a >= b);

  // Test equal packets.
  EXPECT_TRUE(a == a);
  EXPECT_FALSE(a != a);
  EXPECT_FALSE(a < a);
  EXPECT_FALSE(a > a);
  EXPECT_TRUE(a <= a);
  EXPECT_TRUE(a >= a);

  // Test equal timestamps but different sequence numbers (0 and 1).
  a.timestamp = b.timestamp;
  EXPECT_FALSE(a == b);
  EXPECT_TRUE(a != b);
  EXPECT_TRUE(a < b);
  EXPECT_FALSE(a > b);
  EXPECT_TRUE(a <= b);
  EXPECT_FALSE(a >= b);

  // Test equal timestamps but different sequence numbers (32767 and 1).
  a.sequence_number = 0xFFFF;
  EXPECT_FALSE(a == b);
  EXPECT_TRUE(a != b);
  EXPECT_TRUE(a < b);
  EXPECT_FALSE(a > b);
  EXPECT_TRUE(a <= b);
  EXPECT_FALSE(a >= b);

  // Test equal timestamps and sequence numbers, but differing priorities.
  a.sequence_number = b.sequence_number;
  a.priority = {1, 0};
  b.priority = {0, 0};
  // a after b
  EXPECT_FALSE(a == b);
  EXPECT_TRUE(a != b);
  EXPECT_FALSE(a < b);
  EXPECT_TRUE(a > b);
  EXPECT_FALSE(a <= b);
  EXPECT_TRUE(a >= b);

  Packet c(gen.NextPacket(0, nullptr));  // SN = 2, TS = 20.
  Packet d(gen.NextPacket(0, nullptr));  // SN = 3, TS = 20.
  c.timestamp = b.timestamp;
  d.timestamp = b.timestamp;
  c.sequence_number = b.sequence_number;
  d.sequence_number = b.sequence_number;
  c.priority = {1, 1};
  d.priority = {0, 1};
  // c after d
  EXPECT_FALSE(c == d);
  EXPECT_TRUE(c != d);
  EXPECT_FALSE(c < d);
  EXPECT_TRUE(c > d);
  EXPECT_FALSE(c <= d);
  EXPECT_TRUE(c >= d);

  // c after a
  EXPECT_FALSE(c == a);
  EXPECT_TRUE(c != a);
  EXPECT_FALSE(c < a);
  EXPECT_TRUE(c > a);
  EXPECT_FALSE(c <= a);
  EXPECT_TRUE(c >= a);

  // c after b
  EXPECT_FALSE(c == b);
  EXPECT_TRUE(c != b);
  EXPECT_FALSE(c < b);
  EXPECT_TRUE(c > b);
  EXPECT_FALSE(c <= b);
  EXPECT_TRUE(c >= b);

  // a after d
  EXPECT_FALSE(a == d);
  EXPECT_TRUE(a != d);
  EXPECT_FALSE(a < d);
  EXPECT_TRUE(a > d);
  EXPECT_FALSE(a <= d);
  EXPECT_TRUE(a >= d);

  // d after b
  EXPECT_FALSE(d == b);
  EXPECT_TRUE(d != b);
  EXPECT_FALSE(d < b);
  EXPECT_TRUE(d > b);
  EXPECT_FALSE(d <= b);
  EXPECT_TRUE(d >= b);
}

TEST(PacketBuffer, GetSpanSamples) {
  constexpr size_t kFrameSizeSamples = 10;
  constexpr int kPayloadSizeBytes = 1;  // Does not matter to this test;
  constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE;  // Close to wrap around.
  constexpr int kSampleRateHz = 48000;
  constexpr bool kCountWaitingTime = false;
  TickTimer tick_timer;
  PacketBuffer buffer(3, &tick_timer);
  PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples);
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  Packet packet_1 = gen.NextPacket(kPayloadSizeBytes, nullptr);

  std::unique_ptr<MockEncodedAudioFrame> mock_audio_frame =
      std::make_unique<MockEncodedAudioFrame>();
  EXPECT_CALL(*mock_audio_frame, Duration())
      .WillRepeatedly(Return(kFrameSizeSamples));
  Packet packet_2 =
      gen.NextPacket(kPayloadSizeBytes, std::move(mock_audio_frame));

  RTC_DCHECK_GT(packet_1.timestamp,
                packet_2.timestamp);  // Tmestamp wrapped around.

  EXPECT_EQ(PacketBuffer::kOK,
            buffer.InsertPacket(/*packet=*/std::move(packet_1),
                                /*stats=*/&mock_stats,
                                /*last_decoded_length=*/kFrameSizeSamples,
                                /*sample_rate=*/1000,
                                /*target_level_ms=*/60,
                                /*decoder_database=*/decoder_database));

  constexpr size_t kLastDecodedSizeSamples = 2;
  // packet_1 has no access to duration, and relies last decoded duration as
  // input.
  EXPECT_EQ(kLastDecodedSizeSamples,
            buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
                                  kCountWaitingTime));

  EXPECT_EQ(PacketBuffer::kOK,
            buffer.InsertPacket(/*packet=*/std::move(packet_2),
                                /*stats=*/&mock_stats,
                                /*last_decoded_length=*/kFrameSizeSamples,
                                /*sample_rate=*/1000,
                                /*target_level_ms=*/60,
                                /*decoder_database=*/decoder_database));

  EXPECT_EQ(kFrameSizeSamples * 2,
            buffer.GetSpanSamples(0, kSampleRateHz, kCountWaitingTime));

  // packet_2 has access to duration, and ignores last decoded duration as
  // input.
  EXPECT_EQ(kFrameSizeSamples * 2,
            buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
                                  kCountWaitingTime));
}

TEST(PacketBuffer, GetSpanSamplesCountWaitingTime) {
  constexpr size_t kFrameSizeSamples = 10;
  constexpr int kPayloadSizeBytes = 1;  // Does not matter to this test;
  constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE;  // Close to wrap around.
  constexpr int kSampleRateHz = 48000;
  constexpr bool kCountWaitingTime = true;
  constexpr size_t kLastDecodedSizeSamples = 0;
  TickTimer tick_timer;
  PacketBuffer buffer(3, &tick_timer);
  PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples);
  StrictMock<MockStatisticsCalculator> mock_stats;
  MockDecoderDatabase decoder_database;

  Packet packet = gen.NextPacket(kPayloadSizeBytes, nullptr);

  EXPECT_EQ(PacketBuffer::kOK,
            buffer.InsertPacket(/*packet=*/std::move(packet),
                                /*stats=*/&mock_stats,
                                /*last_decoded_length=*/kFrameSizeSamples,
                                /*sample_rate=*/kSampleRateHz,
                                /*target_level_ms=*/60,
                                /*decoder_database=*/decoder_database));

  EXPECT_EQ(0u, buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
                                      kCountWaitingTime));

  tick_timer.Increment();
  EXPECT_EQ(480u, buffer.GetSpanSamples(0, kSampleRateHz, kCountWaitingTime));

  tick_timer.Increment();
  EXPECT_EQ(960u, buffer.GetSpanSamples(0, kSampleRateHz, kCountWaitingTime));
}

namespace {
void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
  // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
  // half the timestamp range.
  static const uint32_t kZeroHorizon = 0;
  static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
  // Timestamp on the limit is not old.
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
      limit_timestamp, limit_timestamp, kZeroHorizon));
  // 1 sample behind is old.
  EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
                                                limit_timestamp, kZeroHorizon));
  // 2^31 - 1 samples behind is old.
  EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - k2Pow31Minus1,
                                                limit_timestamp, kZeroHorizon));
  // 1 sample ahead is not old.
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
      limit_timestamp + 1, limit_timestamp, kZeroHorizon));
  // If |t1-t2|=2^31 and t1>t2, t2 is older than t1 but not the opposite.
  uint32_t other_timestamp = limit_timestamp + (1 << 31);
  uint32_t lowest_timestamp = std::min(limit_timestamp, other_timestamp);
  uint32_t highest_timestamp = std::max(limit_timestamp, other_timestamp);
  EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
      lowest_timestamp, highest_timestamp, kZeroHorizon));
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
      highest_timestamp, lowest_timestamp, kZeroHorizon));

  // Fixed horizon at 10 samples.
  static const uint32_t kHorizon = 10;
  // Timestamp on the limit is not old.
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp,
                                                 limit_timestamp, kHorizon));
  // 1 sample behind is old.
  EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
                                                limit_timestamp, kHorizon));
  // 9 samples behind is old.
  EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 9,
                                                limit_timestamp, kHorizon));
  // 10 samples behind is not old.
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 10,
                                                 limit_timestamp, kHorizon));
  // 2^31 - 1 samples behind is not old.
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
      limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
  // 1 sample ahead is not old.
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + 1,
                                                 limit_timestamp, kHorizon));
  // 2^31 samples ahead is not old.
  EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + (1 << 31),
                                                 limit_timestamp, kHorizon));
}
}  // namespace

// Test the IsObsoleteTimestamp method with different limit timestamps.
TEST(PacketBuffer, IsObsoleteTimestamp) {
  TestIsObsoleteTimestamp(0);
  TestIsObsoleteTimestamp(1);
  TestIsObsoleteTimestamp(0xFFFFFFFF);  // -1 in uint32_t.
  TestIsObsoleteTimestamp(0x80000000);  // 2^31.
  TestIsObsoleteTimestamp(0x80000001);  // 2^31 + 1.
  TestIsObsoleteTimestamp(0x7FFFFFFF);  // 2^31 - 1.
}

}  // namespace webrtc
