Adds support for passing a vector of packets to the paced sender.

Bug: webrtc:10809
Change-Id: Ib2f7ce9d14ee2ce808ab745ff20baf2761811cfb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/155367
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29378}
diff --git a/audio/channel_send.cc b/audio/channel_send.cc
index fbc4583..2a969ab 100644
--- a/audio/channel_send.cc
+++ b/audio/channel_send.cc
@@ -344,9 +344,10 @@
     rtp_packet_pacer_ = rtp_packet_pacer;
   }
 
-  void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) override {
+  void EnqueuePackets(
+      std::vector<std::unique_ptr<RtpPacketToSend>> packets) override {
     rtc::CritScope lock(&crit_);
-    rtp_packet_pacer_->EnqueuePacket(std::move(packet));
+    rtp_packet_pacer_->EnqueuePackets(std::move(packets));
   }
 
  private:
diff --git a/modules/pacing/mock/mock_paced_sender.h b/modules/pacing/mock/mock_paced_sender.h
index fbbac3a..b09b284 100644
--- a/modules/pacing/mock/mock_paced_sender.h
+++ b/modules/pacing/mock/mock_paced_sender.h
@@ -24,7 +24,8 @@
  public:
   MockPacedSender()
       : PacedSender(Clock::GetRealTimeClock(), nullptr, nullptr) {}
-  MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend> packet));
+  MOCK_METHOD1(EnqueuePackets,
+               void(std::vector<std::unique_ptr<RtpPacketToSend>> packet));
   MOCK_METHOD2(CreateProbeCluster, void(DataRate, int));
   MOCK_METHOD2(SetPacingRates, void(DataRate, DataRate));
   MOCK_CONST_METHOD0(OldestPacketWaitTime, TimeDelta());
diff --git a/modules/pacing/paced_sender.cc b/modules/pacing/paced_sender.cc
index de9a420..9326de0 100644
--- a/modules/pacing/paced_sender.cc
+++ b/modules/pacing/paced_sender.cc
@@ -91,9 +91,12 @@
   pacing_controller_.SetPacingRates(pacing_rate, padding_rate);
 }
 
-void PacedSender::EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) {
+void PacedSender::EnqueuePackets(
+    std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
   rtc::CritScope cs(&critsect_);
-  pacing_controller_.EnqueuePacket(std::move(packet));
+  for (auto& packet : packets) {
+    pacing_controller_.EnqueuePacket(std::move(packet));
+  }
 }
 
 void PacedSender::SetAccountForAudioPackets(bool account_for_audio) {
diff --git a/modules/pacing/paced_sender.h b/modules/pacing/paced_sender.h
index 34141d8..b7a3b9b 100644
--- a/modules/pacing/paced_sender.h
+++ b/modules/pacing/paced_sender.h
@@ -72,7 +72,8 @@
 
   // Adds the packet to the queue and calls PacketRouter::SendPacket() when
   // it's time to send.
-  void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) override;
+  void EnqueuePackets(
+      std::vector<std::unique_ptr<RtpPacketToSend>> packet) override;
 
   // Methods implementing RtpPacketPacer:
 
diff --git a/modules/pacing/paced_sender_unittest.cc b/modules/pacing/paced_sender_unittest.cc
index 7eb5350..feb6c07 100644
--- a/modules/pacing/paced_sender_unittest.cc
+++ b/modules/pacing/paced_sender_unittest.cc
@@ -88,9 +88,11 @@
   static constexpr size_t kPacketsToSend = 42;
   pacer.SetPacingRates(DataRate::bps(kDefaultPacketSize * 8 * kPacketsToSend),
                        DataRate::Zero());
+  std::vector<std::unique_ptr<RtpPacketToSend>> packets;
   for (size_t i = 0; i < kPacketsToSend; ++i) {
-    pacer.EnqueuePacket(BuildRtpPacket(RtpPacketToSend::Type::kVideo));
+    packets.emplace_back(BuildRtpPacket(RtpPacketToSend::Type::kVideo));
   }
+  pacer.EnqueuePackets(std::move(packets));
 
   // Expect all of them to be sent.
   size_t packets_sent = 0;
diff --git a/modules/rtp_rtcp/include/rtp_packet_sender.h b/modules/rtp_rtcp/include/rtp_packet_sender.h
index 9b7b23e..ae221b0 100644
--- a/modules/rtp_rtcp/include/rtp_packet_sender.h
+++ b/modules/rtp_rtcp/include/rtp_packet_sender.h
@@ -12,6 +12,7 @@
 #define MODULES_RTP_RTCP_INCLUDE_RTP_PACKET_SENDER_H_
 
 #include <memory>
+#include <vector>
 
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
@@ -22,10 +23,11 @@
  public:
   virtual ~RtpPacketSender() = default;
 
-  // Insert packet into queue, for eventual transmission. Based on the type of
-  // the packet, it will be prioritized and scheduled relative to other packets
-  // and the current target send rate.
-  virtual void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) = 0;
+  // Insert a set of packets into queue, for eventual transmission. Based on the
+  // type of packets, they will be prioritized and scheduled relative to other
+  // packets and the current target send rate.
+  virtual void EnqueuePackets(
+      std::vector<std::unique_ptr<RtpPacketToSend>> packets) = 0;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index b95041a..c88e0e2 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -107,15 +107,17 @@
     : transport_sequence_number_(0), rtp_sender_(rtp_sender) {}
 RTPSender::NonPacedPacketSender::~NonPacedPacketSender() = default;
 
-void RTPSender::NonPacedPacketSender::EnqueuePacket(
-    std::unique_ptr<RtpPacketToSend> packet) {
-  if (!packet->SetExtension<TransportSequenceNumber>(
-          ++transport_sequence_number_)) {
-    --transport_sequence_number_;
+void RTPSender::NonPacedPacketSender::EnqueuePackets(
+    std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+  for (auto& packet : packets) {
+    if (!packet->SetExtension<TransportSequenceNumber>(
+            ++transport_sequence_number_)) {
+      --transport_sequence_number_;
+    }
+    packet->ReserveExtension<TransmissionOffset>();
+    packet->ReserveExtension<AbsoluteSendTime>();
+    rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
   }
-  packet->ReserveExtension<TransmissionOffset>();
-  packet->ReserveExtension<AbsoluteSendTime>();
-  rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
 }
 
 RTPSender::RTPSender(const RtpRtcp::Configuration& config)
@@ -341,7 +343,9 @@
     return -1;
   }
   packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
-  paced_sender_->EnqueuePacket(std::move(packet));
+  std::vector<std::unique_ptr<RtpPacketToSend>> packets;
+  packets.emplace_back(std::move(packet));
+  paced_sender_->EnqueuePackets(std::move(packets));
 
   return packet_size;
 }
@@ -676,11 +680,29 @@
     packet->set_capture_time_ms(now_ms);
   }
 
-  paced_sender_->EnqueuePacket(std::move(packet));
+  std::vector<std::unique_ptr<RtpPacketToSend>> packets;
+  packets.emplace_back(std::move(packet));
+  paced_sender_->EnqueuePackets(std::move(packets));
 
   return true;
 }
 
+void RTPSender::EnqueuePackets(
+    std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+  RTC_DCHECK(!packets.empty());
+  int64_t now_ms = clock_->TimeInMilliseconds();
+  for (auto& packet : packets) {
+    RTC_DCHECK(packet);
+    RTC_CHECK(packet->packet_type().has_value())
+        << "Packet type must be set before sending.";
+    if (packet->capture_time_ms() <= 0) {
+      packet->set_capture_time_ms(now_ms);
+    }
+  }
+
+  paced_sender_->EnqueuePackets(std::move(packets));
+}
+
 void RTPSender::RecomputeMaxSendDelay() {
   max_delay_it_ = send_delays_.begin();
   for (auto it = send_delays_.begin(); it != send_delays_.end(); ++it) {
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index bff2090..d0a8396 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -148,8 +148,13 @@
   absl::optional<uint32_t> FlexfecSsrc() const;
 
   // Sends packet to |transport_| or to the pacer, depending on configuration.
+  // TODO(bugs.webrtc.org/XXX): Remove in favor of EnqueuePackets().
   bool SendToNetwork(std::unique_ptr<RtpPacketToSend> packet);
 
+  // Pass a set of packets to RtpPacketSender instance, for paced or immediate
+  // sending to the network.
+  void EnqueuePackets(std::vector<std::unique_ptr<RtpPacketToSend>> packets);
+
   // Called on update of RTP statistics.
   void RegisterRtpStatisticsCallback(StreamDataCountersCallback* callback);
   StreamDataCountersCallback* GetRtpStatisticsCallback() const;
@@ -180,7 +185,8 @@
     explicit NonPacedPacketSender(RTPSender* rtp_sender);
     virtual ~NonPacedPacketSender();
 
-    void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) override;
+    void EnqueuePackets(
+        std::vector<std::unique_ptr<RtpPacketToSend>> packets) override;
 
    private:
     uint16_t transport_sequence_number_;
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index ef13d80..1138591 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -73,6 +73,7 @@
 
 using ::testing::_;
 using ::testing::AllOf;
+using ::testing::Contains;
 using ::testing::ElementsAreArray;
 using ::testing::Field;
 using ::testing::NiceMock;
@@ -153,7 +154,8 @@
   MockRtpPacketPacer() {}
   virtual ~MockRtpPacketPacer() {}
 
-  MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend>));
+  MOCK_METHOD1(EnqueuePackets,
+               void(std::vector<std::unique_ptr<RtpPacketToSend>>));
 
   MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id));
 
@@ -694,9 +696,9 @@
 
   EXPECT_CALL(
       mock_paced_sender_,
-      EnqueuePacket(
-          AllOf(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
-                Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
+      EnqueuePackets(Contains(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().
@@ -729,8 +731,8 @@
   const int kStoredTimeInMs = 100;
   packet->set_packet_type(RtpPacketToSend::Type::kVideo);
   packet->set_allow_retransmission(true);
-  EXPECT_CALL(mock_paced_sender_,
-              EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
+  EXPECT_CALL(mock_paced_sender_, EnqueuePackets(Contains(Pointee(Property(
+                                      &RtpPacketToSend::Ssrc, kSsrc)))));
   EXPECT_TRUE(
       rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
   fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
@@ -765,9 +767,8 @@
 
     packet->set_packet_type(RtpPacketToSend::Type::kVideo);
     packet->set_allow_retransmission(true);
-    EXPECT_CALL(
-        mock_paced_sender_,
-        EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
+    EXPECT_CALL(mock_paced_sender_, EnqueuePackets(Contains(Pointee(Property(
+                                        &RtpPacketToSend::Ssrc, kSsrc)))));
     EXPECT_TRUE(
         rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
     fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
@@ -825,18 +826,18 @@
   size_t packet_size = packet->size();
 
   const int kStoredTimeInMs = 100;
-    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(std::make_unique<RtpPacketToSend>(*packet)));
-    EXPECT_EQ(0, transport_.packets_sent());
-    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
-    rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
+  EXPECT_CALL(
+      mock_paced_sender_,
+      EnqueuePackets(Contains(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(std::make_unique<RtpPacketToSend>(*packet)));
+  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());
@@ -869,17 +870,17 @@
   size_t packet_size = packet->size();
 
   // Packet should be stored in a send bucket.
-    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(std::make_unique<RtpPacketToSend>(*packet)));
-    // Immediately process send bucket and send packet.
-    rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
+  EXPECT_CALL(
+      mock_paced_sender_,
+      EnqueuePackets(Contains(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(std::make_unique<RtpPacketToSend>(*packet)));
+  // Immediately process send bucket and send packet.
+  rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
 
   EXPECT_EQ(1, transport_.packets_sent());
 
@@ -893,9 +894,9 @@
     packet->set_retransmitted_sequence_number(kSeqNum);
     EXPECT_CALL(
         mock_paced_sender_,
-        EnqueuePacket(AllOf(
+        EnqueuePackets(Contains(AllOf(
             Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
-            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))));
+            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
     EXPECT_EQ(static_cast<int>(packet_size),
               rtp_sender_->ReSendPacket(kSeqNum));
     EXPECT_EQ(1, transport_.packets_sent());
@@ -948,19 +949,19 @@
   const int kStoredTimeInMs = 100;
 
   // Packet should be stored in a send bucket.
-    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(std::make_unique<RtpPacketToSend>(*packet)));
-    EXPECT_EQ(total_packets_sent, transport_.packets_sent());
-    fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
-    rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
-    ++seq_num;
+  EXPECT_CALL(
+      mock_paced_sender_,
+      EnqueuePackets(Contains(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(std::make_unique<RtpPacketToSend>(*packet)));
+  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.
@@ -1006,9 +1007,9 @@
     packet->set_allow_retransmission(true);
     EXPECT_CALL(
         mock_paced_sender_,
-        EnqueuePacket(AllOf(
+        EnqueuePackets(Contains(AllOf(
             Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
-            Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num)))));
+            Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num))))));
     EXPECT_TRUE(
         rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
     rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
@@ -1038,15 +1039,15 @@
               OnSendPacket(kTransportSequenceNumber, _, _))
       .Times(1);
 
-    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_CALL(
+      mock_paced_sender_,
+      EnqueuePackets(Contains(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());
 }
@@ -1059,15 +1060,15 @@
 
   EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
 
-    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_CALL(
+      mock_paced_sender_,
+      EnqueuePackets(Contains(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);
@@ -1176,20 +1177,23 @@
     std::unique_ptr<RtpPacketToSend> media_packet;
     std::unique_ptr<RtpPacketToSend> fec_packet;
 
-    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
+    EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
         .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);
-          }
-        });
+        .WillRepeatedly(
+            [&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+              for (auto& packet : packets) {
+                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, kCodecType,
@@ -1268,16 +1272,18 @@
     std::unique_ptr<RtpPacketToSend> rtp_packet;
     EXPECT_CALL(
         mock_paced_sender_,
-        EnqueuePacket(AllOf(
+        EnqueuePackets(Contains(AllOf(
             Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
-            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))))
-        .WillOnce([&rtp_packet](std::unique_ptr<RtpPacketToSend> packet) {
-          rtp_packet = std::move(packet);
+            Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))))
+        .WillOnce([&rtp_packet](
+                      std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+          EXPECT_EQ(packets.size(), 1u);
+          rtp_packet = std::move(packets[0]);
         });
 
-    EXPECT_CALL(
-        mock_paced_sender_,
-        EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc))))
+    EXPECT_CALL(mock_paced_sender_,
+                EnqueuePackets(Contains(
+                    Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc)))))
         .Times(0);  // Not called because packet should not be protected.
 
     EXPECT_TRUE(rtp_sender_video.SendVideo(
@@ -1303,20 +1309,23 @@
   std::unique_ptr<RtpPacketToSend> media_packet2;
   std::unique_ptr<RtpPacketToSend> fec_packet;
 
-  EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
+  EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
       .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_packet2 = std::move(packet);
-        } else {
-          EXPECT_EQ(packet->packet_type(),
-                    RtpPacketToSend::Type::kForwardErrorCorrection);
-          EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
-          fec_packet = std::move(packet);
-        }
-      });
+      .WillRepeatedly(
+          [&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+            for (auto& packet : packets) {
+              if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
+                EXPECT_EQ(packet->Ssrc(), kSsrc);
+                EXPECT_EQ(packet->SequenceNumber(), kSeqNum + 1);
+                media_packet2 = 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(
@@ -1647,8 +1656,8 @@
   constexpr size_t kNumMediaPackets = 10;
   constexpr size_t kNumFecPackets = kNumMediaPackets;
   constexpr int64_t kTimeBetweenPacketsMs = 10;
-    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
-        .Times(kNumMediaPackets + kNumFecPackets);
+  EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
+      .Times(kNumMediaPackets + kNumFecPackets);
   for (size_t i = 0; i < kNumMediaPackets; ++i) {
     RTPVideoHeader video_header;
 
@@ -2441,10 +2450,11 @@
     packet->AllocatePayload(sizeof(kPayloadData));
 
     std::unique_ptr<RtpPacketToSend> packet_to_pace;
-    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
-        .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
-          EXPECT_GT(packet->capture_time_ms(), 0);
-          packet_to_pace = std::move(packet);
+    EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
+        .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+          EXPECT_EQ(packets.size(), 1u);
+          EXPECT_GT(packets[0]->capture_time_ms(), 0);
+          packet_to_pace = std::move(packets[0]);
         });
 
     packet->set_allow_retransmission(true);
@@ -2465,10 +2475,10 @@
   fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
 
     std::unique_ptr<RtpPacketToSend> rtx_packet_to_pace;
-    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
-        .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
-          EXPECT_GT(packet->capture_time_ms(), 0);
-          rtx_packet_to_pace = std::move(packet);
+    EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
+        .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+          EXPECT_GT(packets[0]->capture_time_ms(), 0);
+          rtx_packet_to_pace = std::move(packets[0]);
         });
 
     EXPECT_GT(rtp_sender_->ReSendPacket(kSeqNum), 0);
@@ -2548,9 +2558,9 @@
 
   // Send a packet so it is in the packet history.
     std::unique_ptr<RtpPacketToSend> packet_to_pace;
-    EXPECT_CALL(mock_paced_sender_, EnqueuePacket)
-        .WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) {
-          packet_to_pace = std::move(packet);
+    EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
+        .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
+          packet_to_pace = std::move(packets[0]);
         });
 
     SendGenericPacket();