/*
 *  Copyright (c) 2013 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.
 */

#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"

#include <cstddef>
#include <cstdint>
#include <deque>
#include <map>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/call/transport.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/rtp_headers.h"
#include "api/rtp_parameters.h"
#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/video_codec_type.h"
#include "api/video/video_content_type.h"
#include "api/video/video_frame_type.h"
#include "api/video/video_rotation.h"
#include "modules/include/module_fec_types.h"
#include "modules/rtp_rtcp/include/flexfec_sender.h"
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/include/rtcp_statistics.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "modules/rtp_rtcp/source/rtp_header_extension_size.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
#include "modules/rtp_rtcp/source/rtp_sender_video.h"
#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h"
#include "modules/rtp_rtcp/source/ulpfec_generator.h"
#include "modules/rtp_rtcp/source/video_fec_generator.h"
#include "modules/video_coding/codecs/interface/common_constants.h"
#include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
#include "rtc_base/buffer.h"
#include "rtc_base/rate_limiter.h"
#include "system_wrappers/include/ntp_time.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/rtcp_packet_parser.h"
#include "test/time_controller/simulated_time_controller.h"

using ::testing::AllOf;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Gt;
using ::testing::Not;
using ::testing::Optional;
using ::testing::SizeIs;

namespace webrtc {
namespace {
constexpr uint32_t kSenderSsrc = 0x12345;
constexpr uint32_t kReceiverSsrc = 0x23456;
constexpr uint32_t kRtxSenderSsrc = 0x12346;
constexpr TimeDelta kOneWayNetworkDelay = TimeDelta::Millis(100);
constexpr uint8_t kBaseLayerTid = 0;
constexpr uint8_t kHigherLayerTid = 1;
constexpr uint16_t kSequenceNumber = 100;
constexpr uint8_t kPayloadType = 100;
constexpr uint8_t kRtxPayloadType = 98;
constexpr int kWidth = 320;
constexpr int kHeight = 100;
constexpr int kCaptureTimeMsToRtpTimestamp = 90;  // 90 kHz clock.
constexpr TimeDelta kDefaultReportInterval = TimeDelta::Millis(1000);

// RTP header extension ids.
enum : int {
  kAbsoluteSendTimeExtensionId = 1,
  kTransportSequenceNumberExtensionId,
  kTransmissionOffsetExtensionId,
};

MATCHER_P2(Near, value, margin, "") {
  return value - margin <= arg && arg <= value + margin;
}

class RtcpRttStatsTestImpl : public RtcpRttStats {
 public:
  RtcpRttStatsTestImpl() : rtt_ms_(0) {}
  ~RtcpRttStatsTestImpl() override = default;

  void OnRttUpdate(int64_t rtt_ms) override { rtt_ms_ = rtt_ms; }
  int64_t LastProcessedRtt() const override { return rtt_ms_; }
  int64_t rtt_ms_;
};

// TODO(bugs.webrtc.org/11581): remove inheritance once the ModuleRtpRtcpImpl2
// Module/ProcessThread dependency is gone.
class SendTransport : public Transport,
                      public sim_time_impl::SimulatedSequenceRunner {
 public:
  SendTransport(TimeDelta delay, GlobalSimulatedTimeController* time_controller)
      : receiver_(nullptr),
        time_controller_(time_controller),
        delay_(delay),
        rtp_packets_sent_(0),
        rtcp_packets_sent_(0),
        last_packet_(&header_extensions_) {
    time_controller_->Register(this);
  }

  ~SendTransport() { time_controller_->Unregister(this); }

  void SetRtpRtcpModule(ModuleRtpRtcpImpl2* receiver) { receiver_ = receiver; }
  void SimulateNetworkDelay(TimeDelta delay) { delay_ = delay; }
  bool SendRtp(ArrayView<const uint8_t> data,
               const PacketOptions& /* options */) override {
    EXPECT_TRUE(last_packet_.Parse(data));
    ++rtp_packets_sent_;
    return true;
  }
  bool SendRtcp(ArrayView<const uint8_t> data) override {
    test::RtcpPacketParser parser;
    parser.Parse(data);
    last_nack_list_ = parser.nack()->packet_ids();
    Timestamp current_time = time_controller_->GetClock()->CurrentTime();
    Timestamp delivery_time = current_time + delay_;
    rtcp_packets_.push_back(
        Packet{delivery_time, std::vector<uint8_t>(data.begin(), data.end())});
    ++rtcp_packets_sent_;
    RunReady(current_time);
    return true;
  }

  // sim_time_impl::SimulatedSequenceRunner
  Timestamp GetNextRunTime() const override {
    if (!rtcp_packets_.empty())
      return rtcp_packets_.front().send_time;
    return Timestamp::PlusInfinity();
  }
  void RunReady(Timestamp at_time) override {
    while (!rtcp_packets_.empty() &&
           rtcp_packets_.front().send_time <= at_time) {
      Packet packet = std::move(rtcp_packets_.front());
      rtcp_packets_.pop_front();
      EXPECT_TRUE(receiver_);
      receiver_->IncomingRtcpPacket(packet.data);
    }
  }
  TaskQueueBase* GetAsTaskQueue() override {
    return reinterpret_cast<TaskQueueBase*>(this);
  }

  size_t NumRtcpSent() { return rtcp_packets_sent_; }

  ModuleRtpRtcpImpl2* receiver_;
  GlobalSimulatedTimeController* const time_controller_;
  TimeDelta delay_;
  int rtp_packets_sent_;
  size_t rtcp_packets_sent_;
  std::vector<uint16_t> last_nack_list_;
  RtpHeaderExtensionMap header_extensions_;
  RtpPacketReceived last_packet_;
  struct Packet {
    Timestamp send_time;
    std::vector<uint8_t> data;
  };
  std::deque<Packet> rtcp_packets_;
};

class RtpRtcpModule : public RtcpPacketTypeCounterObserver,
                      public SendPacketObserver,
                      public StreamDataCountersCallback {
 public:
  struct SentPacket {
    SentPacket(uint16_t packet_id, Timestamp capture_time, uint32_t ssrc)
        : packet_id(packet_id), capture_time(capture_time), ssrc(ssrc) {}
    uint16_t packet_id;
    Timestamp capture_time;
    uint32_t ssrc;
  };

  RtpRtcpModule(const Environment& env,
                GlobalSimulatedTimeController* time_controller,
                bool is_sender)
      : env_(env),
        is_sender_(is_sender),
        receive_statistics_(ReceiveStatistics::Create(&env.clock())),
        transport_(kOneWayNetworkDelay, time_controller) {
    CreateModuleImpl();
  }

  const Environment env_;
  const bool is_sender_;
  RtcpPacketTypeCounter packets_sent_;
  RtcpPacketTypeCounter packets_received_;
  std::unique_ptr<ReceiveStatistics> receive_statistics_;
  SendTransport transport_;
  RtcpRttStatsTestImpl rtt_stats_;
  std::unique_ptr<ModuleRtpRtcpImpl2> impl_;

  void RtcpPacketTypesCounterUpdated(
      uint32_t ssrc,
      const RtcpPacketTypeCounter& packet_counter) override {
    counter_map_[ssrc] = packet_counter;
  }

  void OnSendPacket(std::optional<uint16_t> packet_id,
                    Timestamp capture_time,
                    uint32_t ssrc) override {
    if (packet_id.has_value()) {
      last_sent_packet_.emplace(*packet_id, capture_time, ssrc);
    }
  }

  StreamDataCounters GetDataCounters(uint32_t ssrc) const override {
    auto it = counters_by_ssrc.find(ssrc);
    return it != counters_by_ssrc.end() ? it->second : StreamDataCounters();
  }
  void DataCountersUpdated(const StreamDataCounters& counters,
                           uint32_t ssrc) override {
    counters_by_ssrc[ssrc] = counters;
  }

  std::optional<SentPacket> last_sent_packet() const {
    return last_sent_packet_;
  }

  RtcpPacketTypeCounter RtcpSent() {
    // RTCP counters for remote SSRC.
    return counter_map_[is_sender_ ? kReceiverSsrc : kSenderSsrc];
  }

  RtcpPacketTypeCounter RtcpReceived() {
    // Received RTCP stats for (own) local SSRC.
    return counter_map_[impl_->SSRC()];
  }
  int RtpSent() { return transport_.rtp_packets_sent_; }
  uint16_t LastRtpSequenceNumber() { return last_packet().SequenceNumber(); }
  std::vector<uint16_t> LastNackListSent() {
    return transport_.last_nack_list_;
  }
  void SetRtcpReportIntervalAndReset(TimeDelta rtcp_report_interval) {
    rtcp_report_interval_ = rtcp_report_interval;
    CreateModuleImpl();
  }
  const RtpPacketReceived& last_packet() { return transport_.last_packet_; }
  void RegisterHeaderExtension(absl::string_view uri, int id) {
    impl_->RegisterRtpHeaderExtension(uri, id);
    transport_.header_extensions_.RegisterByUri(id, uri);
    transport_.last_packet_.IdentifyExtensions(transport_.header_extensions_);
  }
  void ReinintWithFec(VideoFecGenerator* fec_generator) {
    fec_generator_ = fec_generator;
    CreateModuleImpl();
  }

  void CreateModuleImpl() {
    RtpRtcpInterface::Configuration config;
    config.audio = false;
    config.outgoing_transport = &transport_;
    config.receive_statistics = receive_statistics_.get();
    config.rtcp_packet_type_counter_observer = this;
    config.rtt_stats = &rtt_stats_;
    config.rtcp_report_interval_ms = rtcp_report_interval_.ms();
    config.local_media_ssrc = is_sender_ ? kSenderSsrc : kReceiverSsrc;
    config.rtx_send_ssrc =
        is_sender_ ? std::make_optional(kRtxSenderSsrc) : std::nullopt;
    config.need_rtp_packet_infos = true;
    config.non_sender_rtt_measurement = true;
    config.send_packet_observer = this;
    config.rtp_stats_callback = this;
    config.fec_generator = fec_generator_;
    impl_ = std::make_unique<ModuleRtpRtcpImpl2>(env_, config);
    impl_->SetRemoteSSRC(is_sender_ ? kReceiverSsrc : kSenderSsrc);
    impl_->SetRTCPStatus(RtcpMode::kCompound);
  }

 private:
  std::map<uint32_t, RtcpPacketTypeCounter> counter_map_;
  std::map<uint32_t, StreamDataCounters> counters_by_ssrc;
  std::optional<SentPacket> last_sent_packet_;
  VideoFecGenerator* fec_generator_ = nullptr;
  TimeDelta rtcp_report_interval_ = kDefaultReportInterval;
};
}  // namespace

class RtpRtcpImpl2Test : public ::testing::Test {
 protected:
  RtpRtcpImpl2Test()
      : time_controller_(Timestamp::Micros(133590000000000)),
        env_(CreateEnvironment(time_controller_.GetClock(),
                               time_controller_.CreateTaskQueueFactory())),
        sender_(env_,
                &time_controller_,
                /*is_sender=*/true),
        receiver_(env_,
                  &time_controller_,
                  /*is_sender=*/false) {}

  void SetUp() override {
    // Send module.
    EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true));
    sender_.impl_->SetSendingMediaStatus(true);
    sender_.impl_->SetSequenceNumber(kSequenceNumber);
    sender_.impl_->SetStorePacketsStatus(true, 100);

    RTPSenderVideo::Config video_config;
    video_config.clock = time_controller_.GetClock();
    video_config.rtp_sender = sender_.impl_->RtpSender();
    video_config.field_trials = &env_.field_trials();
    sender_video_ = std::make_unique<RTPSenderVideo>(video_config);

    // Receive module.
    EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false));
    receiver_.impl_->SetSendingMediaStatus(false);
    // Transport settings.
    sender_.transport_.SetRtpRtcpModule(receiver_.impl_.get());
    receiver_.transport_.SetRtpRtcpModule(sender_.impl_.get());
  }

  void AdvanceTime(TimeDelta duration) {
    time_controller_.AdvanceTime(duration);
  }

  void ReinitWithFec(VideoFecGenerator* fec_generator,
                     std::optional<int> red_payload_type) {
    sender_.ReinintWithFec(fec_generator);
    EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true));
    sender_.impl_->SetSendingMediaStatus(true);
    sender_.impl_->SetSequenceNumber(kSequenceNumber);
    sender_.impl_->SetStorePacketsStatus(true, 100);
    receiver_.transport_.SetRtpRtcpModule(sender_.impl_.get());

    RTPSenderVideo::Config video_config;
    video_config.clock = time_controller_.GetClock();
    video_config.rtp_sender = sender_.impl_->RtpSender();
    video_config.field_trials = &env_.field_trials();
    video_config.fec_overhead_bytes = fec_generator->MaxPacketOverhead();
    video_config.fec_type = fec_generator->GetFecType();
    video_config.red_payload_type = red_payload_type;
    sender_video_ = std::make_unique<RTPSenderVideo>(video_config);
  }

  GlobalSimulatedTimeController time_controller_;
  const Environment env_;
  RtpRtcpModule sender_;
  std::unique_ptr<RTPSenderVideo> sender_video_;
  RtpRtcpModule receiver_;

  bool SendFrame(const RtpRtcpModule* module,
                 RTPSenderVideo* sender,
                 uint8_t tid) {
    int64_t now_ms = time_controller_.GetClock()->TimeInMilliseconds();
    return SendFrame(
        module, sender, tid,
        static_cast<uint32_t>(now_ms * kCaptureTimeMsToRtpTimestamp), now_ms);
  }

  bool SendFrame(const RtpRtcpModule* module,
                 RTPSenderVideo* sender,
                 uint8_t tid,
                 uint32_t rtp_timestamp,
                 int64_t capture_time_ms) {
    RTPVideoHeaderVP8 vp8_header = {};
    vp8_header.temporalIdx = tid;
    RTPVideoHeader rtp_video_header;
    rtp_video_header.frame_type = VideoFrameType::kVideoFrameKey;
    rtp_video_header.width = kWidth;
    rtp_video_header.height = kHeight;
    rtp_video_header.rotation = kVideoRotation_0;
    rtp_video_header.content_type = VideoContentType::UNSPECIFIED;
    rtp_video_header.is_first_packet_in_frame = true;
    rtp_video_header.simulcastIdx = 0;
    rtp_video_header.codec = kVideoCodecVP8;
    rtp_video_header.video_type_header = vp8_header;
    rtp_video_header.video_timing = {0u, 0u, 0u, 0u, 0u, 0u, false};

    const uint8_t payload[100] = {0};
    bool success = module->impl_->OnSendingRtpFrame(0, 0, kPayloadType, true);

    success &= sender->SendVideo(
        kPayloadType, VideoCodecType::kVideoCodecVP8, rtp_timestamp,
        Timestamp::Millis(capture_time_ms), payload, sizeof(payload),
        rtp_video_header, TimeDelta::Zero(), {});
    return success;
  }

  void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) {
    bool sender = module->impl_->SSRC() == kSenderSsrc;
    rtcp::Nack nack;
    uint16_t list[1];
    list[0] = sequence_number;
    const uint16_t kListLength = sizeof(list) / sizeof(list[0]);
    nack.SetSenderSsrc(sender ? kReceiverSsrc : kSenderSsrc);
    nack.SetMediaSsrc(sender ? kSenderSsrc : kReceiverSsrc);
    nack.SetPacketIds(list, kListLength);
    Buffer packet = nack.Build();
    module->impl_->IncomingRtcpPacket(packet);
  }
};

TEST_F(RtpRtcpImpl2Test, RetransmitsAllLayers) {
  // Send frames.
  EXPECT_EQ(0, sender_.RtpSent());
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(),
                        kBaseLayerTid));  // kSequenceNumber
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(),
                        kHigherLayerTid));  // kSequenceNumber + 1
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(),
                        kNoTemporalIdx));  // kSequenceNumber + 2
  EXPECT_EQ(3, sender_.RtpSent());
  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());

  // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
  AdvanceTime(TimeDelta::Millis(5));

  // Frame with kBaseLayerTid re-sent.
  IncomingRtcpNack(&sender_, kSequenceNumber);
  EXPECT_EQ(4, sender_.RtpSent());
  EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber());
  // Frame with kHigherLayerTid re-sent.
  IncomingRtcpNack(&sender_, kSequenceNumber + 1);
  EXPECT_EQ(5, sender_.RtpSent());
  EXPECT_EQ(kSequenceNumber + 1, sender_.LastRtpSequenceNumber());
  // Frame with kNoTemporalIdx re-sent.
  IncomingRtcpNack(&sender_, kSequenceNumber + 2);
  EXPECT_EQ(6, sender_.RtpSent());
  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
}

TEST_F(RtpRtcpImpl2Test, Rtt) {
  RtpPacketReceived packet;
  packet.SetTimestamp(1);
  packet.SetSequenceNumber(123);
  packet.SetSsrc(kSenderSsrc);
  packet.AllocatePayload(100 - 12);
  receiver_.receive_statistics_->OnRtpPacket(packet);

  // Send Frame before sending an SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  // Sender module should send an SR.
  EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
  AdvanceTime(kOneWayNetworkDelay);

  // Receiver module should send a RR with a response to the last received SR.
  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
  AdvanceTime(kOneWayNetworkDelay);

  // Verify RTT.
  EXPECT_THAT(sender_.impl_->LastRtt(),
              Near(2 * kOneWayNetworkDelay, TimeDelta::Millis(1)));

  // Verify RTT from rtt_stats config.
  EXPECT_EQ(0, sender_.rtt_stats_.LastProcessedRtt());
  EXPECT_EQ(0, sender_.impl_->rtt_ms());
  AdvanceTime(TimeDelta::Millis(1000));

  EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(),
              sender_.rtt_stats_.LastProcessedRtt(), 1);
  EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), sender_.impl_->rtt_ms(), 1);
}

TEST_F(RtpRtcpImpl2Test, RttForReceiverOnly) {
  // Receiver module should send a Receiver reference time report block (RRTR).
  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));

  // Sender module should send a response to the last received RRTR (DLRR).
  AdvanceTime(TimeDelta::Millis(1000));
  // Send Frame before sending a SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));

  // Verify RTT.
  EXPECT_EQ(0, receiver_.rtt_stats_.LastProcessedRtt());
  EXPECT_EQ(0, receiver_.impl_->rtt_ms());
  AdvanceTime(TimeDelta::Millis(1000));
  EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(),
              receiver_.rtt_stats_.LastProcessedRtt(), 1);
  EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), receiver_.impl_->rtt_ms(), 1);
}

TEST_F(RtpRtcpImpl2Test, NoSrBeforeMedia) {
  // Ignore fake transport delays in this test.
  sender_.transport_.SimulateNetworkDelay(TimeDelta::Zero());
  receiver_.transport_.SimulateNetworkDelay(TimeDelta::Zero());

  // Move ahead to the instant a rtcp is expected.
  // Verify no SR is sent before media has been sent, RR should still be sent
  // from the receiving module though.
  AdvanceTime(kDefaultReportInterval / 2);
  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u);
  EXPECT_EQ(receiver_.transport_.NumRtcpSent(), 1u);

  // RTCP should be triggered by the RTP send.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);
}

TEST_F(RtpRtcpImpl2Test, RtcpPacketTypeCounter_Nack) {
  EXPECT_EQ(0U, sender_.RtcpReceived().nack_packets);
  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);

  // Receive module sends a NACK.
  const uint16_t kNackLength = 1;
  uint16_t nack_list[kNackLength] = {123};
  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
  AdvanceTime(kOneWayNetworkDelay);
  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);

  // Send module receives the NACK.
  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
}

TEST_F(RtpRtcpImpl2Test, AddStreamDataCounters) {
  StreamDataCounters rtp;
  const Timestamp kStartTime = Timestamp::Seconds(1);
  rtp.first_packet_time = kStartTime;
  rtp.transmitted.packets = 1;
  rtp.transmitted.payload_bytes = 1;
  rtp.transmitted.header_bytes = 2;
  rtp.transmitted.padding_bytes = 3;
  EXPECT_EQ(rtp.transmitted.TotalBytes(), rtp.transmitted.payload_bytes +
                                              rtp.transmitted.header_bytes +
                                              rtp.transmitted.padding_bytes);

  StreamDataCounters rtp2;
  rtp2.transmitted.packets = 10;
  rtp2.transmitted.payload_bytes = 10;
  rtp2.retransmitted.header_bytes = 4;
  rtp2.retransmitted.payload_bytes = 5;
  rtp2.retransmitted.padding_bytes = 6;
  rtp2.retransmitted.packets = 7;
  rtp2.fec.packets = 8;

  StreamDataCounters sum = rtp;
  sum.Add(rtp2);
  EXPECT_EQ(sum.first_packet_time, kStartTime);
  EXPECT_EQ(11U, sum.transmitted.packets);
  EXPECT_EQ(11U, sum.transmitted.payload_bytes);
  EXPECT_EQ(2U, sum.transmitted.header_bytes);
  EXPECT_EQ(3U, sum.transmitted.padding_bytes);
  EXPECT_EQ(4U, sum.retransmitted.header_bytes);
  EXPECT_EQ(5U, sum.retransmitted.payload_bytes);
  EXPECT_EQ(6U, sum.retransmitted.padding_bytes);
  EXPECT_EQ(7U, sum.retransmitted.packets);
  EXPECT_EQ(8U, sum.fec.packets);
  EXPECT_EQ(sum.transmitted.TotalBytes(),
            rtp.transmitted.TotalBytes() + rtp2.transmitted.TotalBytes());

  StreamDataCounters rtp3;
  rtp3.first_packet_time = kStartTime + TimeDelta::Millis(10);
  sum.Add(rtp3);
  EXPECT_EQ(sum.first_packet_time, kStartTime);  // Holds oldest time.
}

TEST_F(RtpRtcpImpl2Test, SendsInitialNackList) {
  // Send module sends a NACK.
  const uint16_t kNackLength = 1;
  uint16_t nack_list[kNackLength] = {123};
  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
  // Send Frame before sending a compound RTCP that starts with SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
}

TEST_F(RtpRtcpImpl2Test, SendsExtendedNackList) {
  // Send module sends a NACK.
  const uint16_t kNackLength = 1;
  uint16_t nack_list[kNackLength] = {123};
  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
  // Send Frame before sending a compound RTCP that starts with SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));

  // Same list not re-send.
  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));

  // Only extended list sent.
  const uint16_t kNackExtLength = 2;
  uint16_t nack_list_ext[kNackExtLength] = {123, 124};
  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list_ext, kNackExtLength));
  EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(124));
}

TEST_F(RtpRtcpImpl2Test, ReSendsNackListAfterRttMs) {
  sender_.transport_.SimulateNetworkDelay(TimeDelta::Zero());
  // Send module sends a NACK.
  const uint16_t kNackLength = 2;
  uint16_t nack_list[kNackLength] = {123, 125};
  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
  // Send Frame before sending a compound RTCP that starts with SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));

  // Same list not re-send, rtt interval has not passed.
  const TimeDelta kStartupRtt = TimeDelta::Millis(100);
  AdvanceTime(kStartupRtt);
  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);

  // Rtt interval passed, full list sent.
  AdvanceTime(TimeDelta::Millis(1));
  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
  EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
}

TEST_F(RtpRtcpImpl2Test, UniqueNackRequests) {
  receiver_.transport_.SimulateNetworkDelay(TimeDelta::Zero());
  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
  EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests);
  EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests);
  EXPECT_EQ(0, receiver_.RtcpSent().UniqueNackRequestsInPercent());

  // Receive module sends NACK request.
  const uint16_t kNackLength = 4;
  uint16_t nack_list[kNackLength] = {10, 11, 13, 18};
  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
  EXPECT_EQ(4U, receiver_.RtcpSent().nack_requests);
  EXPECT_EQ(4U, receiver_.RtcpSent().unique_nack_requests);
  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(10, 11, 13, 18));

  // Send module receives the request.
  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
  EXPECT_EQ(4U, sender_.RtcpReceived().nack_requests);
  EXPECT_EQ(4U, sender_.RtcpReceived().unique_nack_requests);
  EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent());

  // Receive module sends new request with duplicated packets.
  const TimeDelta kStartupRtt = TimeDelta::Millis(100);
  AdvanceTime(kStartupRtt + TimeDelta::Millis(1));
  const uint16_t kNackLength2 = 4;
  uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21};
  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2));
  EXPECT_EQ(2U, receiver_.RtcpSent().nack_packets);
  EXPECT_EQ(8U, receiver_.RtcpSent().nack_requests);
  EXPECT_EQ(6U, receiver_.RtcpSent().unique_nack_requests);
  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(11, 18, 20, 21));

  // Send module receives the request.
  EXPECT_EQ(2U, sender_.RtcpReceived().nack_packets);
  EXPECT_EQ(8U, sender_.RtcpReceived().nack_requests);
  EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests);
  EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent());
}

TEST_F(RtpRtcpImpl2Test, ConfigurableRtcpReportInterval) {
  const TimeDelta kVideoReportInterval = TimeDelta::Millis(3000);

  // Recreate sender impl with new configuration, and redo setup.
  sender_.SetRtcpReportIntervalAndReset(kVideoReportInterval);
  SetUp();

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));

  // Initial state
  EXPECT_EQ(0u, sender_.transport_.NumRtcpSent());

  // Move ahead to the last ms before a rtcp is expected, no action.
  AdvanceTime(kVideoReportInterval / 2 - TimeDelta::Millis(1));
  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u);

  // Move ahead to the first rtcp. Send RTCP.
  AdvanceTime(TimeDelta::Millis(1));
  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));

  // Move ahead to the last possible second before second rtcp is expected.
  AdvanceTime(kVideoReportInterval * 1 / 2 - TimeDelta::Millis(1));
  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);

  // Move ahead into the range of second rtcp, the second rtcp may be sent.
  AdvanceTime(TimeDelta::Millis(1));
  EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);

  AdvanceTime(kVideoReportInterval / 2);
  EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);

  // Move out the range of second rtcp, the second rtcp must have been sent.
  AdvanceTime(kVideoReportInterval / 2);
  EXPECT_EQ(sender_.transport_.NumRtcpSent(), 2u);
}

TEST_F(RtpRtcpImpl2Test, RtpSenderEgressTimestampOffset) {
  // RTP timestamp offset not explicitly set, default to random value.
  uint16_t seqno = sender_.impl_->GetRtpState().sequence_number;
  uint32_t media_rtp_ts = 1001;
  uint32_t rtp_ts = media_rtp_ts + sender_.impl_->StartTimestamp();
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid, rtp_ts,
                        /*capture_time_ms=*/0));
  AdvanceTime(kOneWayNetworkDelay);
  EXPECT_THAT(
      sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{seqno}),
      ElementsAre(Field(&RtpSequenceNumberMap::Info::timestamp, media_rtp_ts)));

  RtpState saved_rtp_state = sender_.impl_->GetRtpState();

  // Change RTP timestamp offset.
  sender_.impl_->SetStartTimestamp(2000);

  // Restores RtpState and make sure the old timestamp offset is in place.
  sender_.impl_->SetRtpState(saved_rtp_state);
  seqno = sender_.impl_->GetRtpState().sequence_number;
  media_rtp_ts = 1031;
  rtp_ts = media_rtp_ts + sender_.impl_->StartTimestamp();
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid, rtp_ts,
                        /*capture_time_ms=*/0));
  AdvanceTime(kOneWayNetworkDelay);
  EXPECT_THAT(
      sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{seqno}),
      ElementsAre(Field(&RtpSequenceNumberMap::Info::timestamp, media_rtp_ts)));
}

TEST_F(RtpRtcpImpl2Test, StoresPacketInfoForSentPackets) {
  const uint32_t kStartTimestamp = 1u;
  SetUp();
  sender_.impl_->SetStartTimestamp(kStartTimestamp);

  sender_.impl_->SetSequenceNumber(1);

  PacedPacketInfo pacing_info;
  RtpPacketToSend packet(nullptr);
  packet.set_packet_type(RtpPacketToSend::Type::kVideo);
  packet.SetSsrc(kSenderSsrc);

  // Single-packet frame.
  packet.SetTimestamp(1);
  packet.set_first_packet_of_frame(true);
  packet.SetMarker(true);
  sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet),
                               pacing_info);
  AdvanceTime(TimeDelta::Millis(1));

  std::vector<RtpSequenceNumberMap::Info> seqno_info =
      sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{1});

  EXPECT_THAT(seqno_info, ElementsAre(RtpSequenceNumberMap::Info(
                              /*timestamp=*/1 - kStartTimestamp,
                              /*is_first=*/1,
                              /*is_last=*/1)));

  // Three-packet frame.
  packet.SetTimestamp(2);
  packet.set_first_packet_of_frame(true);
  packet.SetMarker(false);
  sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet),
                               pacing_info);

  packet.set_first_packet_of_frame(false);
  sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet),
                               pacing_info);

  packet.SetMarker(true);
  sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet),
                               pacing_info);

  AdvanceTime(TimeDelta::Millis(1));

  seqno_info =
      sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{2, 3, 4});

  EXPECT_THAT(seqno_info, ElementsAre(RtpSequenceNumberMap::Info(
                                          /*timestamp=*/2 - kStartTimestamp,
                                          /*is_first=*/1,
                                          /*is_last=*/0),
                                      RtpSequenceNumberMap::Info(
                                          /*timestamp=*/2 - kStartTimestamp,
                                          /*is_first=*/0,
                                          /*is_last=*/0),
                                      RtpSequenceNumberMap::Info(
                                          /*timestamp=*/2 - kStartTimestamp,
                                          /*is_first=*/0,
                                          /*is_last=*/1)));
}

// Checks that the sender report stats are not available if no RTCP SR was sent.
TEST_F(RtpRtcpImpl2Test, SenderReportStatsNotAvailable) {
  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt));
}

// Checks that the sender report stats are available if an RTCP SR was sent.
TEST_F(RtpRtcpImpl2Test, SenderReportStatsAvailable) {
  // Send a frame in order to send an SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  // Send an SR.
  ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
  AdvanceTime(kOneWayNetworkDelay);
  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Not(Eq(std::nullopt)));
}

// Checks that the sender report stats are not available if an RTCP SR with an
// unexpected SSRC is received.
TEST_F(RtpRtcpImpl2Test, SenderReportStatsNotUpdatedWithUnexpectedSsrc) {
  constexpr uint32_t kUnexpectedSenderSsrc = 0x87654321;
  static_assert(kUnexpectedSenderSsrc != kSenderSsrc, "");
  // Forge a sender report and pass it to the receiver as if an RTCP SR were
  // sent by an unexpected sender.
  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kUnexpectedSenderSsrc);
  sr.SetNtp({/*seconds=*/1u, /*fractions=*/1u << 31});
  sr.SetPacketCount(123u);
  sr.SetOctetCount(456u);
  auto raw_packet = sr.Build();
  receiver_.impl_->IncomingRtcpPacket(raw_packet);
  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt));
}

// Checks the stats derived from the last received RTCP SR are set correctly.
TEST_F(RtpRtcpImpl2Test, SenderReportStatsCheckStatsFromLastReport) {
  using SenderReportStats = RtpRtcpInterface::SenderReportStats;
  const NtpTime ntp(/*seconds=*/1u, /*fractions=*/1u << 31);
  constexpr uint32_t kPacketCount = 123u;
  constexpr uint32_t kOctetCount = 456u;
  // Forge a sender report and pass it to the receiver as if an RTCP SR were
  // sent by the sender.
  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  sr.SetNtp(ntp);
  sr.SetPacketCount(kPacketCount);
  sr.SetOctetCount(kOctetCount);
  auto raw_packet = sr.Build();
  receiver_.impl_->IncomingRtcpPacket(raw_packet);

  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(),
              Optional(AllOf(
                  Field(&SenderReportStats::last_remote_ntp_timestamp, Eq(ntp)),
                  Field(&SenderReportStats::packets_sent, Eq(kPacketCount)),
                  Field(&SenderReportStats::bytes_sent, Eq(kOctetCount)))));
}

// Checks that the sender report stats count equals the number of sent RTCP SRs.
TEST_F(RtpRtcpImpl2Test, SenderReportStatsCount) {
  using SenderReportStats = RtpRtcpInterface::SenderReportStats;
  // Send a frame in order to send an SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  // Send the first SR.
  ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
  AdvanceTime(kOneWayNetworkDelay);
  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(),
              Optional(Field(&SenderReportStats::reports_count, Eq(1u))));
  // Send the second SR.
  ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
  AdvanceTime(kOneWayNetworkDelay);
  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(),
              Optional(Field(&SenderReportStats::reports_count, Eq(2u))));
}

// Checks that the sender report stats include a valid arrival time if an RTCP
// SR was sent.
TEST_F(RtpRtcpImpl2Test, SenderReportStatsArrivalTimestampSet) {
  // Send a frame in order to send an SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  // Send an SR.
  ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
  AdvanceTime(kOneWayNetworkDelay);
  auto stats = receiver_.impl_->GetSenderReportStats();
  ASSERT_THAT(stats, Not(Eq(std::nullopt)));
  EXPECT_TRUE(stats->last_arrival_ntp_timestamp.Valid());
}

// Checks that the packet and byte counters from an RTCP SR are not zero once
// a frame is sent.
TEST_F(RtpRtcpImpl2Test, SenderReportStatsPacketByteCounters) {
  using SenderReportStats = RtpRtcpInterface::SenderReportStats;
  // Send a frame in order to send an SR.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  ASSERT_THAT(sender_.transport_.rtp_packets_sent_, Gt(0));
  // Advance time otherwise the RTCP SR report will not include any packets
  // generated by `SendFrame()`.
  AdvanceTime(TimeDelta::Millis(1));
  // Send an SR.
  ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
  AdvanceTime(kOneWayNetworkDelay);
  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(),
              Optional(AllOf(Field(&SenderReportStats::packets_sent, Gt(0u)),
                             Field(&SenderReportStats::bytes_sent, Gt(0u)))));
}

TEST_F(RtpRtcpImpl2Test, SendingVideoAdvancesSequenceNumber) {
  const uint16_t sequence_number = sender_.impl_->SequenceNumber();
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  ASSERT_THAT(sender_.transport_.rtp_packets_sent_, Gt(0));
  EXPECT_EQ(sequence_number + 1, sender_.impl_->SequenceNumber());
}

TEST_F(RtpRtcpImpl2Test, SequenceNumberNotAdvancedWhenNotSending) {
  const uint16_t sequence_number = sender_.impl_->SequenceNumber();
  sender_.impl_->SetSendingMediaStatus(false);
  EXPECT_FALSE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  ASSERT_THAT(sender_.transport_.rtp_packets_sent_, Eq(0));
  EXPECT_EQ(sequence_number, sender_.impl_->SequenceNumber());
}

TEST_F(RtpRtcpImpl2Test, PaddingNotAllowedInMiddleOfFrame) {
  constexpr size_t kPaddingSize = 100;

  // Can't send padding before media.
  EXPECT_THAT(sender_.impl_->GeneratePadding(kPaddingSize), SizeIs(0u));

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));

  // Padding is now ok.
  EXPECT_THAT(sender_.impl_->GeneratePadding(kPaddingSize), SizeIs(Gt(0u)));

  // Send half a video frame.
  PacedPacketInfo pacing_info;
  std::unique_ptr<RtpPacketToSend> packet =
      sender_.impl_->RtpSender()->AllocatePacket();
  packet->set_packet_type(RtpPacketToSend::Type::kVideo);
  packet->set_first_packet_of_frame(true);
  packet->SetMarker(false);  // Marker false - not last packet of frame.

  EXPECT_TRUE(sender_.impl_->TrySendPacket(std::move(packet), pacing_info));

  // Padding not allowed in middle of frame.
  EXPECT_THAT(sender_.impl_->GeneratePadding(kPaddingSize), SizeIs(0u));

  packet = sender_.impl_->RtpSender()->AllocatePacket();
  packet->set_packet_type(RtpPacketToSend::Type::kVideo);
  packet->set_first_packet_of_frame(true);
  packet->SetMarker(true);

  EXPECT_TRUE(sender_.impl_->TrySendPacket(std::move(packet), pacing_info));

  // Padding is OK again.
  EXPECT_THAT(sender_.impl_->GeneratePadding(kPaddingSize), SizeIs(Gt(0u)));
}

TEST_F(RtpRtcpImpl2Test, PaddingTimestampMatchesMedia) {
  constexpr size_t kPaddingSize = 100;
  const uint32_t kTimestamp = 123;

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid,
                        kTimestamp, /*capture_time_ms=*/0));
  EXPECT_EQ(sender_.last_packet().Timestamp(), kTimestamp);
  uint16_t media_seq = sender_.last_packet().SequenceNumber();

  // Generate and send padding.
  auto padding = sender_.impl_->GeneratePadding(kPaddingSize);
  ASSERT_FALSE(padding.empty());
  for (auto& packet : padding) {
    sender_.impl_->TrySendPacket(std::move(packet), PacedPacketInfo());
  }

  // Verify we sent a new packet, but with the same timestamp.
  EXPECT_NE(sender_.last_packet().SequenceNumber(), media_seq);
  EXPECT_EQ(sender_.last_packet().Timestamp(), kTimestamp);
}

TEST_F(RtpRtcpImpl2Test, AssignsTransportSequenceNumber) {
  sender_.RegisterHeaderExtension(TransportSequenceNumber::Uri(),
                                  kTransportSequenceNumberExtensionId);

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  uint16_t first_transport_seq = 0;
  EXPECT_TRUE(sender_.last_packet().GetExtension<TransportSequenceNumber>(
      &first_transport_seq));

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  uint16_t second_transport_seq = 0;
  EXPECT_TRUE(sender_.last_packet().GetExtension<TransportSequenceNumber>(
      &second_transport_seq));

  EXPECT_EQ(first_transport_seq + 1, second_transport_seq);
}

TEST_F(RtpRtcpImpl2Test, AssignsAbsoluteSendTime) {
  sender_.RegisterHeaderExtension(AbsoluteSendTime::Uri(),
                                  kAbsoluteSendTimeExtensionId);

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  EXPECT_NE(sender_.last_packet().GetExtension<AbsoluteSendTime>(), 0u);
}

TEST_F(RtpRtcpImpl2Test, AssignsTransmissionTimeOffset) {
  sender_.RegisterHeaderExtension(TransmissionOffset::Uri(),
                                  kTransmissionOffsetExtensionId);

  constexpr TimeDelta kOffset = TimeDelta::Millis(100);
  // Transmission offset is calculated from difference between capture time
  // and send time.
  int64_t capture_time_ms = time_controller_.GetClock()->TimeInMilliseconds();
  time_controller_.AdvanceTime(kOffset);

  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid,
                        /*timestamp=*/0, capture_time_ms));
  EXPECT_EQ(sender_.last_packet().GetExtension<TransmissionOffset>(),
            kOffset.ms() * kCaptureTimeMsToRtpTimestamp);
}

TEST_F(RtpRtcpImpl2Test, PropagatesSentPacketInfo) {
  sender_.RegisterHeaderExtension(TransportSequenceNumber::Uri(),
                                  kTransportSequenceNumberExtensionId);
  Timestamp now = time_controller_.GetClock()->CurrentTime();
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  EXPECT_THAT(sender_.last_sent_packet(),
              Optional(AllOf(
                  Field(&RtpRtcpModule::SentPacket::packet_id,
                        Eq(sender_.last_packet()
                               .GetExtension<TransportSequenceNumber>())),
                  Field(&RtpRtcpModule::SentPacket::capture_time, Eq(now)),
                  Field(&RtpRtcpModule::SentPacket::ssrc, Eq(kSenderSsrc)))));
}

TEST_F(RtpRtcpImpl2Test, GeneratesFlexfec) {
  constexpr int kFlexfecPayloadType = 118;
  constexpr uint32_t kFlexfecSsrc = 17;
  const char kNoMid[] = "";
  const std::vector<RtpExtension> kNoRtpExtensions;
  const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;

  // Make sure FlexFec sequence numbers start at a different point than media.
  const uint16_t fec_start_seq = sender_.impl_->SequenceNumber() + 100;
  RtpState start_state;
  start_state.sequence_number = fec_start_seq;
  FlexfecSender flexfec_sender(env_, kFlexfecPayloadType, kFlexfecSsrc,
                               kSenderSsrc, kNoMid, kNoRtpExtensions,
                               kNoRtpExtensionSizes, &start_state);
  ReinitWithFec(&flexfec_sender, /*red_payload_type=*/std::nullopt);

  // Parameters selected to generate a single FEC packet per media packet.
  FecProtectionParams params;
  params.fec_rate = 15;
  params.max_fec_frames = 1;
  params.fec_mask_type = kFecMaskRandom;
  sender_.impl_->SetFecProtectionParams(params, params);

  // Send a one packet frame, expect one media packet and one FEC packet.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  ASSERT_THAT(sender_.transport_.rtp_packets_sent_, Eq(2));

  const RtpPacketReceived& fec_packet = sender_.last_packet();
  EXPECT_EQ(fec_packet.SequenceNumber(), fec_start_seq);
  EXPECT_EQ(fec_packet.Ssrc(), kFlexfecSsrc);
  EXPECT_EQ(fec_packet.PayloadType(), kFlexfecPayloadType);
}

TEST_F(RtpRtcpImpl2Test, GeneratesUlpfec) {
  constexpr int kUlpfecPayloadType = 118;
  constexpr int kRedPayloadType = 119;
  UlpfecGenerator ulpfec_sender(env_, kRedPayloadType, kUlpfecPayloadType);
  ReinitWithFec(&ulpfec_sender, kRedPayloadType);

  // Parameters selected to generate a single FEC packet per media packet.
  FecProtectionParams params;
  params.fec_rate = 15;
  params.max_fec_frames = 1;
  params.fec_mask_type = kFecMaskRandom;
  sender_.impl_->SetFecProtectionParams(params, params);

  // Send a one packet frame, expect one media packet and one FEC packet.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  ASSERT_THAT(sender_.transport_.rtp_packets_sent_, Eq(2));

  // Ulpfec is sent on the media ssrc, sharing the sequene number series.
  const RtpPacketReceived& fec_packet = sender_.last_packet();
  EXPECT_EQ(fec_packet.SequenceNumber(), kSequenceNumber + 1);
  EXPECT_EQ(fec_packet.Ssrc(), kSenderSsrc);
  // The packets are encapsulated in RED packets, check that and that the RED
  // header (first byte of payload) indicates the desired FEC payload type.
  EXPECT_EQ(fec_packet.PayloadType(), kRedPayloadType);
  EXPECT_EQ(fec_packet.payload()[0], kUlpfecPayloadType);
}

TEST_F(RtpRtcpImpl2Test, RtpStateReflectsCurrentState) {
  // Verify that that each of the field of GetRtpState actually reflects
  // the current state.

  // Current time will be used for `timestamp`, `capture_time` and
  // `last_timestamp_time`.
  const Timestamp time = time_controller_.GetClock()->CurrentTime();

  // Use different than default sequence number to test `sequence_number`.
  const uint16_t kSeq = kSequenceNumber + 123;
  // Hard-coded value for `start_timestamp`.
  const uint32_t kStartTimestamp = 3456;
  const Timestamp capture_time = time;
  const uint32_t timestamp = capture_time.ms() * kCaptureTimeMsToRtpTimestamp;

  sender_.impl_->SetSequenceNumber(kSeq - 1);
  sender_.impl_->SetStartTimestamp(kStartTimestamp);
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));

  // Simulate an RTCP receiver report in order to populate `ssrc_has_acked`.
  ReportBlockData ack[1];
  ack[0].set_source_ssrc(kSenderSsrc);
  ack[0].set_extended_highest_sequence_number(kSeq);
  sender_.impl_->OnReceivedRtcpReportBlocks(ack);

  RtpState state = sender_.impl_->GetRtpState();
  EXPECT_EQ(state.sequence_number, kSeq);
  EXPECT_EQ(state.start_timestamp, kStartTimestamp);
  EXPECT_EQ(state.timestamp, timestamp);
  EXPECT_EQ(state.capture_time, capture_time);
  EXPECT_EQ(state.last_timestamp_time, time);
  EXPECT_EQ(state.ssrc_has_acked, true);

  // Reset sender, advance time, restore state. Directly observing state
  // is not feasible, so just verify returned state matches what we set.
  sender_.CreateModuleImpl();
  time_controller_.AdvanceTime(TimeDelta::Millis(10));
  sender_.impl_->SetRtpState(state);

  state = sender_.impl_->GetRtpState();
  EXPECT_EQ(state.sequence_number, kSeq);
  EXPECT_EQ(state.start_timestamp, kStartTimestamp);
  EXPECT_EQ(state.timestamp, timestamp);
  EXPECT_EQ(state.capture_time, capture_time);
  EXPECT_EQ(state.last_timestamp_time, time);
  EXPECT_EQ(state.ssrc_has_acked, true);
}

TEST_F(RtpRtcpImpl2Test, RtxRtpStateReflectsCurrentState) {
  // Enable RTX.
  sender_.impl_->SetStorePacketsStatus(/*enable=*/true, /*number_to_store=*/10);
  sender_.impl_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType);
  sender_.impl_->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads);

  // `start_timestamp` is the only timestamp populate in the RTX state.
  const uint32_t kStartTimestamp = 3456;
  sender_.impl_->SetStartTimestamp(kStartTimestamp);

  // Send a frame and ask for a retransmit of the last packet. Capture the RTX
  // packet in order to verify RTX sequence number.
  EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
  time_controller_.AdvanceTime(TimeDelta::Millis(5));
  sender_.impl_->OnReceivedNack(
      std::vector<uint16_t>{sender_.transport_.last_packet_.SequenceNumber()});
  RtpPacketReceived& rtx_packet = sender_.transport_.last_packet_;
  EXPECT_EQ(rtx_packet.Ssrc(), kRtxSenderSsrc);

  // Simulate an RTCP receiver report in order to populate `ssrc_has_acked`.
  ReportBlockData ack[1];
  ack[0].set_source_ssrc(kRtxSenderSsrc);
  ack[0].set_extended_highest_sequence_number(rtx_packet.SequenceNumber());
  sender_.impl_->OnReceivedRtcpReportBlocks(ack);

  RtpState rtp_state = sender_.impl_->GetRtpState();
  RtpState rtx_state = sender_.impl_->GetRtxState();
  EXPECT_EQ(rtx_state.start_timestamp, kStartTimestamp);
  EXPECT_EQ(rtx_state.ssrc_has_acked, true);
  EXPECT_EQ(rtx_state.sequence_number, rtx_packet.SequenceNumber() + 1);

  // Reset sender, advance time, restore state. Directly observing state
  // is not feasible, so just verify returned state matches what we set.
  // Needs SetRtpState() too in order to propagate start timestamp.
  sender_.CreateModuleImpl();
  time_controller_.AdvanceTime(TimeDelta::Millis(10));
  sender_.impl_->SetRtpState(rtp_state);
  sender_.impl_->SetRtxState(rtx_state);

  rtx_state = sender_.impl_->GetRtxState();
  EXPECT_EQ(rtx_state.start_timestamp, kStartTimestamp);
  EXPECT_EQ(rtx_state.ssrc_has_acked, true);
  EXPECT_EQ(rtx_state.sequence_number, rtx_packet.SequenceNumber() + 1);
}

TEST_F(RtpRtcpImpl2Test, CanSendPacketReturnTrueForMediaPacketIfSendingMedia) {
  RtpHeaderExtensionMap extensions;
  RtpPacketToSend packet(&extensions);
  packet.SetSsrc(sender_.impl_->SSRC());
  packet.set_packet_type(RtpPacketMediaType::kAudio);
  sender_.impl_->SetSendingMediaStatus(true);

  EXPECT_TRUE(sender_.impl_->CanSendPacket(packet));
}

TEST_F(RtpRtcpImpl2Test,
       CanSendPacketReturnFalseForMediaPacketIfNotSendingMedia) {
  RtpHeaderExtensionMap extensions;
  RtpPacketToSend packet(&extensions);
  packet.SetSsrc(sender_.impl_->SSRC());
  packet.set_packet_type(RtpPacketMediaType::kAudio);
  sender_.impl_->SetSendingMediaStatus(false);

  EXPECT_FALSE(sender_.impl_->CanSendPacket(packet));
}

TEST_F(RtpRtcpImpl2Test,
       CanSendPacketReturnFalseForPaddingPacketOnMediaSsrcBeforeMediaPacket) {
  RtpHeaderExtensionMap extensions;
  RtpPacketToSend packet(&extensions);
  packet.SetSsrc(sender_.impl_->SSRC());
  packet.set_packet_type(RtpPacketMediaType::kPadding);
  sender_.impl_->SetSendingMediaStatus(true);

  EXPECT_FALSE(sender_.impl_->CanSendPacket(packet));
}

TEST_F(RtpRtcpImpl2Test, RtpSequenceNumberSetByAssignSequenceNumber) {
  RtpHeaderExtensionMap extensions;
  RtpPacketToSend packet(&extensions);
  packet.SetSsrc(sender_.impl_->SSRC());

  sender_.impl_->SetSequenceNumber(1);
  sender_.impl_->AssignSequenceNumber(packet);
  EXPECT_EQ(packet.SequenceNumber(), 1);
  sender_.impl_->AssignSequenceNumber(packet);
  EXPECT_EQ(packet.SequenceNumber(), 2);
}

TEST_F(RtpRtcpImpl2Test, SendPacketSendsPacketOnTransport) {
  RtpHeaderExtensionMap extensions;
  auto packet = std::make_unique<RtpPacketToSend>(&extensions);
  packet->SetSsrc(sender_.impl_->SSRC());
  packet->set_packet_type(RtpPacketMediaType::kAudio);

  sender_.impl_->SendPacket(std::move(packet), PacedPacketInfo());
  EXPECT_EQ(sender_.RtpSent(), 1);
}

}  // namespace webrtc
