/*
 *  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 "absl/memory/memory.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/events/rtc_event.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_header_parser.h"
#include "modules/rtp_rtcp/include/rtp_packet_pacer.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_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"

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 = 0xaabbu;
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::AtLeast;
using ::testing::DoAll;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Field;
using ::testing::Gt;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Pointee;
using ::testing::Property;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SizeIs;
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(kRtpExtensionTransmissionTimeOffset,
                                   kTransmissionTimeOffsetExtensionId);
    receivers_extensions_.Register(kRtpExtensionAbsoluteSendTime,
                                   kAbsoluteSendTimeExtensionId);
    receivers_extensions_.Register(kRtpExtensionTransportSequenceNumber,
                                   kTransportSequenceNumberExtensionId);
    receivers_extensions_.Register(kRtpExtensionVideoRotation,
                                   kVideoRotationExtensionId);
    receivers_extensions_.Register(kRtpExtensionAudioLevel,
                                   kAudioLevelExtensionId);
    receivers_extensions_.Register(kRtpExtensionVideoTiming,
                                   kVideoTimingExtensionId);
    receivers_extensions_.Register(kRtpExtensionMid, kMidExtensionId);
    receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor00,
                                   kGenericDescriptorId00);
    receivers_extensions_.Register(kRtpExtensionGenericFrameDescriptor01,
                                   kGenericDescriptorId01);
    receivers_extensions_.Register(kRtpExtensionRtpStreamId, kRidExtensionId);
    receivers_extensions_.Register(kRtpExtensionRepairedRtpStreamId,
                                   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 {
  TestConfig(bool with_overhead, bool pacer_references_packets)
      : with_overhead(with_overhead),
        pacer_references_packets(pacer_references_packets) {}
  bool with_overhead = false;
  bool pacer_references_packets = false;
};

std::string ToFieldTrialString(TestConfig config) {
  std::string field_trials;
  if (config.with_overhead) {
    field_trials += "WebRTC-SendSideBwe-WithOverhead/Enabled/";
  }
  if (config.pacer_references_packets) {
    field_trials += "WebRTC-Pacer-LegacyPacketReferencing/Enabled/";
  } else {
    field_trials += "WebRTC-Pacer-LegacyPacketReferencing/Disabled/";
  }
  return field_trials;
}

}  // namespace

class MockRtpPacketPacer : public RtpPacketPacer {
 public:
  MockRtpPacketPacer() {}
  virtual ~MockRtpPacketPacer() {}

  MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend>));

  MOCK_METHOD6(InsertPacket,
               void(Priority priority,
                    uint32_t ssrc,
                    uint16_t sequence_number,
                    int64_t capture_time_ms,
                    size_t bytes,
                    bool retransmission));
};

class MockTransportSequenceNumberAllocator
    : public TransportSequenceNumberAllocator {
 public:
  MOCK_METHOD0(AllocateSequenceNumber, uint16_t());
};

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&));
  MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
};

class MockOverheadObserver : public OverheadObserver {
 public:
  MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet));
};

class RtpSenderTest : public ::testing::TestWithParam<TestConfig> {
 protected:
  RtpSenderTest()
      : fake_clock_(kStartTime),
        mock_rtc_event_log_(),
        mock_paced_sender_(),
        retransmission_rate_limiter_(&fake_clock_, 1000),
        flexfec_sender_(0,
                        kFlexFecSsrc,
                        kSsrc,
                        "",
                        std::vector<RtpExtension>(),
                        std::vector<RtpExtensionSize>(),
                        nullptr,
                        &fake_clock_),
        rtp_sender_(),
        transport_(),
        kMarkerBit(true),
        field_trials_(ToFieldTrialString(GetParam())) {}

  void SetUp() override { SetUpRtpSender(true, false); }

  void SetUpRtpSender(bool pacer, bool populate_network2) {
    RtpRtcp::Configuration config;
    config.clock = &fake_clock_;
    config.outgoing_transport = &transport_;
    config.media_send_ssrc = kSsrc;
    config.rtx_send_ssrc = kRtxSsrc;
    config.flexfec_sender = &flexfec_sender_;
    config.transport_sequence_number_allocator = &seq_num_allocator_;
    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;
    rtp_sender_.reset(new RTPSender(config));
    rtp_sender_->SetSequenceNumber(kSeqNum);
    rtp_sender_->SetTimestampOffset(0);
  }

  SimulatedClock fake_clock_;
  NiceMock<MockRtcEventLog> mock_rtc_event_log_;
  MockRtpPacketPacer mock_paced_sender_;
  StrictMock<MockTransportSequenceNumberAllocator> seq_num_allocator_;
  StrictMock<MockSendPacketObserver> send_packet_observer_;
  StrictMock<MockTransportFeedbackObserver> feedback_observer_;
  RateLimiter retransmission_rate_limiter_;
  FlexfecSender flexfec_sender_;
  std::unique_ptr<RTPSender> rtp_sender_;
  LoopbackTransportTest transport_;
  const bool kMarkerBit;
  test::ScopedFieldTrials field_trials_;

  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->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 should be stored in a send bucket.
    EXPECT_TRUE(rtp_sender_->SendToNetwork(
        absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission,
        RtpPacketSender::kNormalPriority));
    return packet;
  }

  std::unique_ptr<RtpPacketToSend> SendGenericPacket() {
    const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
    return SendPacket(kCaptureTimeMs, sizeof(kPayloadData));
  }
};

// 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); }
};

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_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
  packet->SetMarker(false);
  ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
  // Packet without marker bit doesn't allow padding on video stream.
  EXPECT_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));

  packet->SetMarker(true);
  ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
  // Packet with marker bit allows send padding.
  EXPECT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
}

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.media_send_ssrc = kSsrc;
  config.event_log = &mock_rtc_event_log_;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(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,
            rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));

  // 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, rtp_sender_->TimeToSendPadding(kMinPaddingSize - 5,
                                                            PacedPacketInfo()));
}

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()));
  ASSERT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));

  ASSERT_EQ(1u, transport_.sent_packets_.size());
  // Verify padding packet timestamp.
  EXPECT_EQ(kTimestamp, transport_.last_sent_packet().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.media_send_ssrc = kSsrc;
  config.transport_sequence_number_allocator = &seq_num_allocator_;
  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_ = absl::make_unique<RTPSender>(config);

  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                   kRtpExtensionTransportSequenceNumber,
                   kTransportSequenceNumberExtensionId));
  EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
      .WillOnce(Return(kTransportSequenceNumber));

  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.media_send_ssrc = kSsrc;
  config.transport_sequence_number_allocator = &seq_num_allocator_;
  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_ = absl::make_unique<RTPSender>(config);

  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                   kRtpExtensionTransportSequenceNumber,
                   kTransportSequenceNumberExtensionId));

  EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
      .WillOnce(Return(kTransportSequenceNumber));
  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.media_send_ssrc = kSsrc;
  config.transport_sequence_number_allocator = &seq_num_allocator_;
  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_ = absl::make_unique<RTPSender>(config);

  SendGenericPacket();

  EXPECT_FALSE(transport_.last_options_.is_retransmit);
}

TEST_P(RtpSenderTestWithoutPacer,
       SetsIncludedInFeedbackWhenTransportSequenceNumberExtensionIsRegistered) {
  SetUpRtpSender(false, false);
  rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
                                          kTransportSequenceNumberExtensionId);
  EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
      .WillOnce(Return(kTransportSequenceNumber));
  EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
  SendGenericPacket();
  EXPECT_TRUE(transport_.last_options_.included_in_feedback);
}

TEST_P(
    RtpSenderTestWithoutPacer,
    SetsIncludedInAllocationWhenTransportSequenceNumberExtensionIsRegistered) {
  SetUpRtpSender(false, false);
  rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
                                          kTransportSequenceNumberExtensionId);
  EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
      .WillOnce(Return(kTransportSequenceNumber));
  EXPECT_CALL(send_packet_observer_, OnSendPacket).Times(1);
  SendGenericPacket();
  EXPECT_TRUE(transport_.last_options_.included_in_allocation);
}

TEST_P(RtpSenderTestWithoutPacer,
       SetsIncludedInAllocationWhenForcedAsPartOfAllocation) {
  SetUpRtpSender(false, false);
  rtp_sender_->SetAsPartOfAllocation(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);
  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.media_send_ssrc = kSsrc;
  config.send_side_delay_observer = &send_side_delay_observer_;
  config.event_log = &mock_rtc_event_log_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
                                  &playout_delay_oracle, nullptr, false, false,
                                  FieldTrialBasedConfig());

  const uint8_t kPayloadType = 127;
  const char payload_name[] = "GENERIC";

  rtp_sender_video.RegisterPayloadType(kPayloadType, payload_name,
                                       /*raw_payload=*/false);

  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);
  EXPECT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, kPayloadType,
      capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
      kPayloadData, sizeof(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);
  EXPECT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, kPayloadType,
      capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
      kPayloadData, sizeof(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();
  EXPECT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, kPayloadType,
      capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
      kPayloadData, sizeof(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);
  EXPECT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, kPayloadType,
      capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
      kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
      kDefaultExpectedRetransmissionTimeMs));
}

TEST_P(RtpSenderTestWithoutPacer, OnSendPacketUpdated) {
  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                   kRtpExtensionTransportSequenceNumber,
                   kTransportSequenceNumberExtensionId));
  EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
      .WillOnce(Return(kTransportSequenceNumber));
  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.media_send_ssrc = kSsrc;
  config.transport_sequence_number_allocator = &seq_num_allocator_;
  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_ = absl::make_unique<RTPSender>(config);

  rtp_sender_->SetSequenceNumber(kSeqNum);
  rtp_sender_->SetStorePacketsStatus(true, 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);

  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
    SendGenericPacket();
    EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
        .WillOnce(Return(kTransportSequenceNumber));
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
                                  fake_clock_.TimeInMilliseconds(), false,
                                  PacedPacketInfo());
  } else {
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
    auto packet = SendGenericPacket();
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    // Transport sequence number is set by PacketRouter, before TrySendPacket().
    packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
    rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
  }

  const auto& packet = transport_.last_sent_packet();
  uint16_t transport_seq_no;
  EXPECT_TRUE(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_->SetStorePacketsStatus(true, 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;
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(
        mock_paced_sender_,
        InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _));
    EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
                                           kAllowRetransmission,
                                           RtpPacketSender::kNormalPriority));
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
                                  PacedPacketInfo());
  } else {
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
    EXPECT_TRUE(rtp_sender_->SendToNetwork(
        absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TrySendPacket(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);
  rtp_sender_->SetStorePacketsStatus(true, 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;

  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(
        mock_paced_sender_,
        InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _));
    EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
                                           kAllowRetransmission,
                                           RtpPacketSender::kNormalPriority));
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
                                  PacedPacketInfo());
  } else {
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
    EXPECT_TRUE(rtp_sender_->SendToNetwork(
        absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission,
        RtpPacketSender::kNormalPriority));
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TrySendPacket(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);
  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);
  EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));

  const int kPropagateTimeMs = 10;
  fake_clock_.AdvanceTimeMilliseconds(kPropagateTimeMs);

  EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
                                         kAllowRetransmission,
                                         RtpPacketSender::kNormalPriority));

  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_->SetStorePacketsStatus(true, 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;
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_,
                InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
                             _, _, _));
    // Packet should be stored in a send bucket.
    EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
                                           kAllowRetransmission,
                                           RtpPacketSender::kNormalPriority));
    EXPECT_EQ(0, transport_.packets_sent());
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
                                  PacedPacketInfo());
  } else {
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    EXPECT_TRUE(rtp_sender_->SendToNetwork(
        absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
    EXPECT_EQ(0, transport_.packets_sent());
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TrySendPacket(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_->SetStorePacketsStatus(true, 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.
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_,
                InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
                             _, _, _));
    EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
                                           kAllowRetransmission,
                                           RtpPacketSender::kNormalPriority));
    // Immediately process send bucket and send packet.
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, false,
                                  PacedPacketInfo());
  } else {
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_TRUE(rtp_sender_->SendToNetwork(
        absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
    // Immediately process send bucket and send packet.
    rtp_sender_->TrySendPacket(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)));
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_,
                InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
                             _, _, _));
    EXPECT_EQ(static_cast<int>(packet_size),
              rtp_sender_->ReSendPacket(kSeqNum));
    EXPECT_EQ(1, transport_.packets_sent());
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum, capture_time_ms, true,
                                  PacedPacketInfo());
  } else {
    packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
    packet->set_retransmitted_sequence_number(kSeqNum);
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(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_sender_->TrySendPacket(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_->SetStorePacketsStatus(true, 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.
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_,
                InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum,
                             _, _, _));
    EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
                                           kAllowRetransmission,
                                           RtpPacketSender::kNormalPriority));
    EXPECT_EQ(total_packets_sent, transport_.packets_sent());
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TimeToSendPacket(kSsrc, seq_num++, capture_time_ms, false,
                                  PacedPacketInfo());
  } else {
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    packet->set_allow_retransmission(true);
    EXPECT_TRUE(rtp_sender_->SendToNetwork(
        absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
    EXPECT_EQ(total_packets_sent, transport_.packets_sent());
    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
    rtp_sender_->TrySendPacket(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,
              rtp_sender_->TimeToSendPadding(kPaddingBytes, PacedPacketInfo()));

    // 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();

  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_,
                InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, seq_num,
                             _, _, _));
    // Packet should be stored in a send bucket.
    EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet),
                                           kAllowRetransmission,
                                           RtpPacketSender::kNormalPriority));
    rtp_sender_->TimeToSendPacket(kSsrc, seq_num, capture_time_ms, false,
                                  PacedPacketInfo());
  } else {
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
    EXPECT_TRUE(rtp_sender_->SendToNetwork(
        absl::make_unique<RtpPacketToSend>(*packet), kAllowRetransmission));
    rtp_sender_->TrySendPacket(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_->SetStorePacketsStatus(true, 10);

  EXPECT_CALL(send_packet_observer_,
              OnSendPacket(kTransportSequenceNumber, _, _))
      .Times(1);

  if (GetParam().pacer_references_packets) {
    const bool kIsRetransmit = false;
    EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
    SendGenericPacket();  // Packet passed to pacer.
    EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
        .WillOnce(::testing::Return(kTransportSequenceNumber));
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
                                  fake_clock_.TimeInMilliseconds(),
                                  kIsRetransmit, PacedPacketInfo());
  } else {
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
    auto packet = SendGenericPacket();
    packet->set_packet_type(RtpPacketToSend::Type::kVideo);
    packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
    rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
  }

  EXPECT_EQ(1, transport_.packets_sent());
}

TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                   kRtpExtensionTransportSequenceNumber,
                   kTransportSequenceNumberExtensionId));
  rtp_sender_->SetStorePacketsStatus(true, 10);

  EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);

  if (GetParam().pacer_references_packets) {
    const bool kIsRetransmit = true;
    EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
    SendGenericPacket();  // Packet passed to pacer.
    EXPECT_CALL(seq_num_allocator_, AllocateSequenceNumber())
        .WillOnce(Return(kTransportSequenceNumber));
    rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
                                  fake_clock_.TimeInMilliseconds(),
                                  kIsRetransmit, PacedPacketInfo());
  } else {
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
    auto packet = SendGenericPacket();
    packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
    packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
    rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
  }

  EXPECT_EQ(1, transport_.packets_sent());
  EXPECT_TRUE(transport_.last_options_.is_retransmit);
}

TEST_P(RtpSenderTest, OnSendPacketNotUpdatedWithoutSeqNumAllocator) {
  if (!GetParam().pacer_references_packets) {
    // When PacedSender owns packets, there is no
    // TransportSequenceNumberAllocator callback, so this test does not make any
    // sense.
    // TODO(bugs.webrtc.org/10633): Remove this test once old code is gone.
    return;
  }

  RtpRtcp::Configuration config;
  config.clock = &fake_clock_;
  config.outgoing_transport = &transport_;
  config.paced_sender = &mock_paced_sender_;
  config.media_send_ssrc = kSsrc;
  config.send_packet_observer = &send_packet_observer_;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  rtp_sender_->SetSequenceNumber(kSeqNum);
  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                   kRtpExtensionTransportSequenceNumber,
                   kTransportSequenceNumberExtensionId));
  rtp_sender_->SetSequenceNumber(kSeqNum);
  rtp_sender_->SetStorePacketsStatus(true, 10);

  EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);

  const bool kIsRetransmit = false;
  EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, kSeqNum, _, _, _));
  SendGenericPacket();  // Packet passed to pacer.
  rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
                                fake_clock_.TimeInMilliseconds(), kIsRetransmit,
                                PacedPacketInfo());

  EXPECT_EQ(1, transport_.packets_sent());
}

// TODO(bugs.webrtc.org/8975): Remove this test when non-useful padding is
// removed.
TEST_P(RtpSenderTest, SendRedundantPayloads) {
  if (!GetParam().pacer_references_packets) {
    // If PacedSender owns the RTP packets, GeneratePadding() family of methods
    // will be called instead and this test makes no sense.
    return;
  }

  test::ScopedFieldTrials field_trials(
      "WebRTC-PayloadPadding-UseMostUsefulPacket/Disabled/");
  MockTransport transport;
  RtpRtcp::Configuration config;
  config.clock = &fake_clock_;
  config.outgoing_transport = &transport;
  config.paced_sender = &mock_paced_sender_;
  config.media_send_ssrc = kSsrc;
  config.rtx_send_ssrc = kRtxSsrc;
  config.event_log = &mock_rtc_event_log_;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  rtp_sender_->SetSequenceNumber(kSeqNum);
  rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);

  uint16_t seq_num = kSeqNum;
  rtp_sender_->SetStorePacketsStatus(true, 10);
  int32_t rtp_header_len = kRtpHeaderSize;
  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.

  rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);

  const size_t kNumPayloadSizes = 10;
  const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700,
                                                  750, 800, 850, 900, 950};
  // Expect all packets go through the pacer.
  EXPECT_CALL(mock_rtc_event_log_,
              LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
      .Times(kNumPayloadSizes);

  // Send 10 packets of increasing size.
  for (size_t i = 0; i < kNumPayloadSizes; ++i) {
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();

    EXPECT_CALL(transport, SendRtp(_, _, _)).WillOnce(::testing::Return(true));

    if (GetParam().pacer_references_packets) {
      EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, seq_num, _, _, _));
      SendPacket(capture_time_ms, kPayloadSizes[i]);
      rtp_sender_->TimeToSendPacket(kSsrc, seq_num,
                                    fake_clock_.TimeInMilliseconds(), false,
                                    PacedPacketInfo());
    } else {
      EXPECT_CALL(
          mock_paced_sender_,
          EnqueuePacket(AllOf(
              Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
              Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
      auto packet = SendPacket(capture_time_ms, kPayloadSizes[i]);
      packet->set_packet_type(RtpPacketToSend::Type::kVideo);
      rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
    }

    ++seq_num;
    fake_clock_.AdvanceTimeMilliseconds(33);
  }

  EXPECT_CALL(mock_rtc_event_log_,
              LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
      .Times(AtLeast(4));

  // The amount of padding to send it too small to send a payload packet.
  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
      .WillOnce(Return(true));
  EXPECT_EQ(kMaxPaddingSize,
            rtp_sender_->TimeToSendPadding(49, PacedPacketInfo()));

  PacketOptions options;
  EXPECT_CALL(transport,
              SendRtp(_, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize, _))
      .WillOnce(DoAll(SaveArg<2>(&options), Return(true)));
  EXPECT_EQ(kPayloadSizes[0],
            rtp_sender_->TimeToSendPadding(500, PacedPacketInfo()));
  EXPECT_TRUE(options.is_retransmit);

  EXPECT_CALL(transport, SendRtp(_,
                                 kPayloadSizes[kNumPayloadSizes - 1] +
                                     rtp_header_len + kRtxHeaderSize,
                                 _))
      .WillOnce(Return(true));

  options.is_retransmit = false;
  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
      .WillOnce(DoAll(SaveArg<2>(&options), Return(true)));
  EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kMaxPaddingSize,
            rtp_sender_->TimeToSendPadding(999, PacedPacketInfo()));
  EXPECT_FALSE(options.is_retransmit);
}

TEST_P(RtpSenderTest, SendRedundantPayloadsUsefulPadding) {
  if (!GetParam().pacer_references_packets) {
    // If PacedSender owns the RTP packets, GeneratePadding() family of methods
    // will be called instead and this test makes no sense.
    return;
  }

  test::ScopedFieldTrials field_trials(
      "WebRTC-PayloadPadding-UseMostUsefulPacket/Enabled/");
  MockTransport transport;
  RtpRtcp::Configuration config;
  config.clock = &fake_clock_;
  config.outgoing_transport = &transport;
  config.paced_sender = &mock_paced_sender_;
  config.media_send_ssrc = kSsrc;
  config.rtx_send_ssrc = kRtxSsrc;
  config.event_log = &mock_rtc_event_log_;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  rtp_sender_->SetSequenceNumber(kSeqNum);
  rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);

  uint16_t seq_num = kSeqNum;
  rtp_sender_->SetStorePacketsStatus(true, 10);
  int32_t rtp_header_len = kRtpHeaderSize;
  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.

  rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);

  const size_t kNumPayloadSizes = 10;
  const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700,
                                                  750, 800, 850, 900, 950};
  // Expect all packets go through the pacer.
  EXPECT_CALL(mock_rtc_event_log_,
              LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
      .Times(kNumPayloadSizes);

  // Send 10 packets of increasing size.
  for (size_t i = 0; i < kNumPayloadSizes; ++i) {
    int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();

    EXPECT_CALL(transport, SendRtp(_, _, _)).WillOnce(::testing::Return(true));

    if (GetParam().pacer_references_packets) {
      EXPECT_CALL(mock_paced_sender_, InsertPacket(_, kSsrc, seq_num, _, _, _));
      SendPacket(capture_time_ms, kPayloadSizes[i]);
      rtp_sender_->TimeToSendPacket(kSsrc, seq_num,
                                    fake_clock_.TimeInMilliseconds(), false,
                                    PacedPacketInfo());
    } else {
      EXPECT_CALL(
          mock_paced_sender_,
          EnqueuePacket(AllOf(
              Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
              Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
      auto packet = SendPacket(capture_time_ms, kPayloadSizes[i]);
      packet->set_packet_type(RtpPacketToSend::Type::kVideo);
      rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
    }

    ++seq_num;
    fake_clock_.AdvanceTimeMilliseconds(33);
  }

  EXPECT_CALL(mock_rtc_event_log_,
              LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
      .Times(AtLeast(4));

  // The amount of padding to send it too small to send a payload packet.
  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
      .WillOnce(Return(true));
  EXPECT_EQ(kMaxPaddingSize,
            rtp_sender_->TimeToSendPadding(49, PacedPacketInfo()));

  // Payload padding will prefer packets with lower transmit count first and
  // lower age second.
  EXPECT_CALL(transport, SendRtp(_,
                                 kPayloadSizes[kNumPayloadSizes - 1] +
                                     rtp_header_len + kRtxHeaderSize,
                                 Field(&PacketOptions::is_retransmit, true)))
      .WillOnce(Return(true));
  EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1],
            rtp_sender_->TimeToSendPadding(500, PacedPacketInfo()));

  EXPECT_CALL(transport, SendRtp(_,
                                 kPayloadSizes[kNumPayloadSizes - 2] +
                                     rtp_header_len + kRtxHeaderSize,
                                 _))
      .WillOnce(Return(true));

  EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len,
                                 Field(&PacketOptions::is_retransmit, false)))
      .WillOnce(Return(true));
  EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 2] + kMaxPaddingSize,
            rtp_sender_->TimeToSendPadding(
                kPayloadSizes[kNumPayloadSizes - 2] + 49, PacedPacketInfo()));
}

TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
  const char payload_name[] = "GENERIC";
  const uint8_t payload_type = 127;
  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
                                  &playout_delay_oracle, nullptr, false, false,
                                  FieldTrialBasedConfig());
  rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
                                       /*raw_payload=*/false);
  uint8_t payload[] = {47, 11, 32, 93, 89};

  // Send keyframe
  RTPVideoHeader video_header;
  ASSERT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
      sizeof(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;

  ASSERT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
      sizeof(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 char payload_name[] = "VP8";
  const uint8_t payload_type = 111;
  const uint8_t payload[] = {11, 22, 33, 44, 55};

  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
                                  &playout_delay_oracle, nullptr, false, false,
                                  FieldTrialBasedConfig());
  rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
                                       /*raw_payload=*/true);

  // Send a frame.
  RTPVideoHeader video_header;
  ASSERT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
      sizeof(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 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.media_send_ssrc = kSsrc;
  config.flexfec_sender = &flexfec_sender_;
  config.transport_sequence_number_allocator = &seq_num_allocator_;
  config.event_log = &mock_rtc_event_log_;
  config.send_packet_observer = &send_packet_observer_;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  rtp_sender_->SetSequenceNumber(kSeqNum);
  rtp_sender_->SetStorePacketsStatus(true, 10);

  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(
      &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
      nullptr, false, false, FieldTrialBasedConfig());
  rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
                                       /*raw_payload=*/false);

  // 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;

  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
                                                 kSsrc, kSeqNum, _, _, false));
    EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
                                                 kFlexFecSsrc, _, _, _, false))
        .WillOnce(::testing::SaveArg<2>(&flexfec_seq_num));

    EXPECT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
        fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
        nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));

    EXPECT_EQ(RtpPacketSendResult::kSuccess,
              rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
                                            fake_clock_.TimeInMilliseconds(),
                                            false, PacedPacketInfo()));
    EXPECT_EQ(RtpPacketSendResult::kSuccess,
              rtp_sender_->TimeToSendPacket(kFlexFecSsrc, flexfec_seq_num,
                                            fake_clock_.TimeInMilliseconds(),
                                            false, PacedPacketInfo()));
  } else {
    std::unique_ptr<RtpPacketToSend> media_packet;
    std::unique_ptr<RtpPacketToSend> fec_packet;

    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
        .Times(2)
        .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
          if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
            EXPECT_EQ(packet->Ssrc(), kSsrc);
            EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
            media_packet = std::move(packet);
          } else {
            EXPECT_EQ(packet->packet_type(),
                      RtpPacketToSend::Type::kForwardErrorCorrection);
            EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
            fec_packet = std::move(packet);
          }
        });

    EXPECT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
        fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
        nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
    ASSERT_TRUE(media_packet != nullptr);
    ASSERT_TRUE(fec_packet != nullptr);

    flexfec_seq_num = fec_packet->SequenceNumber();
    rtp_sender_->TrySendPacket(media_packet.get(), PacedPacketInfo());
    rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
  }

  ASSERT_EQ(2, transport_.packets_sent());
  const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
  EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
  EXPECT_EQ(kSeqNum, media_packet.SequenceNumber());
  EXPECT_EQ(kSsrc, media_packet.Ssrc());
  const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[1];
  EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
  EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
  EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
}

// TODO(ilnik): because of webrtc:7859. Once FEC moved below pacer, this test
// should be removed.
TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
  constexpr uint32_t kTimestamp = 1234;
  const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
  constexpr int kMediaPayloadType = 127;
  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.
  rtp_sender_.reset(new RTPSender(
      false, &fake_clock_, &transport_, &mock_paced_sender_,
      flexfec_sender.ssrc(), &seq_num_allocator_, nullptr, nullptr, nullptr,
      &mock_rtc_event_log_, &send_packet_observer_,
      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false,
      FieldTrialBasedConfig()));
  rtp_sender_->SetSSRC(kSsrc);
  rtp_sender_->SetSequenceNumber(kSeqNum);
  rtp_sender_->SetStorePacketsStatus(true, 10);

  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(
      &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
      nullptr, false, false, FieldTrialBasedConfig());
  rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
                                       /*raw_payload=*/false);

  // Need extension to be registered for timing frames to be sent.
  ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                   kRtpExtensionVideoTiming, kVideoTimingExtensionId));

  // 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);

  RTPVideoHeader video_header;
  video_header.video_timing.flags = VideoSendTiming::kTriggeredByTimer;

  EXPECT_CALL(mock_rtc_event_log_,
              LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
      .Times(1);
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
                                                 kSsrc, kSeqNum, _, _, false));
    EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
                                                 kFlexFecSsrc, _, _, _, false))
        .Times(0);  // Not called because packet should not be protected.

    EXPECT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
        kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr,
        &video_header, kDefaultExpectedRetransmissionTimeMs));

    EXPECT_EQ(RtpPacketSendResult::kSuccess,
              rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum,
                                            fake_clock_.TimeInMilliseconds(),
                                            false, PacedPacketInfo()));
  } else {
    std::unique_ptr<RtpPacketToSend> rtp_packet;
    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(AllOf(
            Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))))
        .WillOnce([&rtp_packet](std::unique_ptr<RtpPacketToSend> packet) {
          rtp_packet = std::move(packet);
        });

    EXPECT_CALL(
        mock_paced_sender_,
        EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc))))
        .Times(0);  // Not called because packet should not be protected.

    EXPECT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
        kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr,
        &video_header, kDefaultExpectedRetransmissionTimeMs));

    EXPECT_TRUE(
        rtp_sender_->TrySendPacket(rtp_packet.get(), PacedPacketInfo()));
  }

  ASSERT_EQ(1, transport_.packets_sent());
  const RtpPacketReceived& media_packet = transport_.sent_packets_[0];
  EXPECT_EQ(kMediaPayloadType, media_packet.PayloadType());
  EXPECT_EQ(kSeqNum, media_packet.SequenceNumber());
  EXPECT_EQ(kSsrc, media_packet.Ssrc());

  // Now try to send not a timing frame.
  uint16_t flexfec_seq_num;

  EXPECT_CALL(mock_rtc_event_log_,
              LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
      .Times(2);
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kLowPriority,
                                                 kFlexFecSsrc, _, _, _, false))
        .WillOnce(::testing::SaveArg<2>(&flexfec_seq_num));
    EXPECT_CALL(mock_paced_sender_,
                InsertPacket(RtpPacketSender::kLowPriority, kSsrc, kSeqNum + 1,
                             _, _, false));
    video_header.video_timing.flags = VideoSendTiming::kInvalid;
    EXPECT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp + 1,
        kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData), nullptr,
        &video_header, kDefaultExpectedRetransmissionTimeMs));

    EXPECT_EQ(RtpPacketSendResult::kSuccess,
              rtp_sender_->TimeToSendPacket(kSsrc, kSeqNum + 1,
                                            fake_clock_.TimeInMilliseconds(),
                                            false, PacedPacketInfo()));
    EXPECT_EQ(RtpPacketSendResult::kSuccess,
              rtp_sender_->TimeToSendPacket(kFlexFecSsrc, flexfec_seq_num,
                                            fake_clock_.TimeInMilliseconds(),
                                            false, PacedPacketInfo()));
  } else {
    std::unique_ptr<RtpPacketToSend> media_packet;
    std::unique_ptr<RtpPacketToSend> fec_packet;

    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
        .Times(2)
        .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) {
          if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
            EXPECT_EQ(packet->Ssrc(), kSsrc);
            EXPECT_EQ(packet->SequenceNumber(), kSeqNum + 1);
            media_packet = std::move(packet);
          } else {
            EXPECT_EQ(packet->packet_type(),
                      RtpPacketToSend::Type::kForwardErrorCorrection);
            EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
            fec_packet = std::move(packet);
          }
        });

    video_header.video_timing.flags = VideoSendTiming::kInvalid;
    EXPECT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp + 1,
        kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData), nullptr,
        &video_header, kDefaultExpectedRetransmissionTimeMs));

    ASSERT_TRUE(media_packet != nullptr);
    ASSERT_TRUE(fec_packet != nullptr);

    flexfec_seq_num = fec_packet->SequenceNumber();
    rtp_sender_->TrySendPacket(media_packet.get(), PacedPacketInfo());
    rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo());
  }

  ASSERT_EQ(3, transport_.packets_sent());
  const RtpPacketReceived& media_packet2 = transport_.sent_packets_[1];
  EXPECT_EQ(kMediaPayloadType, media_packet2.PayloadType());
  EXPECT_EQ(kSeqNum + 1, media_packet2.SequenceNumber());
  EXPECT_EQ(kSsrc, media_packet2.Ssrc());
  const RtpPacketReceived& flexfec_packet = transport_.sent_packets_[2];
  EXPECT_EQ(kFlexfecPayloadType, flexfec_packet.PayloadType());
  EXPECT_EQ(flexfec_seq_num, flexfec_packet.SequenceNumber());
  EXPECT_EQ(kFlexFecSsrc, flexfec_packet.Ssrc());
}

TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
  constexpr uint32_t kTimestamp = 1234;
  constexpr int kMediaPayloadType = 127;
  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.media_send_ssrc = kSsrc;
  config.flexfec_sender = &flexfec_sender;
  config.transport_sequence_number_allocator = &seq_num_allocator_;
  config.event_log = &mock_rtc_event_log_;
  config.send_packet_observer = &send_packet_observer_;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  rtp_sender_->SetSequenceNumber(kSeqNum);

  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(
      &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
      nullptr, false, false, FieldTrialBasedConfig());
  rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
                                       /*raw_payload=*/false);

  // 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;
  EXPECT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
      fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(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";

  // Register MID header extension and set the MID for the RTPSender.
  rtp_sender_->SetSendingMediaStatus(false);
  rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionMid, kMidExtensionId);
  rtp_sender_->SetMid(kMid);
  rtp_sender_->SetSendingMediaStatus(true);

  // 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";

  rtp_sender_->SetSendingMediaStatus(false);
  rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
                                          kRidExtensionId);
  rtp_sender_->SetRid(kRid);
  rtp_sender_->SetSendingMediaStatus(true);

  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";

  rtp_sender_->SetSendingMediaStatus(false);
  rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRtpStreamId,
                                          kRidExtensionId);
  rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionRepairedRtpStreamId,
                                          kRepairedRidExtensionId);
  rtp_sender_->SetRid(kRid);
  rtp_sender_->SetSendingMediaStatus(true);

  rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
  rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);

  rtp_sender_->SetStorePacketsStatus(true, 10);

  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.GetExtension<RepairedRtpStreamId>(&rid));

  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(RtpSenderTest, FecOverheadRate) {
  constexpr uint32_t kTimestamp = 1234;
  constexpr int kMediaPayloadType = 127;
  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.media_send_ssrc = kSsrc;
  config.flexfec_sender = &flexfec_sender;
  config.transport_sequence_number_allocator = &seq_num_allocator_;
  config.event_log = &mock_rtc_event_log_;
  config.send_packet_observer = &send_packet_observer_;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  rtp_sender_->SetSequenceNumber(kSeqNum);

  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(
      &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
      nullptr, false, false, FieldTrialBasedConfig());
  rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
                                       /*raw_payload=*/false);
  // 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;
  if (GetParam().pacer_references_packets) {
    EXPECT_CALL(mock_paced_sender_, InsertPacket(_, _, _, _, _, false))
        .Times(kNumMediaPackets + kNumFecPackets);
  } else {
    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
        .Times(kNumMediaPackets + kNumFecPackets);
  }
  for (size_t i = 0; i < kNumMediaPackets; ++i) {
    RTPVideoHeader video_header;

    EXPECT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp,
        fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(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.media_send_ssrc = kSsrc;
  config.send_bitrate_observer = &callback;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
                                  &playout_delay_oracle, nullptr, false, false,
                                  FieldTrialBasedConfig());
  const char payload_name[] = "GENERIC";
  const uint8_t payload_type = 127;
  rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
                                       /*raw_payload=*/false);

  // 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_->SetStorePacketsStatus(true, 1);
  uint32_t ssrc = rtp_sender_->SSRC();

  // Initial process call so we get a new time window.
  rtp_sender_->ProcessBitrate();

  // Send a few frames.
  RTPVideoHeader video_header;
  for (uint32_t i = 0; i < kNumPackets; ++i) {
    ASSERT_TRUE(rtp_sender_video.SendVideo(
        VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
        sizeof(payload), nullptr, &video_header,
        kDefaultExpectedRetransmissionTimeMs));
    fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
  }

  rtp_sender_->ProcessBitrate();

  // 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_);

  rtp_sender_.reset();
}

TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
  class TestCallback : public StreamDataCountersCallback {
   public:
    TestCallback() : StreamDataCountersCallback(), ssrc_(0), counters_() {}
    ~TestCallback() 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);
    }
  } callback;

  const uint8_t kRedPayloadType = 96;
  const uint8_t kUlpfecPayloadType = 97;
  const char payload_name[] = "GENERIC";
  const uint8_t payload_type = 127;
  PlayoutDelayOracle playout_delay_oracle;
  RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
                                  &playout_delay_oracle, nullptr, false, false,
                                  FieldTrialBasedConfig());
  rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
                                       /*raw_payload=*/false);
  uint8_t payload[] = {47, 11, 32, 93, 89};
  rtp_sender_->SetStorePacketsStatus(true, 1);
  uint32_t ssrc = rtp_sender_->SSRC();

  rtp_sender_->RegisterRtpStatisticsCallback(&callback);

  // Send a frame.
  RTPVideoHeader video_header;
  ASSERT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
      sizeof(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;
  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;
  callback.Matches(ssrc, expected);

  // Send padding.
  rtp_sender_->TimeToSendPadding(kMaxPaddingSize, PacedPacketInfo());
  expected.transmitted.payload_bytes = 12;
  expected.transmitted.header_bytes = 36;
  expected.transmitted.padding_bytes = kMaxPaddingSize;
  expected.transmitted.packets = 3;
  callback.Matches(ssrc, expected);

  // Send ULPFEC.
  rtp_sender_video.SetUlpfecConfig(kRedPayloadType, kUlpfecPayloadType);
  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);
  ASSERT_TRUE(rtp_sender_video.SendVideo(
      VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload,
      sizeof(payload), nullptr, &video_header,
      kDefaultExpectedRetransmissionTimeMs));
  expected.transmitted.payload_bytes = 40;
  expected.transmitted.header_bytes = 60;
  expected.transmitted.packets = 5;
  expected.fec.packets = 1;
  callback.Matches(ssrc, expected);

  rtp_sender_->RegisterRtpStatisticsCallback(nullptr);
}

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.
  rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
  rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());

  StreamDataCounters rtp_stats;
  StreamDataCounters rtx_stats;
  rtp_sender_->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_->SetStorePacketsStatus(true, 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.media_send_ssrc = kSsrc;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  config.overhead_observer = &mock_overhead_observer;
  rtp_sender_ = absl::make_unique<RTPSender>(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.media_send_ssrc = kSsrc;
  config.retransmission_rate_limiter = &retransmission_rate_limiter_;
  config.overhead_observer = &mock_overhead_observer;
  rtp_sender_ = absl::make_unique<RTPSender>(config);

  EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
  SendGenericPacket();
  SendGenericPacket();
}

TEST_P(RtpSenderTest, TrySendPacketMatchesVideo) {
  std::unique_ptr<RtpPacketToSend> packet =
      BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->set_packet_type(RtpPacketToSend::Type::kVideo);

  // Verify not sent with wrong SSRC.
  packet->SetSsrc(kSsrc + 1);
  EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // Verify sent with correct SSRC.
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kVideo);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
}

TEST_P(RtpSenderTest, TrySendPacketMatchesAudio) {
  std::unique_ptr<RtpPacketToSend> packet =
      BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->set_packet_type(RtpPacketToSend::Type::kAudio);

  // Verify not sent with wrong SSRC.
  packet->SetSsrc(kSsrc + 1);
  EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // Verify sent with correct SSRC.
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kAudio);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
}

TEST_P(RtpSenderTest, TrySendPacketMatchesRetransmissions) {
  std::unique_ptr<RtpPacketToSend> packet =
      BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);

  // Verify not sent with wrong SSRC.
  packet->SetSsrc(kSsrc + 1);
  EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // Verify sent with correct SSRC (non-RTX).
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // RTX retransmission.
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kRtxSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
}

TEST_P(RtpSenderTest, TrySendPacketMatchesPadding) {
  std::unique_ptr<RtpPacketToSend> packet =
      BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->set_packet_type(RtpPacketToSend::Type::kPadding);

  // Verify not sent with wrong SSRC.
  packet->SetSsrc(kSsrc + 1);
  EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // Verify sent with correct SSRC (non-RTX).
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kPadding);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // RTX padding.
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kRtxSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kPadding);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
}

TEST_P(RtpSenderTest, TrySendPacketMatchesFlexfec) {
  std::unique_ptr<RtpPacketToSend> packet =
      BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);

  // Verify not sent with wrong SSRC.
  packet->SetSsrc(kSsrc + 1);
  EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // Verify sent with correct SSRC.
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kFlexFecSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
}

TEST_P(RtpSenderTest, TrySendPacketMatchesUlpfec) {
  std::unique_ptr<RtpPacketToSend> packet =
      BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);

  // Verify not sent with wrong SSRC.
  packet->SetSsrc(kSsrc + 1);
  EXPECT_FALSE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));

  // Verify sent with correct SSRC.
  packet = BuildRtpPacket(kPayload, true, 0, fake_clock_.TimeInMilliseconds());
  packet->SetSsrc(kSsrc);
  packet->set_packet_type(RtpPacketToSend::Type::kForwardErrorCorrection);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
}

TEST_P(RtpSenderTest, TrySendPacketHandlesRetransmissionHistory) {
  rtp_sender_->SetStorePacketsStatus(true, 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(RtpPacketToSend::Type::kVideo);
  packet->set_allow_retransmission(true);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(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(RtpPacketToSend::Type::kRetransmission);
  packet->SetSsrc(kRtxSsrc);
  packet->set_retransmitted_sequence_number(media_sequence_number);
  packet->set_allow_retransmission(false);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(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, TrySendPacketUpdatesExtensions) {
  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(RtpPacketToSend::Type::kVideo);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(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, TrySendPacketSetsPacketOptions) {
  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(RtpPacketToSend::Type::kVideo);
  EXPECT_CALL(send_packet_observer_, OnSendPacket);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(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(RtpPacketToSend::Type::kRetransmission);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()));
  EXPECT_TRUE(transport_.last_options_.is_retransmit);
}

TEST_P(RtpSenderTest, TrySendPacketUpdatesStats) {
  const size_t kPayloadSize = 1000;

  StrictMock<MockSendSideDelayObserver> send_side_delay_observer;

  RtpRtcp::Configuration config;
  config.clock = &fake_clock_;
  config.outgoing_transport = &transport_;
  config.media_send_ssrc = kSsrc;
  config.rtx_send_ssrc = kRtxSsrc;
  config.flexfec_sender = &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_ = absl::make_unique<RTPSender>(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(RtpPacketToSend::Type::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(RtpPacketToSend::Type::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(RtpPacketToSend::Type::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));
  EXPECT_TRUE(
      rtp_sender_->TrySendPacket(video_packet.get(), PacedPacketInfo()));

  // Send packet observer not called for padding/retransmissions.
  EXPECT_CALL(send_packet_observer_, OnSendPacket(2, _, _)).Times(0);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(rtx_packet.get(), PacedPacketInfo()));

  EXPECT_CALL(send_packet_observer_,
              OnSendPacket(3, capture_time_ms, kFlexFecSsrc));
  EXPECT_TRUE(rtp_sender_->TrySendPacket(fec_packet.get(), PacedPacketInfo()));

  StreamDataCounters rtp_stats;
  StreamDataCounters rtx_stats;
  rtp_sender_->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_->SetStorePacketsStatus(true, 1);

  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(RtpPacketToSend::Type::kVideo);

  // Send a dummy video packet so it ends up in the packet history.
  EXPECT_TRUE(rtp_sender_->TrySendPacket(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);
  ASSERT_EQ(generated_packets.size(), 1u);
  auto& padding_packet = generated_packets.front();
  EXPECT_EQ(padding_packet->packet_type(), RtpPacketToSend::Type::kPadding);
  EXPECT_EQ(padding_packet->Ssrc(), kRtxSsrc);
  EXPECT_EQ(padding_packet->payload_size(),
            kPayloadPacketSize + kRtxHeaderSize);

  // 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);
  EXPECT_EQ(generated_packets.size(), 1u);
  for (auto& packet : generated_packets) {
    EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::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_EQ(padding_bytes_generated, kMaxPaddingSize);
}

TEST_P(RtpSenderTest, GeneratePaddingCreatesPurePaddingWithoutRtx) {
  rtp_sender_->SetStorePacketsStatus(true, 1);

  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(RtpPacketToSend::Type::kVideo);
  EXPECT_TRUE(rtp_sender_->TrySendPacket(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);
  EXPECT_EQ(padding_packets.size(), kExpectedNumPaddingPackets);
  for (auto& packet : padding_packets) {
    EXPECT_EQ(packet->packet_type(), RtpPacketToSend::Type::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_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());
      }
    }
  }
}

INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
                         RtpSenderTest,
                         ::testing::Values(TestConfig{false, false},
                                           TestConfig{false, true},
                                           TestConfig{true, false},
                                           TestConfig{true, true}));

INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
                         RtpSenderTestWithoutPacer,
                         ::testing::Values(TestConfig{false, false},
                                           TestConfig{true, false}));

}  // namespace webrtc
