text: /*
   *  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.
   */
  
  #include "modules/rtp_rtcp/source/rtp_sender.h"
  
  #include <memory>
  #include <vector>
  
  #include "api/rtc_event_log/rtc_event.h"
  #include "api/transport/field_trial_based_config.h"
  #include "api/video/video_codec_constants.h"
  #include "api/video/video_timing.h"
  #include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
  #include "modules/rtp_rtcp/include/rtp_cvo.h"
  #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
  #include "modules/rtp_rtcp/include/rtp_packet_sender.h"
  #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
  #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
  #include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
  #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
  #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.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_packet_to_send.h"
  #include "modules/rtp_rtcp/source/rtp_sender_egress.h"
  #include "modules/rtp_rtcp/source/rtp_sender_video.h"
  #include "modules/rtp_rtcp/source/rtp_utility.h"
  #include "rtc_base/arraysize.h"
  #include "rtc_base/rate_limiter.h"
  #include "test/field_trial.h"
  #include "test/gmock.h"
  #include "test/gtest.h"
  #include "test/mock_transport.h"
  #include "test/rtp_header_parser.h"
  
  namespace webrtc {
  
  namespace {
  enum : int {  // The first valid value is 1.
    kAbsoluteSendTimeExtensionId = 1,
    kAudioLevelExtensionId,
    kGenericDescriptorId00,
    kGenericDescriptorId01,
    kMidExtensionId,
    kRepairedRidExtensionId,
    kRidExtensionId,
    kTransmissionTimeOffsetExtensionId,
    kTransportSequenceNumberExtensionId,
    kVideoRotationExtensionId,
    kVideoTimingExtensionId,
  };
  
  const int kPayload = 100;
  const int kRtxPayload = 98;
  const uint32_t kTimestamp = 10;
  const uint16_t kSeqNum = 33;
  const uint32_t kSsrc = 725242;
  const uint32_t kRtxSsrc = 12345;
  const uint32_t kFlexFecSsrc = 45678;
  const uint16_t kTransportSequenceNumber = 1;
  const uint64_t kStartTime = 123456789;
  const size_t kMaxPaddingSize = 224u;
  const uint8_t kPayloadData[] = {47, 11, 32, 93, 89};
  const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
  const char kNoRid[] = "";
  const char kNoMid[] = "";
  
  using ::testing::_;
  using ::testing::AllOf;
  using ::testing::Contains;
  using ::testing::ElementsAreArray;
  using ::testing::Field;
  using ::testing::NiceMock;
  using ::testing::Pointee;
  using ::testing::Property;
  using ::testing::Return;
  using ::testing::StrictMock;
  
  uint64_t ConvertMsToAbsSendTime(int64_t time_ms) {
    return (((time_ms << 18) + 500) / 1000) & 0x00ffffff;
  }
  
  class LoopbackTransportTest : public webrtc::Transport {
   public:
    LoopbackTransportTest() : total_bytes_sent_(0) {
      receivers_extensions_.Register<TransmissionOffset>(
          kTransmissionTimeOffsetExtensionId);
      receivers_extensions_.Register<AbsoluteSendTime>(
          kAbsoluteSendTimeExtensionId);
      receivers_extensions_.Register<TransportSequenceNumber>(
          kTransportSequenceNumberExtensionId);
      receivers_extensions_.Register<VideoOrientation>(kVideoRotationExtensionId);
      receivers_extensions_.Register<AudioLevel>(kAudioLevelExtensionId);
      receivers_extensions_.Register<VideoTimingExtension>(
          kVideoTimingExtensionId);
      receivers_extensions_.Register<RtpMid>(kMidExtensionId);
      receivers_extensions_.Register<RtpGenericFrameDescriptorExtension00>(
          kGenericDescriptorId00);
      receivers_extensions_.Register<RtpGenericFrameDescriptorExtension01>(
          kGenericDescriptorId01);
      receivers_extensions_.Register<RtpStreamId>(kRidExtensionId);
      receivers_extensions_.Register<RepairedRtpStreamId>(
          kRepairedRidExtensionId);
    }
  
    bool SendRtp(const uint8_t* data,
                 size_t len,
                 const PacketOptions& options) override {
      last_options_ = options;
      total_bytes_sent_ += len;
      sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
      EXPECT_TRUE(sent_packets_.back().Parse(data, len));
      return true;
    }
    bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
    const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
    int packets_sent() { return sent_packets_.size(); }
  
    size_t total_bytes_sent_;
    PacketOptions last_options_;
    std::vector<RtpPacketReceived> sent_packets_;
  
   private:
    RtpHeaderExtensionMap receivers_extensions_;
  };
  
  MATCHER_P(SameRtcEventTypeAs, value, "") {
    return value == arg->GetType();
  }
  
  struct TestConfig {
    explicit TestConfig(bool with_overhead) : with_overhead(with_overhead) {}
    bool with_overhead = false;
  };
  
  std::string ToFieldTrialString(TestConfig config) {
    std::string field_trials;
    if (config.with_overhead) {
      field_trials += "WebRTC-SendSideBwe-WithOverhead/Enabled/";
    }
    return field_trials;
  }
  
  class MockRtpPacketPacer : public RtpPacketSender {
   public:
    MockRtpPacketPacer() {}
    virtual ~MockRtpPacketPacer() {}
  
    MOCK_METHOD1(EnqueuePackets,
                 void(std::vector<std::unique_ptr<RtpPacketToSend>>));
  
    MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id));
  
    MOCK_METHOD0(Pause, void());
    MOCK_METHOD0(Resume, void());
    MOCK_METHOD1(SetCongestionWindow,
                 void(absl::optional<int64_t> congestion_window_bytes));
    MOCK_METHOD1(UpdateOutstandingData, void(int64_t outstanding_bytes));
    MOCK_METHOD1(SetAccountForAudioPackets, void(bool account_for_audio));
  };
  
  class MockSendSideDelayObserver : public SendSideDelayObserver {
   public:
    MOCK_METHOD4(SendSideDelayUpdated, void(int, int, uint64_t, uint32_t));
  };
  
  class MockSendPacketObserver : public SendPacketObserver {
   public:
    MOCK_METHOD3(OnSendPacket, void(uint16_t, int64_t, uint32_t));
  };
  
  class MockTransportFeedbackObserver : public TransportFeedbackObserver {
   public:
    MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
    MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
  };
  
  class MockOverheadObserver : public OverheadObserver {
   public:
    MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet));
  };
  
  class StreamDataTestCallback : public StreamDataCountersCallback {
   public:
    StreamDataTestCallback()
        : StreamDataCountersCallback(), ssrc_(0), counters_() {}
    ~StreamDataTestCallback() override = default;
  
    void DataCountersUpdated(const StreamDataCounters& counters,
                             uint32_t ssrc) override {
      ssrc_ = ssrc;
      counters_ = counters;
    }
  
    uint32_t ssrc_;
    StreamDataCounters counters_;
  
    void MatchPacketCounter(const RtpPacketCounter& expected,
                            const RtpPacketCounter& actual) {
      EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
      EXPECT_EQ(expected.header_bytes, actual.header_bytes);
      EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
      EXPECT_EQ(expected.packets, actual.packets);
    }
  
    void Matches(uint32_t ssrc, const StreamDataCounters& counters) {
      EXPECT_EQ(ssrc, ssrc_);
      MatchPacketCounter(counters.transmitted, counters_.transmitted);
      MatchPacketCounter(counters.retransmitted, counters_.retransmitted);
      EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
    }
  };
  
  // Mimics ModuleRtpRtcp::RtpSenderContext.
  // TODO(sprang): Split up unit tests and test these components individually
  // wherever possible.
  struct RtpSenderContext {
    explicit RtpSenderContext(const RtpRtcp::Configuration& config)
        : packet_history_(config.clock),
          packet_sender_(config, &packet_history_),
          non_paced_sender_(&packet_sender_),
          packet_generator_(
              config,
              &packet_history_,
              config.paced_sender ? config.paced_sender : &non_paced_sender_) {}
    RtpPacketHistory packet_history_;
    RtpSenderEgress packet_sender_;
    RtpSenderEgress::NonPacedPacketSender non_paced_sender_;
    RTPSender packet_generator_;
  };
  
  }  // namespace
  
  class RtpSenderTest : public ::testing::TestWithParam<TestConfig> {
   protected:
    RtpSenderTest()
        : fake_clock_(kStartTime),
          retransmission_rate_limiter_(&fake_clock_, 1000),
          flexfec_sender_(0,
                          kFlexFecSsrc,
                          kSsrc,
                          "",
                          std::vector<RtpExtension>(),
                          std::vector<RtpExtensionSize>(),
                          nullptr,
                          &fake_clock_),
          kMarkerBit(true),
          field_trials_(ToFieldTrialString(GetParam())) {}
  
    void SetUp() override { SetUpRtpSender(true, false, false); }
  
    RTPSender* rtp_sender() {
      RTC_DCHECK(rtp_sender_context_);
      return &rtp_sender_context_->packet_generator_;
    }
  
    RtpSenderEgress* rtp_egress() {
      RTC_DCHECK(rtp_sender_context_);
      return &rtp_sender_context_->packet_sender_;
    }
  
    void SetUpRtpSender(bool pacer,
                        bool populate_network2,
                        bool always_send_mid_and_rid) {
      RtpRtcp::Configuration config;
      config.clock = &fake_clock_;
      config.outgoing_transport = &transport_;
      config.local_media_ssrc = kSsrc;
      config.rtx_send_ssrc = kRtxSsrc;
      config.fec_generator = &flexfec_sender_;
      config.event_log = &mock_rtc_event_log_;
      config.send_packet_observer = &send_packet_observer_;
      config.retransmission_rate_limiter = &retransmission_rate_limiter_;
      config.paced_sender = pacer ? &mock_paced_sender_ : nullptr;
      config.populate_network2_timestamp = populate_network2;
      config.rtp_stats_callback = &rtp_stats_callback_;
      config.always_send_mid_and_rid = always_send_mid_and_rid;
      rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
      rtp_sender()->SetSequenceNumber(kSeqNum);
      rtp_sender()->SetTimestampOffset(0);
    }
  
    SimulatedClock fake_clock_;
    NiceMock<MockRtcEventLog> mock_rtc_event_log_;
    MockRtpPacketPacer mock_paced_sender_;
    StrictMock<MockSendPacketObserver> send_packet_observer_;
    StrictMock<MockTransportFeedbackObserver> feedback_observer_;
    RateLimiter retransmission_rate_limiter_;
    FlexfecSender flexfec_sender_;
  
    std::unique_ptr<RtpSenderContext> rtp_sender_context_;
  
    LoopbackTransportTest transport_;
    const bool kMarkerBit;
    test::ScopedFieldTrials field_trials_;
    StreamDataTestCallback rtp_stats_callback_;
  
    std::unique_ptr<RtpPacketToSend> BuildRtpPacket(int payload_type,
                                                    bool marker_bit,
                                                    uint32_t timestamp,
                                                    int64_t capture_time_ms) {
      auto packet = rtp_sender()->AllocatePacket();
      packet->SetPayloadType(payload_type);
      packet->set_packet_type(RtpPacketMediaType::kVideo);
      packet->SetMarker(marker_bit);
      packet->SetTimestamp(timestamp);
      packet->set_capture_time_ms(capture_time_ms);
      EXPECT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
      return packet;
    }
  
    std::unique_ptr<RtpPacketToSend> SendPacket(int64_t capture_time_ms,
                                                int payload_length) {
      uint32_t timestamp = capture_time_ms * 90;
      auto packet =
          BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
      packet->AllocatePayload(payload_length);
      packet->set_allow_retransmission(true);
  
      // Packet should be stored in a send bucket.
      EXPECT_TRUE(rtp_sender()->SendToNetwork(
          std::make_unique<RtpPacketToSend>(*packet)));
      return packet;
    }
  
    std::unique_ptr<RtpPacketToSend> SendGenericPacket() {
      const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
      return SendPacket(kCaptureTimeMs, sizeof(kPayloadData));
    }
  
    size_t GenerateAndSendPadding(size_t target_size_bytes) {
      size_t generated_bytes = 0;
      for (auto& packet :
           rtp_sender()->GeneratePadding(target_size_bytes, true)) {
        generated_bytes += packet->payload_size() + packet->padding_size();
        rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
      }
      return generated_bytes;
    }
  
    // The following are helpers for configuring the RTPSender. They must be
    // called before sending any packets.
  
    // Enable the retransmission stream with sizable packet storage.
    void EnableRtx() {
      // RTX needs to be able to read the source packets from the packet store.
      // Pick a number of packets to store big enough for any unit test.
      constexpr uint16_t kNumberOfPacketsToStore = 100;
      rtp_sender_context_->packet_history_.SetStorePacketsStatus(
          RtpPacketHistory::StorageMode::kStoreAndCull, kNumberOfPacketsToStore);
      rtp_sender()->SetRtxPayloadType(kRtxPayload, kPayload);
      rtp_sender()->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
    }
  
    // Enable sending of the MID header extension for both the primary SSRC and
    // the RTX SSRC.
    void EnableMidSending(const std::string& mid) {
      rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionMid, kMidExtensionId);
      rtp_sender()->SetMid(mid);
    }
  
    // Enable sending of the RSID header extension for the primary SSRC and the
    // RRSID header extension for the RTX SSRC.
    void EnableRidSending(const std::string& rid) {
      rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
                                               kRidExtensionId);
      rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionRepairedRtpStreamId,
                                               kRepairedRidExtensionId);
      rtp_sender()->SetRid(rid);
    }
  };
  
  // TODO(pbos): Move tests over from WithoutPacer to RtpSenderTest as this is our
  // default code path.
  class RtpSenderTestWithoutPacer : public RtpSenderTest {
   public:
    void SetUp() override { SetUpRtpSender(false, false, false); }
  };
  
  TEST_P(RtpSenderTestWithoutPacer, AllocatePacketSetCsrc) {
    // Configure rtp_sender with csrc.
    std::vector<uint32_t> csrcs;
    csrcs.push_back(0x23456789);
    rtp_sender()->SetCsrcs(csrcs);
  
    auto packet = rtp_sender()->AllocatePacket();
  
    ASSERT_TRUE(packet);
    EXPECT_EQ(rtp_sender()->SSRC(), packet->Ssrc());
    EXPECT_EQ(csrcs, packet->Csrcs());
  }
  
  TEST_P(RtpSenderTestWithoutPacer, AllocatePacketReserveExtensions) {
    // Configure rtp_sender with extensions.
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransmissionTimeOffset,
                     kTransmissionTimeOffsetExtensionId));
    ASSERT_EQ(0,
              rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionAudioLevel, kAudioLevelExtensionId));
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionVideoRotation, kVideoRotationExtensionId));
  
    auto packet = rtp_sender()->AllocatePacket();
  
    ASSERT_TRUE(packet);
    // Preallocate BWE extensions RtpSender set itself.
    EXPECT_TRUE(packet->HasExtension<TransmissionOffset>());
    EXPECT_TRUE(packet->HasExtension<AbsoluteSendTime>());
    EXPECT_TRUE(packet->HasExtension<TransportSequenceNumber>());
    // Do not allocate media specific extensions.
    EXPECT_FALSE(packet->HasExtension<AudioLevel>());
    EXPECT_FALSE(packet->HasExtension<VideoOrientation>());
  }
  
  TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberAdvanceSequenceNumber) {
    auto packet = rtp_sender()->AllocatePacket();
    ASSERT_TRUE(packet);
    const uint16_t sequence_number = rtp_sender()->SequenceNumber();
  
    EXPECT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
  
    EXPECT_EQ(sequence_number, packet->SequenceNumber());
    EXPECT_EQ(sequence_number + 1, rtp_sender()->SequenceNumber());
  }
  
  TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberFailsOnNotSending) {
    auto packet = rtp_sender()->AllocatePacket();
    ASSERT_TRUE(packet);
  
    rtp_sender()->SetSendingMediaStatus(false);
    EXPECT_FALSE(rtp_sender()->AssignSequenceNumber(packet.get()));
  }
  
  TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberMayAllowPaddingOnVideo) {
    constexpr size_t kPaddingSize = 100;
    auto packet = rtp_sender()->AllocatePacket();
    ASSERT_TRUE(packet);
  
    ASSERT_TRUE(rtp_sender()->GeneratePadding(kPaddingSize, true).empty());
    packet->SetMarker(false);
    ASSERT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
    // Packet without marker bit doesn't allow padding on video stream.
    ASSERT_TRUE(rtp_sender()->GeneratePadding(kPaddingSize, true).empty());
  
    packet->SetMarker(true);
    ASSERT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
    // Packet with marker bit allows send padding.
    ASSERT_FALSE(rtp_sender()->GeneratePadding(kPaddingSize, true).empty());
  }
  
  TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
    MockTransport transport;
    RtpRtcp::Configuration config;
    config.audio = true;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport;
    config.paced_sender = &mock_paced_sender_;
    config.local_media_ssrc = kSsrc;
    config.event_log = &mock_rtc_event_log_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    rtp_sender()->SetTimestampOffset(0);
  
    std::unique_ptr<RtpPacketToSend> audio_packet =
        rtp_sender()->AllocatePacket();
    // Padding on audio stream allowed regardless of marker in the last packet.
    audio_packet->SetMarker(false);
    audio_packet->SetPayloadType(kPayload);
    rtp_sender()->AssignSequenceNumber(audio_packet.get());
  
    const size_t kPaddingSize = 59;
    EXPECT_CALL(transport, SendRtp(_, kPaddingSize + kRtpHeaderSize, _))
        .WillOnce(Return(true));
    EXPECT_EQ(kPaddingSize, GenerateAndSendPadding(kPaddingSize));
  
    // Requested padding size is too small, will send a larger one.
    const size_t kMinPaddingSize = 50;
    EXPECT_CALL(transport, SendRtp(_, kMinPaddingSize + kRtpHeaderSize, _))
        .WillOnce(Return(true));
    EXPECT_EQ(kMinPaddingSize, GenerateAndSendPadding(kMinPaddingSize - 5));
  }
  
  TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
    constexpr size_t kPaddingSize = 100;
    auto packet = rtp_sender()->AllocatePacket();
    ASSERT_TRUE(packet);
    packet->SetMarker(true);
    packet->SetTimestamp(kTimestamp);
  
    ASSERT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
    auto padding_packets = rtp_sender()->GeneratePadding(kPaddingSize, true);
  
    ASSERT_EQ(1u, padding_packets.size());
    // Verify padding packet timestamp.
    EXPECT_EQ(kTimestamp, padding_packets[0]->Timestamp());
  }
  
  TEST_P(RtpSenderTestWithoutPacer,
         TransportFeedbackObserverGetsCorrectByteCount) {
    constexpr int kRtpOverheadBytesPerPacket = 12 + 8;
    NiceMock<MockOverheadObserver> mock_overhead_observer;
  
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.transport_feedback_callback = &feedback_observer_;
    config.event_log = &mock_rtc_event_log_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    config.overhead_observer = &mock_overhead_observer;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
  
    const size_t expected_bytes =
        GetParam().with_overhead
            ? sizeof(kPayloadData) + kRtpOverheadBytesPerPacket
            : sizeof(kPayloadData);
  
    EXPECT_CALL(feedback_observer_,
                OnAddPacket(AllOf(
                    Field(&RtpPacketSendInfo::ssrc, rtp_sender()->SSRC()),
                    Field(&RtpPacketSendInfo::transport_sequence_number,
                          kTransportSequenceNumber),
                    Field(&RtpPacketSendInfo::rtp_sequence_number,
                          rtp_sender()->SequenceNumber()),
                    Field(&RtpPacketSendInfo::length, expected_bytes),
                    Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
        .Times(1);
    EXPECT_CALL(mock_overhead_observer,
                OnOverheadChanged(kRtpOverheadBytesPerPacket))
        .Times(1);
    SendGenericPacket();
  }
  
  TEST_P(RtpSenderTestWithoutPacer, SendsPacketsWithTransportSequenceNumber) {
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.transport_feedback_callback = &feedback_observer_;
    config.event_log = &mock_rtc_event_log_;
    config.send_packet_observer = &send_packet_observer_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
  
    EXPECT_CALL(send_packet_observer_,
                OnSendPacket(kTransportSequenceNumber, _, _))
        .Times(1);
  
    EXPECT_CALL(feedback_observer_,
                OnAddPacket(AllOf(
                    Field(&RtpPacketSendInfo::ssrc, rtp_sender()->SSRC()),
                    Field(&RtpPacketSendInfo::transport_sequence_number,
                          kTransportSequenceNumber),
                    Field(&RtpPacketSendInfo::rtp_sequence_number,
                          rtp_sender()->SequenceNumber()),
                    Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
        .Times(1);
  
    SendGenericPacket();
  
    const auto& packet = transport_.last_sent_packet();
    uint16_t transport_seq_no;
    ASSERT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
    EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
    EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
    EXPECT_TRUE(transport_.last_options_.included_in_allocation);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, PacketOptionsNoRetransmission) {
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.transport_feedback_callback = &feedback_observer_;
    config.event_log = &mock_rtc_event_log_;
    config.send_packet_observer = &send_packet_observer_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    SendGenericPacket();
  
    EXPECT_FALSE(transport_.last_options_.is_retransmit);
  }
  
  TEST_P(RtpSenderTestWithoutPacer,
         SetsIncludedInFeedbackWhenTransportSequenceNumberExtensionIsRegistered) {
    SetUpRtpSender(false, false, false);
    rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
                                             kTransportSequenceNumberExtensionId);
    EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
    SendGenericPacket();
    EXPECT_TRUE(transport_.last_options_.included_in_feedback);
  }
  
  TEST_P(
      RtpSenderTestWithoutPacer,
      SetsIncludedInAllocationWhenTransportSequenceNumberExtensionIsRegistered) {
    SetUpRtpSender(false, false, false);
    rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
                                             kTransportSequenceNumberExtensionId);
    EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
    SendGenericPacket();
    EXPECT_TRUE(transport_.last_options_.included_in_allocation);
  }
  
  TEST_P(RtpSenderTestWithoutPacer,
         SetsIncludedInAllocationWhenForcedAsPartOfAllocation) {
    SetUpRtpSender(false, false, false);
    rtp_egress()->ForceIncludeSendPacketsInAllocation(true);
    SendGenericPacket();
    EXPECT_FALSE(transport_.last_options_.included_in_feedback);
    EXPECT_TRUE(transport_.last_options_.included_in_allocation);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, DoesnSetIncludedInAllocationByDefault) {
    SetUpRtpSender(false, false, false);
    SendGenericPacket();
    EXPECT_FALSE(transport_.last_options_.included_in_feedback);
    EXPECT_FALSE(transport_.last_options_.included_in_allocation);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
    StrictMock<MockSendSideDelayObserver> send_side_delay_observer_;
  
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.send_side_delay_observer = &send_side_delay_observer_;
    config.event_log = &mock_rtc_event_log_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
  
    const uint8_t kPayloadType = 127;
    const absl::optional<VideoCodecType> kCodecType =
        VideoCodecType::kVideoCodecGeneric;
  
    const uint32_t kCaptureTimeMsToRtpTimestamp = 90;  // 90 kHz clock
    RTPVideoHeader video_header;
  
    // Send packet with 10 ms send-side delay. The average, max and total should
    // be 10 ms.
    EXPECT_CALL(send_side_delay_observer_,
                SendSideDelayUpdated(10, 10, 10, kSsrc))
        .Times(1);
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    fake_clock_.AdvanceTimeMilliseconds(10);
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    EXPECT_TRUE(rtp_sender_video.SendVideo(
        kPayloadType, kCodecType, capture_time_ms * kCaptureTimeMsToRtpTimestamp,
        capture_time_ms, kPayloadData, nullptr, video_header,
        kDefaultExpectedRetransmissionTimeMs));
  
    // Send another packet with 20 ms delay. The average, max and total should be
    // 15, 20 and 30 ms respectively.
    EXPECT_CALL(send_side_delay_observer_,
                SendSideDelayUpdated(15, 20, 30, kSsrc))
        .Times(1);
    fake_clock_.AdvanceTimeMilliseconds(10);
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    EXPECT_TRUE(rtp_sender_video.SendVideo(
        kPayloadType, kCodecType, capture_time_ms * kCaptureTimeMsToRtpTimestamp,
        capture_time_ms, kPayloadData, nullptr, video_header,
        kDefaultExpectedRetransmissionTimeMs));
  
    // Send another packet at the same time, which replaces the last packet.
    // Since this packet has 0 ms delay, the average is now 5 ms and max is 10 ms.
    // The total counter stays the same though.
    // TODO(terelius): Is is not clear that this is the right behavior.
    EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(5, 10, 30, kSsrc))
        .Times(1);
    capture_time_ms = fake_clock_.TimeInMilliseconds();
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    EXPECT_TRUE(rtp_sender_video.SendVideo(
        kPayloadType, kCodecType, capture_time_ms * kCaptureTimeMsToRtpTimestamp,
        capture_time_ms, kPayloadData, nullptr, video_header,
        kDefaultExpectedRetransmissionTimeMs));
  
    // Send a packet 1 second later. The earlier packets should have timed
    // out, so both max and average should be the delay of this packet. The total
    // keeps increasing.
    fake_clock_.AdvanceTimeMilliseconds(1000);
    capture_time_ms = fake_clock_.TimeInMilliseconds();
    fake_clock_.AdvanceTimeMilliseconds(1);
    EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(1, 1, 31, kSsrc))
        .Times(1);
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    EXPECT_TRUE(rtp_sender_video.SendVideo(
        kPayloadType, kCodecType, capture_time_ms * kCaptureTimeMsToRtpTimestamp,
        capture_time_ms, kPayloadData, nullptr, video_header,
        kDefaultExpectedRetransmissionTimeMs));
  }
  
  TEST_P(RtpSenderTestWithoutPacer, OnSendPacketUpdated) {
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
    EXPECT_CALL(send_packet_observer_,
                OnSendPacket(kTransportSequenceNumber, _, _))
        .Times(1);
  
    SendGenericPacket();
  }
  
  TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) {
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.paced_sender = &mock_paced_sender_;
    config.local_media_ssrc = kSsrc;
    config.transport_feedback_callback = &feedback_observer_;
    config.event_log = &mock_rtc_event_log_;
    config.send_packet_observer = &send_packet_observer_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    rtp_sender()->SetSequenceNumber(kSeqNum);
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
  
    EXPECT_CALL(send_packet_observer_,
                OnSendPacket(kTransportSequenceNumber, _, _))
        .Times(1);
    EXPECT_CALL(feedback_observer_,
                OnAddPacket(AllOf(
                    Field(&RtpPacketSendInfo::ssrc, rtp_sender()->SSRC()),
                    Field(&RtpPacketSendInfo::transport_sequence_number,
                          kTransportSequenceNumber),
                    Field(&RtpPacketSendInfo::rtp_sequence_number,
                          rtp_sender()->SequenceNumber()),
                    Field(&RtpPacketSendInfo::pacing_info, PacedPacketInfo()))))
        .Times(1);
  
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
    auto packet = SendGenericPacket();
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    // Transport sequence number is set by PacketRouter, before SendPacket().
    packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    uint16_t transport_seq_no;
    EXPECT_TRUE(
        transport_.last_sent_packet().GetExtension<TransportSequenceNumber>(
            &transport_seq_no));
    EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
    EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
  }
  
  TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) {
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionVideoTiming, kVideoTimingExtensionId));
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    auto packet = rtp_sender()->AllocatePacket();
    packet->SetPayloadType(kPayload);
    packet->SetMarker(true);
    packet->SetTimestamp(kTimestamp);
    packet->set_capture_time_ms(capture_time_ms);
    const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
    packet->SetExtension<VideoTimingExtension>(kVideoTiming);
    EXPECT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
    size_t packet_size = packet->size();
  
    const int kStoredTimeInMs = 100;
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_CALL(mock_paced_sender_, EnqueuePackets(Contains(Pointee(Property(
                                        &RtpPacketToSend::Ssrc, kSsrc)))));
    EXPECT_TRUE(
        rtp_sender()->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(1, transport_.packets_sent());
    EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
  
    VideoSendTiming video_timing;
    EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
        &video_timing));
    EXPECT_EQ(kStoredTimeInMs, video_timing.pacer_exit_delta_ms);
  }
  
  TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithPacer) {
    SetUpRtpSender(/*pacer=*/true, /*populate_network2=*/true, false);
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionVideoTiming, kVideoTimingExtensionId));
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    auto packet = rtp_sender()->AllocatePacket();
    packet->SetPayloadType(kPayload);
    packet->SetMarker(true);
    packet->SetTimestamp(kTimestamp);
    packet->set_capture_time_ms(capture_time_ms);
    const uint16_t kPacerExitMs = 1234u;
    const VideoSendTiming kVideoTiming = {0u, 0u, 0u, kPacerExitMs, 0u, 0u, true};
    packet->SetExtension<VideoTimingExtension>(kVideoTiming);
    EXPECT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
    size_t packet_size = packet->size();
  
    const int kStoredTimeInMs = 100;
  
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_CALL(mock_paced_sender_, EnqueuePackets(Contains(Pointee(Property(
                                        &RtpPacketToSend::Ssrc, kSsrc)))));
    EXPECT_TRUE(
        rtp_sender()->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    EXPECT_EQ(1, transport_.packets_sent());
    EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
  
    VideoSendTiming video_timing;
    EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
        &video_timing));
    EXPECT_EQ(kStoredTimeInMs, video_timing.network2_timestamp_delta_ms);
    EXPECT_EQ(kPacerExitMs, video_timing.pacer_exit_delta_ms);
  }
  
  TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithoutPacer) {
    SetUpRtpSender(/*pacer=*/false, /*populate_network2=*/true, false);
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionVideoTiming, kVideoTimingExtensionId));
    auto packet = rtp_sender()->AllocatePacket();
    packet->SetMarker(true);
    packet->set_capture_time_ms(fake_clock_.TimeInMilliseconds());
    const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
    packet->SetExtension<VideoTimingExtension>(kVideoTiming);
    packet->set_allow_retransmission(true);
    EXPECT_TRUE(rtp_sender()->AssignSequenceNumber(packet.get()));
    packet->set_packet_type(RtpPacketMediaType::kVideo);
  
    const int kPropagateTimeMs = 10;
    fake_clock_.AdvanceTimeMilliseconds(kPropagateTimeMs);
  
    EXPECT_TRUE(rtp_sender()->SendToNetwork(std::move(packet)));
  
    EXPECT_EQ(1, transport_.packets_sent());
    absl::optional<VideoSendTiming> video_timing =
        transport_.last_sent_packet().GetExtension<VideoTimingExtension>();
    ASSERT_TRUE(video_timing);
    EXPECT_EQ(kPropagateTimeMs, video_timing->network2_timestamp_delta_ms);
  }
  
  TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) {
    EXPECT_CALL(mock_rtc_event_log_,
                LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
  
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransmissionTimeOffset,
                     kTransmissionTimeOffsetExtensionId));
    EXPECT_EQ(0,
              rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    auto packet =
        BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
    size_t packet_size = packet->size();
  
    const int kStoredTimeInMs = 100;
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_TRUE(
        rtp_sender()->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
    EXPECT_EQ(0, transport_.packets_sent());
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    // Process send bucket. Packet should now be sent.
    EXPECT_EQ(1, transport_.packets_sent());
    EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
  
    webrtc::RTPHeader rtp_header;
    transport_.last_sent_packet().GetHeader(&rtp_header);
  
    // Verify transmission time offset.
    EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
    uint64_t expected_send_time =
        ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
    EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
  }
  
  TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) {
    EXPECT_CALL(mock_rtc_event_log_,
                LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
  
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransmissionTimeOffset,
                     kTransmissionTimeOffsetExtensionId));
    EXPECT_EQ(0,
              rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    auto packet =
        BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, capture_time_ms);
    size_t packet_size = packet->size();
  
    // Packet should be stored in a send bucket.
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_TRUE(
        rtp_sender()->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
    // Immediately process send bucket and send packet.
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    EXPECT_EQ(1, transport_.packets_sent());
  
    // Retransmit packet.
    const int kStoredTimeInMs = 100;
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
  
    EXPECT_CALL(mock_rtc_event_log_,
                LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)));
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    packet->set_retransmitted_sequence_number(kSeqNum);
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
    EXPECT_EQ(static_cast<int>(packet_size), rtp_sender()->ReSendPacket(kSeqNum));
    EXPECT_EQ(1, transport_.packets_sent());
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    // Process send bucket. Packet should now be sent.
    EXPECT_EQ(2, transport_.packets_sent());
    EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
  
    webrtc::RTPHeader rtp_header;
    transport_.last_sent_packet().GetHeader(&rtp_header);
  
    // Verify transmission time offset.
    EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
    uint64_t expected_send_time =
        ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
    EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
  }
  
  // This test sends 1 regular video packet, then 4 padding packets, and then
  // 1 more regular packet.
  TEST_P(RtpSenderTest, SendPadding) {
    // Make all (non-padding) packets go to send queue.
    EXPECT_CALL(mock_rtc_event_log_,
                LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
        .Times(1 + 4 + 1);
  
    uint16_t seq_num = kSeqNum;
    uint32_t timestamp = kTimestamp;
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    size_t rtp_header_len = kRtpHeaderSize;
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransmissionTimeOffset,
                     kTransmissionTimeOffsetExtensionId));
    rtp_header_len += 4;  // 4 bytes extension.
    EXPECT_EQ(0,
              rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
    rtp_header_len += 4;  // 4 bytes extension.
    rtp_header_len += 4;  // 4 extra bytes common to all extension headers.
  
    webrtc::RTPHeader rtp_header;
  
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    auto packet =
        BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
    const uint32_t media_packet_timestamp = timestamp;
    size_t packet_size = packet->size();
    int total_packets_sent = 0;
    const int kStoredTimeInMs = 100;
  
    // Packet should be stored in a send bucket.
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_TRUE(
        rtp_sender()->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
    EXPECT_EQ(total_packets_sent, transport_.packets_sent());
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    ++seq_num;
  
    // Packet should now be sent. This test doesn't verify the regular video
    // packet, since it is tested in another test.
    EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
    timestamp += 90 * kStoredTimeInMs;
  
    // Send padding 4 times, waiting 50 ms between each.
    for (int i = 0; i < 4; ++i) {
      const int kPaddingPeriodMs = 50;
      const size_t kPaddingBytes = 100;
      const size_t kMaxPaddingLength = 224;  // Value taken from rtp_sender.cc.
      // Padding will be forced to full packets.
      EXPECT_EQ(kMaxPaddingLength, GenerateAndSendPadding(kPaddingBytes));
  
      // Process send bucket. Padding should now be sent.
      EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
      EXPECT_EQ(kMaxPaddingLength + rtp_header_len,
                transport_.last_sent_packet().size());
  
      transport_.last_sent_packet().GetHeader(&rtp_header);
      EXPECT_EQ(kMaxPaddingLength, rtp_header.paddingLength);
  
      // Verify sequence number and timestamp. The timestamp should be the same
      // as the last media packet.
      EXPECT_EQ(seq_num++, rtp_header.sequenceNumber);
      EXPECT_EQ(media_packet_timestamp, rtp_header.timestamp);
      // Verify transmission time offset.
      int offset = timestamp - media_packet_timestamp;
      EXPECT_EQ(offset, rtp_header.extension.transmissionTimeOffset);
      uint64_t expected_send_time =
          ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
      EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
      fake_clock_.AdvanceTimeMilliseconds(kPaddingPeriodMs);
      timestamp += 90 * kPaddingPeriodMs;
    }
  
    // Send a regular video packet again.
    capture_time_ms = fake_clock_.TimeInMilliseconds();
    packet = BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms);
    packet_size = packet->size();
  
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num))))));
    EXPECT_TRUE(
        rtp_sender()->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    // Process send bucket.
    EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
    EXPECT_EQ(packet_size, transport_.last_sent_packet().size());
    transport_.last_sent_packet().GetHeader(&rtp_header);
  
    // Verify sequence number and timestamp.
    EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
    EXPECT_EQ(timestamp, rtp_header.timestamp);
    // Verify transmission time offset. This packet is sent without delay.
    EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
    uint64_t expected_send_time =
        ConvertMsToAbsSendTime(fake_clock_.TimeInMilliseconds());
    EXPECT_EQ(expected_send_time, rtp_header.extension.absoluteSendTime);
  }
  
  TEST_P(RtpSenderTest, OnSendPacketUpdated) {
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
  
    EXPECT_CALL(send_packet_observer_,
                OnSendPacket(kTransportSequenceNumber, _, _))
        .Times(1);
  
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
    auto packet = SendGenericPacket();
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    EXPECT_EQ(1, transport_.packets_sent());
  }
  
  TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
    EXPECT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
  
    EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
  
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePackets(Contains(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
    auto packet = SendGenericPacket();
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    EXPECT_EQ(1, transport_.packets_sent());
    EXPECT_TRUE(transport_.last_options_.is_retransmit);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
    const uint8_t kPayloadType = 127;
    const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
    uint8_t payload[] = {47, 11, 32, 93, 89};
  
    // Send keyframe
    RTPVideoHeader video_header;
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    ASSERT_TRUE(rtp_sender_video.SendVideo(kPayloadType, kCodecType, 1234, 4321,
                                           payload, nullptr, video_header,
                                           kDefaultExpectedRetransmissionTimeMs));
  
    auto sent_payload = transport_.last_sent_packet().payload();
    uint8_t generic_header = sent_payload[0];
    EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
    EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
    EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
  
    // Send delta frame
    payload[0] = 13;
    payload[1] = 42;
    payload[4] = 13;
  
    video_header.frame_type = VideoFrameType::kVideoFrameDelta;
    ASSERT_TRUE(rtp_sender_video.SendVideo(kPayloadType, kCodecType, 1234, 4321,
                                           payload, nullptr, video_header,
                                           kDefaultExpectedRetransmissionTimeMs));
  
    sent_payload = transport_.last_sent_packet().payload();
    generic_header = sent_payload[0];
    EXPECT_FALSE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
    EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
    EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
  }
  
  TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) {
    const uint8_t kPayloadType = 111;
    const uint8_t payload[] = {11, 22, 33, 44, 55};
  
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
  
    // Send a frame.
    RTPVideoHeader video_header;
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    ASSERT_TRUE(rtp_sender_video.SendVideo(kPayloadType, absl::nullopt, 1234,
                                           4321, payload, nullptr, video_header,
                                           kDefaultExpectedRetransmissionTimeMs));
  
    auto sent_payload = transport_.last_sent_packet().payload();
    EXPECT_THAT(sent_payload, ElementsAreArray(payload));
  }
  
  TEST_P(RtpSenderTest, SendFlexfecPackets) {
    constexpr uint32_t kTimestamp = 1234;
    constexpr int kMediaPayloadType = 127;
    constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
    constexpr int kFlexfecPayloadType = 118;
    const std::vector<RtpExtension> kNoRtpExtensions;
    const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
    FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
                                 kNoRtpExtensions, kNoRtpExtensionSizes,
                                 nullptr /* rtp_state */, &fake_clock_);
  
    // Reset |rtp_sender_| to use FlexFEC.
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.paced_sender = &mock_paced_sender_;
    config.local_media_ssrc = kSsrc;
    config.fec_generator = &flexfec_sender_;
    config.event_log = &mock_rtc_event_log_;
    config.send_packet_observer = &send_packet_observer_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    rtp_sender()->SetSequenceNumber(kSeqNum);
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
  
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.fec_generator = &flexfec_sender;
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
  
    // 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;
    rtp_sender_video.SetFecParameters(params, params);
  
    uint16_t flexfec_seq_num;
    RTPVideoHeader video_header;
  
      std::unique_ptr<RtpPacketToSend> media_packet;
      std::unique_ptr<RtpPacketToSend> fec_packet;
  
      EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
          .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
            for (auto& packet : packets) {
              if (packet->packet_type() == RtpPacketMediaType::kVideo) {
                EXPECT_EQ(packet->Ssrc(), kSsrc);
                EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
                media_packet = std::move(packet);
              } else {
                EXPECT_EQ(packet->packet_type(),
                          RtpPacketMediaType::kForwardErrorCorrection);
                EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
                fec_packet = std::move(packet);
              }
            }
          });
  
      video_header.frame_type = VideoFrameType::kVideoFrameKey;
      EXPECT_TRUE(rtp_sender_video.SendVideo(
          kMediaPayloadType, kCodecType, kTimestamp,
          fake_clock_.TimeInMilliseconds(), kPayloadData, nullptr, video_header,
          kDefaultExpectedRetransmissionTimeMs));
      ASSERT_TRUE(media_packet != nullptr);
      ASSERT_TRUE(fec_packet != nullptr);
  
      flexfec_seq_num = fec_packet->SequenceNumber();
      rtp_egress()->SendPacket(media_packet.get(), PacedPacketInfo());
      rtp_egress()->SendPacket(fec_packet.get(), PacedPacketInfo());
  
      ASSERT_EQ(2, transport_.packets_sent());
      const RtpPacketReceived& sent_media_packet = transport_.sent_packets_[0];
      EXPECT_EQ(kMediaPayloadType, sent_media_packet.PayloadType());
      EXPECT_EQ(kSeqNum, sent_media_packet.SequenceNumber());
      EXPECT_EQ(kSsrc, sent_media_packet.Ssrc());
      const RtpPacketReceived& sent_flexfec_packet = transport_.sent_packets_[1];
      EXPECT_EQ(kFlexfecPayloadType, sent_flexfec_packet.PayloadType());
      EXPECT_EQ(flexfec_seq_num, sent_flexfec_packet.SequenceNumber());
      EXPECT_EQ(kFlexFecSsrc, sent_flexfec_packet.Ssrc());
  }
  
  TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
    constexpr uint32_t kTimestamp = 1234;
    constexpr int kMediaPayloadType = 127;
    constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
    constexpr int kFlexfecPayloadType = 118;
    const std::vector<RtpExtension> kNoRtpExtensions;
    const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
    FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
                                 kNoRtpExtensions, kNoRtpExtensionSizes,
                                 nullptr /* rtp_state */, &fake_clock_);
  
    // Reset |rtp_sender_| to use FlexFEC.
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.fec_generator = &flexfec_sender;
    config.event_log = &mock_rtc_event_log_;
    config.send_packet_observer = &send_packet_observer_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    rtp_sender()->SetSequenceNumber(kSeqNum);
  
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.fec_generator = &flexfec_sender;
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
  
    // 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;
    rtp_sender_video.SetFecParameters(params, params);
  
    EXPECT_CALL(mock_rtc_event_log_,
                LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
        .Times(2);
    RTPVideoHeader video_header;
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    EXPECT_TRUE(rtp_sender_video.SendVideo(
        kMediaPayloadType, kCodecType, kTimestamp,
        fake_clock_.TimeInMilliseconds(), kPayloadData, nullptr, video_header,
        kDefaultExpectedRetransmissionTimeMs));
  
    ASSERT_EQ(2, transport_.packets_sent());
    const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
    EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
    EXPECT_EQ(kSsrc, media_packet.Ssrc());
    const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
    EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
    EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
  }
  
  // Test that the MID header extension is included on sent packets when
  // configured.
  TEST_P(RtpSenderTestWithoutPacer, MidIncludedOnSentPackets) {
    const char kMid[] = "mid";
  
    EnableMidSending(kMid);
  
    // Send a couple packets.
    SendGenericPacket();
    SendGenericPacket();
  
    // Expect both packets to have the MID set.
    ASSERT_EQ(2u, transport_.sent_packets_.size());
    for (const RtpPacketReceived& packet : transport_.sent_packets_) {
      std::string mid;
      ASSERT_TRUE(packet.GetExtension<RtpMid>(&mid));
      EXPECT_EQ(kMid, mid);
    }
  }
  
  TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnSentPackets) {
    const char kRid[] = "f";
  
    EnableRidSending(kRid);
  
    SendGenericPacket();
  
    ASSERT_EQ(1u, transport_.sent_packets_.size());
    const RtpPacketReceived& packet = transport_.sent_packets_[0];
    std::string rid;
    ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
    EXPECT_EQ(kRid, rid);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnRtxSentPackets) {
    const char kRid[] = "f";
  
    EnableRtx();
    EnableRidSending(kRid);
  
    SendGenericPacket();
    ASSERT_EQ(1u, transport_.sent_packets_.size());
    const RtpPacketReceived& packet = transport_.sent_packets_[0];
    std::string rid;
    ASSERT_TRUE(packet.GetExtension<RtpStreamId>(&rid));
    EXPECT_EQ(kRid, rid);
    rid = kNoRid;
    EXPECT_FALSE(packet.HasExtension<RepairedRtpStreamId>());
  
    uint16_t packet_id = packet.SequenceNumber();
    rtp_sender()->ReSendPacket(packet_id);
    ASSERT_EQ(2u, transport_.sent_packets_.size());
    const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
    ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rid));
    EXPECT_EQ(kRid, rid);
    EXPECT_FALSE(rtx_packet.HasExtension<RtpStreamId>());
  }
  
  TEST_P(RtpSenderTestWithoutPacer, MidAndRidNotIncludedOnSentPacketsAfterAck) {
    const char kMid[] = "mid";
    const char kRid[] = "f";
  
    EnableMidSending(kMid);
    EnableRidSending(kRid);
  
    // This first packet should include both MID and RID.
    auto first_built_packet = SendGenericPacket();
  
    rtp_sender()->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
  
    // The second packet should include neither since an ack was received.
    SendGenericPacket();
  
    ASSERT_EQ(2u, transport_.sent_packets_.size());
  
    const RtpPacketReceived& first_packet = transport_.sent_packets_[0];
    std::string mid, rid;
    ASSERT_TRUE(first_packet.GetExtension<RtpMid>(&mid));
    EXPECT_EQ(kMid, mid);
    ASSERT_TRUE(first_packet.GetExtension<RtpStreamId>(&rid));
    EXPECT_EQ(kRid, rid);
  
    const RtpPacketReceived& second_packet = transport_.sent_packets_[1];
    EXPECT_FALSE(second_packet.HasExtension<RtpMid>());
    EXPECT_FALSE(second_packet.HasExtension<RtpStreamId>());
  }
  
  TEST_P(RtpSenderTestWithoutPacer,
         MidAndRidAlwaysIncludedOnSentPacketsWhenConfigured) {
    SetUpRtpSender(false, false, /*always_send_mid_and_rid=*/true);
    const char kMid[] = "mid";
    const char kRid[] = "f";
    EnableMidSending(kMid);
    EnableRidSending(kRid);
  
    // Send two media packets: one before and one after the ack.
    auto first_packet = SendGenericPacket();
    rtp_sender()->OnReceivedAckOnSsrc(first_packet->SequenceNumber());
    SendGenericPacket();
  
    // Due to the configuration, both sent packets should contain MID and RID.
    ASSERT_EQ(2u, transport_.sent_packets_.size());
    for (const RtpPacketReceived& packet : transport_.sent_packets_) {
      EXPECT_EQ(packet.GetExtension<RtpMid>(), kMid);
      EXPECT_EQ(packet.GetExtension<RtpStreamId>(), kRid);
    }
  }
  
  // Test that the first RTX packet includes both MID and RRID even if the packet
  // being retransmitted did not have MID or RID. The MID and RID are needed on
  // the first packets for a given SSRC, and RTX packets are sent on a separate
  // SSRC.
  TEST_P(RtpSenderTestWithoutPacer, MidAndRidIncludedOnFirstRtxPacket) {
    const char kMid[] = "mid";
    const char kRid[] = "f";
  
    EnableRtx();
    EnableMidSending(kMid);
    EnableRidSending(kRid);
  
    // This first packet will include both MID and RID.
    auto first_built_packet = SendGenericPacket();
    rtp_sender()->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
  
    // The second packet will include neither since an ack was received.
    auto second_built_packet = SendGenericPacket();
  
    // The first RTX packet should include MID and RRID.
    ASSERT_LT(0,
              rtp_sender()->ReSendPacket(second_built_packet->SequenceNumber()));
  
    ASSERT_EQ(3u, transport_.sent_packets_.size());
  
    const RtpPacketReceived& rtx_packet = transport_.sent_packets_[2];
    std::string mid, rrid;
    ASSERT_TRUE(rtx_packet.GetExtension<RtpMid>(&mid));
    EXPECT_EQ(kMid, mid);
    ASSERT_TRUE(rtx_packet.GetExtension<RepairedRtpStreamId>(&rrid));
    EXPECT_EQ(kRid, rrid);
  }
  
  // Test that the RTX packets sent after receving an ACK on the RTX SSRC does
  // not include either MID or RRID even if the packet being retransmitted did
  // had a MID or RID.
  TEST_P(RtpSenderTestWithoutPacer, MidAndRidNotIncludedOnRtxPacketsAfterAck) {
    const char kMid[] = "mid";
    const char kRid[] = "f";
  
    EnableRtx();
    EnableMidSending(kMid);
    EnableRidSending(kRid);
  
    // This first packet will include both MID and RID.
    auto first_built_packet = SendGenericPacket();
    rtp_sender()->OnReceivedAckOnSsrc(first_built_packet->SequenceNumber());
  
    // The second packet will include neither since an ack was received.
    auto second_built_packet = SendGenericPacket();
  
    // The first RTX packet will include MID and RRID.
    ASSERT_LT(0,
              rtp_sender()->ReSendPacket(second_built_packet->SequenceNumber()));
  
    ASSERT_EQ(3u, transport_.sent_packets_.size());
    const RtpPacketReceived& first_rtx_packet = transport_.sent_packets_[2];
  
    rtp_sender()->OnReceivedAckOnRtxSsrc(first_rtx_packet.SequenceNumber());
  
    // The second and third RTX packets should not include MID nor RRID.
    ASSERT_LT(0,
              rtp_sender()->ReSendPacket(first_built_packet->SequenceNumber()));
    ASSERT_LT(0,
              rtp_sender()->ReSendPacket(second_built_packet->SequenceNumber()));
  
    ASSERT_EQ(5u, transport_.sent_packets_.size());
  
    const RtpPacketReceived& second_rtx_packet = transport_.sent_packets_[3];
    EXPECT_FALSE(second_rtx_packet.HasExtension<RtpMid>());
    EXPECT_FALSE(second_rtx_packet.HasExtension<RepairedRtpStreamId>());
  
    const RtpPacketReceived& third_rtx_packet = transport_.sent_packets_[4];
    EXPECT_FALSE(third_rtx_packet.HasExtension<RtpMid>());
    EXPECT_FALSE(third_rtx_packet.HasExtension<RepairedRtpStreamId>());
  }
  
  TEST_P(RtpSenderTestWithoutPacer,
         MidAndRidAlwaysIncludedOnRtxPacketsWhenConfigured) {
    SetUpRtpSender(false, false, /*always_send_mid_and_rid=*/true);
    const char kMid[] = "mid";
    const char kRid[] = "f";
    EnableRtx();
    EnableMidSending(kMid);
    EnableRidSending(kRid);
  
    // Send two media packets: one before and one after the ack.
    auto media_packet1 = SendGenericPacket();
    rtp_sender()->OnReceivedAckOnSsrc(media_packet1->SequenceNumber());
    auto media_packet2 = SendGenericPacket();
  
    // Send three RTX packets with different combinations of orders w.r.t. the
    // media and RTX acks.
    ASSERT_LT(0, rtp_sender()->ReSendPacket(media_packet2->SequenceNumber()));
    ASSERT_EQ(3u, transport_.sent_packets_.size());
    rtp_sender()->OnReceivedAckOnRtxSsrc(
        transport_.sent_packets_[2].SequenceNumber());
    ASSERT_LT(0, rtp_sender()->ReSendPacket(media_packet1->SequenceNumber()));
    ASSERT_LT(0, rtp_sender()->ReSendPacket(media_packet2->SequenceNumber()));
  
    // Due to the configuration, all sent packets should contain MID
    // and either RID (media) or RRID (RTX).
    ASSERT_EQ(5u, transport_.sent_packets_.size());
    for (const auto& packet : transport_.sent_packets_) {
      EXPECT_EQ(packet.GetExtension<RtpMid>(), kMid);
    }
    for (size_t i = 0; i < 2; ++i) {
      const RtpPacketReceived& packet = transport_.sent_packets_[i];
      EXPECT_EQ(packet.GetExtension<RtpStreamId>(), kRid);
    }
    for (size_t i = 2; i < transport_.sent_packets_.size(); ++i) {
      const RtpPacketReceived& packet = transport_.sent_packets_[i];
      EXPECT_EQ(packet.GetExtension<RepairedRtpStreamId>(), kRid);
    }
  }
  
  // Test that if the RtpState indicates an ACK has been received on that SSRC
  // then neither the MID nor RID header extensions will be sent.
  TEST_P(RtpSenderTestWithoutPacer,
         MidAndRidNotIncludedOnSentPacketsAfterRtpStateRestored) {
    const char kMid[] = "mid";
    const char kRid[] = "f";
  
    EnableMidSending(kMid);
    EnableRidSending(kRid);
  
    RtpState state = rtp_sender()->GetRtpState();
    EXPECT_FALSE(state.ssrc_has_acked);
    state.ssrc_has_acked = true;
    rtp_sender()->SetRtpState(state);
  
    SendGenericPacket();
  
    ASSERT_EQ(1u, transport_.sent_packets_.size());
    const RtpPacketReceived& packet = transport_.sent_packets_[0];
    EXPECT_FALSE(packet.HasExtension<RtpMid>());
    EXPECT_FALSE(packet.HasExtension<RtpStreamId>());
  }
  
  // Test that if the RTX RtpState indicates an ACK has been received on that
  // RTX SSRC then neither the MID nor RRID header extensions will be sent on
  // RTX packets.
  TEST_P(RtpSenderTestWithoutPacer,
         MidAndRridNotIncludedOnRtxPacketsAfterRtpStateRestored) {
    const char kMid[] = "mid";
    const char kRid[] = "f";
  
    EnableRtx();
    EnableMidSending(kMid);
    EnableRidSending(kRid);
  
    RtpState rtx_state = rtp_sender()->GetRtxRtpState();
    EXPECT_FALSE(rtx_state.ssrc_has_acked);
    rtx_state.ssrc_has_acked = true;
    rtp_sender()->SetRtxRtpState(rtx_state);
  
    auto built_packet = SendGenericPacket();
    ASSERT_LT(0, rtp_sender()->ReSendPacket(built_packet->SequenceNumber()));
  
    ASSERT_EQ(2u, transport_.sent_packets_.size());
    const RtpPacketReceived& rtx_packet = transport_.sent_packets_[1];
    EXPECT_FALSE(rtx_packet.HasExtension<RtpMid>());
    EXPECT_FALSE(rtx_packet.HasExtension<RepairedRtpStreamId>());
  }
  
  TEST_P(RtpSenderTest, FecOverheadRate) {
    constexpr uint32_t kTimestamp = 1234;
    constexpr int kMediaPayloadType = 127;
    constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
    constexpr int kFlexfecPayloadType = 118;
    const std::vector<RtpExtension> kNoRtpExtensions;
    const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
    FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid,
                                 kNoRtpExtensions, kNoRtpExtensionSizes,
                                 nullptr /* rtp_state */, &fake_clock_);
  
    // Reset |rtp_sender_| to use FlexFEC.
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.paced_sender = &mock_paced_sender_;
    config.local_media_ssrc = kSsrc;
    config.fec_generator = &flexfec_sender;
    config.event_log = &mock_rtc_event_log_;
    config.send_packet_observer = &send_packet_observer_;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    rtp_sender()->SetSequenceNumber(kSeqNum);
  
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.fec_generator = &flexfec_sender;
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
    // 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;
    rtp_sender_video.SetFecParameters(params, params);
  
    constexpr size_t kNumMediaPackets = 10;
    constexpr size_t kNumFecPackets = kNumMediaPackets;
    constexpr int64_t kTimeBetweenPacketsMs = 10;
    EXPECT_CALL(mock_paced_sender_, EnqueuePackets).Times(kNumMediaPackets);
    for (size_t i = 0; i < kNumMediaPackets; ++i) {
      RTPVideoHeader video_header;
  
      video_header.frame_type = VideoFrameType::kVideoFrameKey;
      EXPECT_TRUE(rtp_sender_video.SendVideo(
          kMediaPayloadType, kCodecType, kTimestamp,
          fake_clock_.TimeInMilliseconds(), kPayloadData, nullptr, video_header,
          kDefaultExpectedRetransmissionTimeMs));
  
      fake_clock_.AdvanceTimeMilliseconds(kTimeBetweenPacketsMs);
    }
    constexpr size_t kRtpHeaderLength = 12;
    constexpr size_t kFlexfecHeaderLength = 20;
    constexpr size_t kGenericCodecHeaderLength = 1;
    constexpr size_t kPayloadLength = sizeof(kPayloadData);
    constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength +
                                     kGenericCodecHeaderLength + kPayloadLength;
    EXPECT_NEAR(kNumFecPackets * kPacketLength * 8 /
                    (kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
                rtp_sender_video.FecOverheadRate(), 500);
  }
  
  TEST_P(RtpSenderTest, BitrateCallbacks) {
    class TestCallback : public BitrateStatisticsObserver {
     public:
      TestCallback()
          : BitrateStatisticsObserver(),
            num_calls_(0),
            ssrc_(0),
            total_bitrate_(0),
            retransmit_bitrate_(0) {}
      ~TestCallback() override = default;
  
      void Notify(uint32_t total_bitrate,
                  uint32_t retransmit_bitrate,
                  uint32_t ssrc) override {
        ++num_calls_;
        ssrc_ = ssrc;
        total_bitrate_ = total_bitrate;
        retransmit_bitrate_ = retransmit_bitrate;
      }
  
      uint32_t num_calls_;
      uint32_t ssrc_;
      uint32_t total_bitrate_;
      uint32_t retransmit_bitrate_;
    } callback;
  
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.send_bitrate_observer = &callback;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
    const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
    const uint8_t kPayloadType = 127;
  
    // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
    // number of packets selected so that we fill (but don't overflow) the one
    // second averaging window.
    const uint32_t kWindowSizeMs = 1000;
    const uint32_t kPacketInterval = 20;
    const uint32_t kNumPackets =
        (kWindowSizeMs - kPacketInterval) / kPacketInterval;
    // Overhead = 12 bytes RTP header + 1 byte generic header.
    const uint32_t kPacketOverhead = 13;
  
    uint8_t payload[] = {47, 11, 32, 93, 89};
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 1);
    uint32_t ssrc = rtp_sender()->SSRC();
  
    // Initial process call so we get a new time window.
    rtp_egress()->ProcessBitrateAndNotifyObservers();
  
    // Send a few frames.
    RTPVideoHeader video_header;
    for (uint32_t i = 0; i < kNumPackets; ++i) {
      video_header.frame_type = VideoFrameType::kVideoFrameKey;
      ASSERT_TRUE(rtp_sender_video.SendVideo(
          kPayloadType, kCodecType, 1234, 4321, payload, nullptr, video_header,
          kDefaultExpectedRetransmissionTimeMs));
      fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
    }
  
    rtp_egress()->ProcessBitrateAndNotifyObservers();
  
    // We get one call for every stats updated, thus two calls since both the
    // stream stats and the retransmit stats are updated once.
    EXPECT_EQ(2u, callback.num_calls_);
    EXPECT_EQ(ssrc, callback.ssrc_);
    const uint32_t kTotalPacketSize = kPacketOverhead + sizeof(payload);
    // Bitrate measured over delta between last and first timestamp, plus one.
    const uint32_t kExpectedWindowMs = kNumPackets * kPacketInterval + 1;
    const uint32_t kExpectedBitsAccumulated = kTotalPacketSize * kNumPackets * 8;
    const uint32_t kExpectedRateBps =
        (kExpectedBitsAccumulated * 1000 + (kExpectedWindowMs / 2)) /
        kExpectedWindowMs;
    EXPECT_EQ(kExpectedRateBps, callback.total_bitrate_);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
    const uint8_t kPayloadType = 127;
    const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
    FieldTrialBasedConfig field_trials;
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.field_trials = &field_trials;
    RTPSenderVideo rtp_sender_video(video_config);
    uint8_t payload[] = {47, 11, 32, 93, 89};
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 1);
    uint32_t ssrc = rtp_sender()->SSRC();
  
    // Send a frame.
    RTPVideoHeader video_header;
    video_header.frame_type = VideoFrameType::kVideoFrameKey;
    ASSERT_TRUE(rtp_sender_video.SendVideo(kPayloadType, kCodecType, 1234, 4321,
                                           payload, nullptr, video_header,
                                           kDefaultExpectedRetransmissionTimeMs));
    StreamDataCounters expected;
    expected.transmitted.payload_bytes = 6;
    expected.transmitted.header_bytes = 12;
    expected.transmitted.padding_bytes = 0;
    expected.transmitted.packets = 1;
    expected.retransmitted.payload_bytes = 0;
    expected.retransmitted.header_bytes = 0;
    expected.retransmitted.padding_bytes = 0;
    expected.retransmitted.packets = 0;
    expected.fec.packets = 0;
    rtp_stats_callback_.Matches(ssrc, expected);
  
    // Retransmit a frame.
    uint16_t seqno = rtp_sender()->SequenceNumber() - 1;
    rtp_sender()->ReSendPacket(seqno);
    expected.transmitted.payload_bytes = 12;
    expected.transmitted.header_bytes = 24;
    expected.transmitted.packets = 2;
    expected.retransmitted.payload_bytes = 6;
    expected.retransmitted.header_bytes = 12;
    expected.retransmitted.padding_bytes = 0;
    expected.retransmitted.packets = 1;
    rtp_stats_callback_.Matches(ssrc, expected);
  
    // Send padding.
    GenerateAndSendPadding(kMaxPaddingSize);
    expected.transmitted.payload_bytes = 12;
    expected.transmitted.header_bytes = 36;
    expected.transmitted.padding_bytes = kMaxPaddingSize;
    expected.transmitted.packets = 3;
    rtp_stats_callback_.Matches(ssrc, expected);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacksUlpfec) {
    const uint8_t kRedPayloadType = 96;
    const uint8_t kUlpfecPayloadType = 97;
    const uint8_t kPayloadType = 127;
    const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
    FieldTrialBasedConfig field_trials;
    UlpfecGenerator ulpfec_generator(kRedPayloadType, kUlpfecPayloadType,
                                     &fake_clock_);
    RTPSenderVideo::Config video_config;
    video_config.clock = &fake_clock_;
    video_config.rtp_sender = rtp_sender();
    video_config.field_trials = &field_trials;
    video_config.red_payload_type = kRedPayloadType;
    video_config.fec_generator = &ulpfec_generator;
    RTPSenderVideo rtp_sender_video(video_config);
    uint8_t payload[] = {47, 11, 32, 93, 89};
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 1);
    uint32_t ssrc = rtp_sender()->SSRC();
  
    RTPVideoHeader video_header;
    StreamDataCounters expected;
  
    // Send ULPFEC.
    FecProtectionParams fec_params;
    fec_params.fec_mask_type = kFecMaskRandom;
    fec_params.fec_rate = 1;
    fec_params.max_fec_frames = 1;
    rtp_sender_video.SetFecParameters(fec_params, fec_params);
    video_header.frame_type = VideoFrameType::kVideoFrameDelta;
    ASSERT_TRUE(rtp_sender_video.SendVideo(kPayloadType, kCodecType, 1234, 4321,
                                           payload, nullptr, video_header,
                                           kDefaultExpectedRetransmissionTimeMs));
    expected.transmitted.payload_bytes = 28;
    expected.transmitted.header_bytes = 24;
    expected.transmitted.packets = 2;
    expected.fec.packets = 1;
    rtp_stats_callback_.Matches(ssrc, expected);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
    // XXX const char* kPayloadName = "GENERIC";
    const uint8_t kPayloadType = 127;
    rtp_sender()->SetRtxPayloadType(kPayloadType - 1, kPayloadType);
    rtp_sender()->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
  
    SendGenericPacket();
    // Will send 2 full-size padding packets.
    GenerateAndSendPadding(1);
    GenerateAndSendPadding(1);
  
    StreamDataCounters rtp_stats;
    StreamDataCounters rtx_stats;
    rtp_egress()->GetDataCounters(&rtp_stats, &rtx_stats);
  
    // Payload
    EXPECT_GT(rtp_stats.first_packet_time_ms, -1);
    EXPECT_EQ(rtp_stats.transmitted.payload_bytes, sizeof(kPayloadData));
    EXPECT_EQ(rtp_stats.transmitted.header_bytes, 12u);
    EXPECT_EQ(rtp_stats.transmitted.padding_bytes, 0u);
    EXPECT_EQ(rtx_stats.transmitted.payload_bytes, 0u);
    EXPECT_EQ(rtx_stats.transmitted.header_bytes, 24u);
    EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
  
    EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
              rtp_stats.transmitted.payload_bytes +
                  rtp_stats.transmitted.header_bytes +
                  rtp_stats.transmitted.padding_bytes);
    EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
              rtx_stats.transmitted.payload_bytes +
                  rtx_stats.transmitted.header_bytes +
                  rtx_stats.transmitted.padding_bytes);
  
    EXPECT_EQ(
        transport_.total_bytes_sent_,
        rtp_stats.transmitted.TotalBytes() + rtx_stats.transmitted.TotalBytes());
  }
  
  TEST_P(RtpSenderTestWithoutPacer, RespectsNackBitrateLimit) {
    const int32_t kPacketSize = 1400;
    const int32_t kNumPackets = 30;
  
    retransmission_rate_limiter_.SetMaxRate(kPacketSize * kNumPackets * 8);
  
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, kNumPackets);
    const uint16_t kStartSequenceNumber = rtp_sender()->SequenceNumber();
    std::vector<uint16_t> sequence_numbers;
    for (int32_t i = 0; i < kNumPackets; ++i) {
      sequence_numbers.push_back(kStartSequenceNumber + i);
      fake_clock_.AdvanceTimeMilliseconds(1);
      SendPacket(fake_clock_.TimeInMilliseconds(), kPacketSize);
    }
    EXPECT_EQ(kNumPackets, transport_.packets_sent());
  
    fake_clock_.AdvanceTimeMilliseconds(1000 - kNumPackets);
  
    // Resending should work - brings the bandwidth up to the limit.
    // NACK bitrate is capped to the same bitrate as the encoder, since the max
    // protection overhead is 50% (see MediaOptimization::SetTargetRates).
    rtp_sender()->OnReceivedNack(sequence_numbers, 0);
    EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
  
    // Must be at least 5ms in between retransmission attempts.
    fake_clock_.AdvanceTimeMilliseconds(5);
  
    // Resending should not work, bandwidth exceeded.
    rtp_sender()->OnReceivedNack(sequence_numbers, 0);
    EXPECT_EQ(kNumPackets * 2, transport_.packets_sent());
  }
  
  TEST_P(RtpSenderTest, OnOverheadChanged) {
    MockOverheadObserver mock_overhead_observer;
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    config.overhead_observer = &mock_overhead_observer;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    // RTP overhead is 12B.
    EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(12)).Times(1);
    SendGenericPacket();
  
    rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
                                             kTransmissionTimeOffsetExtensionId);
  
    // TransmissionTimeOffset extension has a size of 8B.
    // 12B + 8B = 20B
    EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(20)).Times(1);
    SendGenericPacket();
  }
  
  TEST_P(RtpSenderTest, DoesNotUpdateOverheadOnEqualSize) {
    MockOverheadObserver mock_overhead_observer;
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.retransmission_rate_limiter = &retransmission_rate_limiter_;
    config.overhead_observer = &mock_overhead_observer;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
  
    EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
    SendGenericPacket();
    SendGenericPacket();
  }
  
  TEST_P(RtpSenderTest, SendPacketMatchesVideo) {
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_packet_type(RtpPacketMediaType::kVideo);
  
    // Verify sent with correct SSRC.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kSsrc);
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 1);
  }
  
  TEST_P(RtpSenderTest, SendPacketMatchesAudio) {
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_packet_type(RtpPacketMediaType::kAudio);
  
    // Verify sent with correct SSRC.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kSsrc);
    packet->set_packet_type(RtpPacketMediaType::kAudio);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 1);
  }
  
  TEST_P(RtpSenderTest, SendPacketMatchesRetransmissions) {
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
  
    // Verify sent with correct SSRC (non-RTX).
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kSsrc);
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 1);
  
    // RTX retransmission.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kRtxSsrc);
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 2);
  }
  
  TEST_P(RtpSenderTest, SendPacketMatchesPadding) {
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_packet_type(RtpPacketMediaType::kPadding);
  
    // Verify sent with correct SSRC (non-RTX).
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kSsrc);
    packet->set_packet_type(RtpPacketMediaType::kPadding);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 1);
  
    // RTX padding.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kRtxSsrc);
    packet->set_packet_type(RtpPacketMediaType::kPadding);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 2);
  }
  
  TEST_P(RtpSenderTest, SendPacketMatchesFlexfec) {
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
  
    // Verify sent with correct SSRC.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kFlexFecSsrc);
    packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 1);
  }
  
  TEST_P(RtpSenderTest, SendPacketMatchesUlpfec) {
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
  
    // Verify sent with correct SSRC.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetSsrc(kSsrc);
    packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_EQ(transport_.packets_sent(), 1);
  }
  
  TEST_P(RtpSenderTest, SendPacketHandlesRetransmissionHistory) {
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
  
    // Build a media packet and send it.
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    const uint16_t media_sequence_number = packet->SequenceNumber();
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    packet->set_allow_retransmission(true);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    // Simulate retransmission request.
    fake_clock_.AdvanceTimeMilliseconds(30);
    EXPECT_GT(rtp_sender()->ReSendPacket(media_sequence_number), 0);
  
    // Packet already pending, retransmission not allowed.
    fake_clock_.AdvanceTimeMilliseconds(30);
    EXPECT_EQ(rtp_sender()->ReSendPacket(media_sequence_number), 0);
  
    // Packet exiting pacer, mark as not longer pending.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    EXPECT_NE(packet->SequenceNumber(), media_sequence_number);
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    packet->SetSsrc(kRtxSsrc);
    packet->set_retransmitted_sequence_number(media_sequence_number);
    packet->set_allow_retransmission(false);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    // Retransmissions allowed again.
    fake_clock_.AdvanceTimeMilliseconds(30);
    EXPECT_GT(rtp_sender()->ReSendPacket(media_sequence_number), 0);
  
    // Retransmission of RTX packet should not be allowed.
    EXPECT_EQ(rtp_sender()->ReSendPacket(packet->SequenceNumber()), 0);
  }
  
  TEST_P(RtpSenderTest, SendPacketUpdatesExtensions) {
    ASSERT_EQ(rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionTransmissionTimeOffset,
                  kTransmissionTimeOffsetExtensionId),
              0);
    ASSERT_EQ(rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId),
              0);
    ASSERT_EQ(rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionVideoTiming,
                                                       kVideoTimingExtensionId),
              0);
  
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_packetization_finish_time_ms(fake_clock_.TimeInMilliseconds());
  
    const int32_t kDiffMs = 10;
    fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
  
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    const RtpPacketReceived& received_packet = transport_.last_sent_packet();
  
    EXPECT_EQ(received_packet.GetExtension<TransmissionOffset>(), kDiffMs * 90);
  
    EXPECT_EQ(received_packet.GetExtension<AbsoluteSendTime>(),
              AbsoluteSendTime::MsTo24Bits(fake_clock_.TimeInMilliseconds()));
  
    VideoSendTiming timing;
    EXPECT_TRUE(received_packet.GetExtension<VideoTimingExtension>(&timing));
    EXPECT_EQ(timing.pacer_exit_delta_ms, kDiffMs);
  }
  
  TEST_P(RtpSenderTest, SendPacketSetsPacketOptions) {
    const uint16_t kPacketId = 42;
    ASSERT_EQ(rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionTransportSequenceNumber,
                  kTransportSequenceNumberExtensionId),
              0);
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetExtension<TransportSequenceNumber>(kPacketId);
  
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    EXPECT_CALL(send_packet_observer_, OnSendPacket);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    EXPECT_EQ(transport_.last_options_.packet_id, kPacketId);
    EXPECT_TRUE(transport_.last_options_.included_in_allocation);
    EXPECT_TRUE(transport_.last_options_.included_in_feedback);
    EXPECT_FALSE(transport_.last_options_.is_retransmit);
  
    // Send another packet as retransmission, verify options are populated.
    packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->SetExtension<TransportSequenceNumber>(kPacketId + 1);
    packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
    EXPECT_TRUE(transport_.last_options_.is_retransmit);
  }
  
  TEST_P(RtpSenderTest, SendPacketUpdatesStats) {
    const size_t kPayloadSize = 1000;
  
    StrictMock<MockSendSideDelayObserver> send_side_delay_observer;
  
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.local_media_ssrc = kSsrc;
    config.rtx_send_ssrc = kRtxSsrc;
    config.fec_generator = &flexfec_sender_;
    config.send_side_delay_observer = &send_side_delay_observer;
    config.event_log = &mock_rtc_event_log_;
    config.send_packet_observer = &send_packet_observer_;
    rtp_sender_context_ = std::make_unique<RtpSenderContext>(config);
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
  
    const int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
  
    std::unique_ptr<RtpPacketToSend> video_packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    video_packet->set_packet_type(RtpPacketMediaType::kVideo);
    video_packet->SetPayloadSize(kPayloadSize);
    video_packet->SetExtension<TransportSequenceNumber>(1);
  
    std::unique_ptr<RtpPacketToSend> rtx_packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    rtx_packet->SetSsrc(kRtxSsrc);
    rtx_packet->set_packet_type(RtpPacketMediaType::kRetransmission);
    rtx_packet->SetPayloadSize(kPayloadSize);
    rtx_packet->SetExtension<TransportSequenceNumber>(2);
  
    std::unique_ptr<RtpPacketToSend> fec_packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    fec_packet->SetSsrc(kFlexFecSsrc);
    fec_packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
    fec_packet->SetPayloadSize(kPayloadSize);
    fec_packet->SetExtension<TransportSequenceNumber>(3);
  
    const int64_t kDiffMs = 25;
    fake_clock_.AdvanceTimeMilliseconds(kDiffMs);
  
    EXPECT_CALL(send_side_delay_observer,
                SendSideDelayUpdated(kDiffMs, kDiffMs, kDiffMs, kSsrc));
    EXPECT_CALL(
        send_side_delay_observer,
        SendSideDelayUpdated(kDiffMs, kDiffMs, 2 * kDiffMs, kFlexFecSsrc));
  
    EXPECT_CALL(send_packet_observer_, OnSendPacket(1, capture_time_ms, kSsrc));
  
    rtp_egress()->SendPacket(video_packet.get(), PacedPacketInfo());
  
    // Send packet observer not called for padding/retransmissions.
    EXPECT_CALL(send_packet_observer_, OnSendPacket(2, _, _)).Times(0);
    rtp_egress()->SendPacket(rtx_packet.get(), PacedPacketInfo());
  
    EXPECT_CALL(send_packet_observer_,
                OnSendPacket(3, capture_time_ms, kFlexFecSsrc));
    rtp_egress()->SendPacket(fec_packet.get(), PacedPacketInfo());
  
    StreamDataCounters rtp_stats;
    StreamDataCounters rtx_stats;
    rtp_egress()->GetDataCounters(&rtp_stats, &rtx_stats);
    EXPECT_EQ(rtp_stats.transmitted.packets, 2u);
    EXPECT_EQ(rtp_stats.fec.packets, 1u);
    EXPECT_EQ(rtx_stats.retransmitted.packets, 1u);
  }
  
  TEST_P(RtpSenderTest, GeneratePaddingResendsOldPacketsWithRtx) {
    // Min requested size in order to use RTX payload.
    const size_t kMinPaddingSize = 50;
  
    rtp_sender()->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
    rtp_sender()->SetRtxPayloadType(kRtxPayload, kPayload);
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 1);
  
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransmissionTimeOffset,
                     kTransmissionTimeOffsetExtensionId));
    ASSERT_EQ(0,
              rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
  
    const size_t kPayloadPacketSize = 1234;
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_allow_retransmission(true);
    packet->SetPayloadSize(kPayloadPacketSize);
    packet->set_packet_type(RtpPacketMediaType::kVideo);
  
    // Send a dummy video packet so it ends up in the packet history.
    EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    // Generated padding has large enough budget that the video packet should be
    // retransmitted as padding.
    std::vector<std::unique_ptr<RtpPacketToSend>> generated_packets =
        rtp_sender()->GeneratePadding(kMinPaddingSize, true);
    ASSERT_EQ(generated_packets.size(), 1u);
    auto& padding_packet = generated_packets.front();
    EXPECT_EQ(padding_packet->packet_type(), RtpPacketMediaType::kPadding);
    EXPECT_EQ(padding_packet->Ssrc(), kRtxSsrc);
    EXPECT_EQ(padding_packet->payload_size(),
              kPayloadPacketSize + kRtxHeaderSize);
    EXPECT_TRUE(padding_packet->HasExtension<TransportSequenceNumber>());
    EXPECT_TRUE(padding_packet->HasExtension<AbsoluteSendTime>());
    EXPECT_TRUE(padding_packet->HasExtension<TransmissionOffset>());
  
    // Verify all header extensions are received.
    rtp_egress()->SendPacket(padding_packet.get(), PacedPacketInfo());
    webrtc::RTPHeader rtp_header;
    transport_.last_sent_packet().GetHeader(&rtp_header);
    EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
    EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
    EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
  
    // Not enough budged for payload padding, use plain padding instead.
    const size_t kPaddingBytesRequested = kMinPaddingSize - 1;
  
    size_t padding_bytes_generated = 0;
    generated_packets =
        rtp_sender()->GeneratePadding(kPaddingBytesRequested, true);
    EXPECT_EQ(generated_packets.size(), 1u);
    for (auto& packet : generated_packets) {
      EXPECT_EQ(packet->packet_type(), RtpPacketMediaType::kPadding);
      EXPECT_EQ(packet->Ssrc(), kRtxSsrc);
      EXPECT_EQ(packet->payload_size(), 0u);
      EXPECT_GT(packet->padding_size(), 0u);
      padding_bytes_generated += packet->padding_size();
  
      EXPECT_TRUE(packet->HasExtension<TransportSequenceNumber>());
      EXPECT_TRUE(packet->HasExtension<AbsoluteSendTime>());
      EXPECT_TRUE(packet->HasExtension<TransmissionOffset>());
  
      // Verify all header extensions are received.
      rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
      webrtc::RTPHeader rtp_header;
      transport_.last_sent_packet().GetHeader(&rtp_header);
      EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
      EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
      EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
    }
  
    EXPECT_EQ(padding_bytes_generated, kMaxPaddingSize);
  }
  
  TEST_P(RtpSenderTest, GeneratePaddingCreatesPurePaddingWithoutRtx) {
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 1);
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransmissionTimeOffset,
                     kTransmissionTimeOffsetExtensionId));
    ASSERT_EQ(0,
              rtp_sender()->RegisterRtpHeaderExtension(
                  kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
    ASSERT_EQ(0, rtp_sender()->RegisterRtpHeaderExtension(
                     kRtpExtensionTransportSequenceNumber,
                     kTransportSequenceNumberExtensionId));
  
    const size_t kPayloadPacketSize = 1234;
    // Send a dummy video packet so it ends up in the packet history. Since we
    // are not using RTX, it should never be used as padding.
    std::unique_ptr<RtpPacketToSend> packet =
        BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
    packet->set_allow_retransmission(true);
    packet->SetPayloadSize(kPayloadPacketSize);
    packet->set_packet_type(RtpPacketMediaType::kVideo);
    EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
    rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
  
    // Payload padding not available without RTX, only generate plain padding on
    // the media SSRC.
    // Number of padding packets is the requested padding size divided by max
    // padding packet size, rounded up. Pure padding packets are always of the
    // maximum size.
    const size_t kPaddingBytesRequested = kPayloadPacketSize + kRtxHeaderSize;
    const size_t kExpectedNumPaddingPackets =
        (kPaddingBytesRequested + kMaxPaddingSize - 1) / kMaxPaddingSize;
    size_t padding_bytes_generated = 0;
    std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
        rtp_sender()->GeneratePadding(kPaddingBytesRequested, true);
    EXPECT_EQ(padding_packets.size(), kExpectedNumPaddingPackets);
    for (auto& packet : padding_packets) {
      EXPECT_EQ(packet->packet_type(), RtpPacketMediaType::kPadding);
      EXPECT_EQ(packet->Ssrc(), kSsrc);
      EXPECT_EQ(packet->payload_size(), 0u);
      EXPECT_GT(packet->padding_size(), 0u);
      padding_bytes_generated += packet->padding_size();
      EXPECT_TRUE(packet->HasExtension<TransportSequenceNumber>());
      EXPECT_TRUE(packet->HasExtension<AbsoluteSendTime>());
      EXPECT_TRUE(packet->HasExtension<TransmissionOffset>());
  
      // Verify all header extensions are received.
      rtp_egress()->SendPacket(packet.get(), PacedPacketInfo());
      webrtc::RTPHeader rtp_header;
      transport_.last_sent_packet().GetHeader(&rtp_header);
      EXPECT_TRUE(rtp_header.extension.hasAbsoluteSendTime);
      EXPECT_TRUE(rtp_header.extension.hasTransmissionTimeOffset);
      EXPECT_TRUE(rtp_header.extension.hasTransportSequenceNumber);
    }
  
    EXPECT_EQ(padding_bytes_generated,
              kExpectedNumPaddingPackets * kMaxPaddingSize);
  }
  
  TEST_P(RtpSenderTest, SupportsPadding) {
    bool kSendingMediaStats[] = {true, false};
    bool kEnableRedundantPayloads[] = {true, false};
    RTPExtensionType kBweExtensionTypes[] = {
        kRtpExtensionTransportSequenceNumber,
        kRtpExtensionTransportSequenceNumber02, kRtpExtensionAbsoluteSendTime,
        kRtpExtensionTransmissionTimeOffset};
    const int kExtensionsId = 7;
  
    for (bool sending_media : kSendingMediaStats) {
      rtp_sender()->SetSendingMediaStatus(sending_media);
      for (bool redundant_payloads : kEnableRedundantPayloads) {
        int rtx_mode = kRtxRetransmitted;
        if (redundant_payloads) {
          rtx_mode |= kRtxRedundantPayloads;
        }
        rtp_sender()->SetRtxStatus(rtx_mode);
  
        for (auto extension_type : kBweExtensionTypes) {
          EXPECT_FALSE(rtp_sender()->SupportsPadding());
          rtp_sender()->RegisterRtpHeaderExtension(extension_type, kExtensionsId);
          if (!sending_media) {
            EXPECT_FALSE(rtp_sender()->SupportsPadding());
          } else {
            EXPECT_TRUE(rtp_sender()->SupportsPadding());
            if (redundant_payloads) {
              EXPECT_TRUE(rtp_sender()->SupportsRtxPayloadPadding());
            } else {
              EXPECT_FALSE(rtp_sender()->SupportsRtxPayloadPadding());
            }
          }
          rtp_sender()->DeregisterRtpHeaderExtension(extension_type);
          EXPECT_FALSE(rtp_sender()->SupportsPadding());
        }
      }
    }
  }
  
  TEST_P(RtpSenderTest, SetsCaptureTimeAndPopulatesTransmissionOffset) {
    rtp_sender()->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
                                             kTransmissionTimeOffsetExtensionId);
  
    rtp_sender()->SetSendingMediaStatus(true);
    rtp_sender()->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
    rtp_sender()->SetRtxPayloadType(kRtxPayload, kPayload);
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
  
    const int64_t kMissingCaptureTimeMs = 0;
    const uint32_t kTimestampTicksPerMs = 90;
    const int64_t kOffsetMs = 10;
  
      auto packet =
          BuildRtpPacket(kPayload, kMarkerBit, fake_clock_.TimeInMilliseconds(),
                         kMissingCaptureTimeMs);
      packet->set_packet_type(RtpPacketMediaType::kVideo);
      packet->ReserveExtension<TransmissionOffset>();
      packet->AllocatePayload(sizeof(kPayloadData));
  
      std::unique_ptr<RtpPacketToSend> packet_to_pace;
      EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
          .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
            EXPECT_EQ(packets.size(), 1u);
            EXPECT_GT(packets[0]->capture_time_ms(), 0);
            packet_to_pace = std::move(packets[0]);
          });
  
      packet->set_allow_retransmission(true);
      EXPECT_TRUE(rtp_sender()->SendToNetwork(std::move(packet)));
  
      fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
  
      rtp_egress()->SendPacket(packet_to_pace.get(), PacedPacketInfo());
  
      EXPECT_EQ(1, transport_.packets_sent());
      absl::optional<int32_t> transmission_time_extension =
          transport_.sent_packets_.back().GetExtension<TransmissionOffset>();
      ASSERT_TRUE(transmission_time_extension.has_value());
      EXPECT_EQ(*transmission_time_extension, kOffsetMs * kTimestampTicksPerMs);
  
      // Retransmit packet. The RTX packet should get the same capture time as the
      // original packet, so offset is delta from original packet to now.
      fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
  
      std::unique_ptr<RtpPacketToSend> rtx_packet_to_pace;
      EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
          .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
            EXPECT_GT(packets[0]->capture_time_ms(), 0);
            rtx_packet_to_pace = std::move(packets[0]);
          });
  
      EXPECT_GT(rtp_sender()->ReSendPacket(kSeqNum), 0);
      rtp_egress()->SendPacket(rtx_packet_to_pace.get(), PacedPacketInfo());
  
      EXPECT_EQ(2, transport_.packets_sent());
      transmission_time_extension =
          transport_.sent_packets_.back().GetExtension<TransmissionOffset>();
      ASSERT_TRUE(transmission_time_extension.has_value());
      EXPECT_EQ(*transmission_time_extension,
                2 * kOffsetMs * kTimestampTicksPerMs);
  }
  
  TEST_P(RtpSenderTestWithoutPacer, ClearHistoryOnSequenceNumberCange) {
    const int64_t kRtt = 10;
  
    rtp_sender()->SetSendingMediaStatus(true);
    rtp_sender()->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
    rtp_sender()->SetRtxPayloadType(kRtxPayload, kPayload);
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    rtp_sender_context_->packet_history_.SetRtt(kRtt);
  
    // Send a packet and record its sequence numbers.
    SendGenericPacket();
    ASSERT_EQ(1u, transport_.sent_packets_.size());
    const uint16_t packet_seqence_number =
        transport_.sent_packets_.back().SequenceNumber();
  
    // Advance time and make sure it can be retransmitted, even if we try to set
    // the ssrc the what it already is.
    rtp_sender()->SetSequenceNumber(rtp_sender()->SequenceNumber());
    fake_clock_.AdvanceTimeMilliseconds(kRtt);
    EXPECT_GT(rtp_sender()->ReSendPacket(packet_seqence_number), 0);
  
    // Change the sequence number, then move the time and try to retransmit again.
    // The old packet should now be gone.
    rtp_sender()->SetSequenceNumber(rtp_sender()->SequenceNumber() - 1);
    fake_clock_.AdvanceTimeMilliseconds(kRtt);
    EXPECT_EQ(rtp_sender()->ReSendPacket(packet_seqence_number), 0);
  }
  
  TEST_P(RtpSenderTest, IgnoresNackAfterDisablingMedia) {
    const int64_t kRtt = 10;
  
    rtp_sender()->SetSendingMediaStatus(true);
    rtp_sender()->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
    rtp_sender()->SetRtxPayloadType(kRtxPayload, kPayload);
    rtp_sender_context_->packet_history_.SetStorePacketsStatus(
        RtpPacketHistory::StorageMode::kStoreAndCull, 10);
    rtp_sender_context_->packet_history_.SetRtt(kRtt);
  
    // Send a packet so it is in the packet history.
      std::unique_ptr<RtpPacketToSend> packet_to_pace;
      EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
          .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
            packet_to_pace = std::move(packets[0]);
          });
  
      SendGenericPacket();
      rtp_egress()->SendPacket(packet_to_pace.get(), PacedPacketInfo());
  
      ASSERT_EQ(1u, transport_.sent_packets_.size());
  
      // Disable media sending and try to retransmit the packet, it should fail.
      rtp_sender()->SetSendingMediaStatus(false);
      fake_clock_.AdvanceTimeMilliseconds(kRtt);
      EXPECT_LT(rtp_sender()->ReSendPacket(kSeqNum), 0);
  }
  
  INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
                           RtpSenderTest,
                           ::testing::Values(TestConfig{false},
                                             TestConfig{true}));
  
  INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
                           RtpSenderTestWithoutPacer,
                           ::testing::Values(TestConfig{false},
                                             TestConfig{true}));
  
  }  // namespace webrtc
  