diff --git a/audio/channel_send.cc b/audio/channel_send.cc index fbc4583ab5..2a969ab1b4 100644 --- a/audio/channel_send.cc +++ b/audio/channel_send.cc @@ -344,9 +344,10 @@ class RtpPacketSenderProxy : public RtpPacketSender { rtp_packet_pacer_ = rtp_packet_pacer; } - void EnqueuePacket(std::unique_ptr packet) override { + void EnqueuePackets( + std::vector> 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 fbbac3a876..b09b2843cd 100644 --- a/modules/pacing/mock/mock_paced_sender.h +++ b/modules/pacing/mock/mock_paced_sender.h @@ -24,7 +24,8 @@ class MockPacedSender : public PacedSender { public: MockPacedSender() : PacedSender(Clock::GetRealTimeClock(), nullptr, nullptr) {} - MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr packet)); + MOCK_METHOD1(EnqueuePackets, + void(std::vector> 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 de9a4205ad..9326de014a 100644 --- a/modules/pacing/paced_sender.cc +++ b/modules/pacing/paced_sender.cc @@ -91,9 +91,12 @@ void PacedSender::SetPacingRates(DataRate pacing_rate, DataRate padding_rate) { pacing_controller_.SetPacingRates(pacing_rate, padding_rate); } -void PacedSender::EnqueuePacket(std::unique_ptr packet) { +void PacedSender::EnqueuePackets( + std::vector> 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 34141d832a..b7a3b9b31f 100644 --- a/modules/pacing/paced_sender.h +++ b/modules/pacing/paced_sender.h @@ -72,7 +72,8 @@ class PacedSender : public Module, // Adds the packet to the queue and calls PacketRouter::SendPacket() when // it's time to send. - void EnqueuePacket(std::unique_ptr packet) override; + void EnqueuePackets( + std::vector> packet) override; // Methods implementing RtpPacketPacer: diff --git a/modules/pacing/paced_sender_unittest.cc b/modules/pacing/paced_sender_unittest.cc index 7eb5350f51..feb6c072ed 100644 --- a/modules/pacing/paced_sender_unittest.cc +++ b/modules/pacing/paced_sender_unittest.cc @@ -88,9 +88,11 @@ TEST(PacedSenderTest, PacesPackets) { static constexpr size_t kPacketsToSend = 42; pacer.SetPacingRates(DataRate::bps(kDefaultPacketSize * 8 * kPacketsToSend), DataRate::Zero()); + std::vector> 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 9b7b23ef23..ae221b09d3 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 +#include #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" @@ -22,10 +23,11 @@ class RtpPacketSender { 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 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> packets) = 0; }; } // namespace webrtc diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc index b95041a115..c88e0e20b0 100644 --- a/modules/rtp_rtcp/source/rtp_sender.cc +++ b/modules/rtp_rtcp/source/rtp_sender.cc @@ -107,15 +107,17 @@ RTPSender::NonPacedPacketSender::NonPacedPacketSender(RTPSender* rtp_sender) : transport_sequence_number_(0), rtp_sender_(rtp_sender) {} RTPSender::NonPacedPacketSender::~NonPacedPacketSender() = default; -void RTPSender::NonPacedPacketSender::EnqueuePacket( - std::unique_ptr packet) { - if (!packet->SetExtension( - ++transport_sequence_number_)) { - --transport_sequence_number_; +void RTPSender::NonPacedPacketSender::EnqueuePackets( + std::vector> packets) { + for (auto& packet : packets) { + if (!packet->SetExtension( + ++transport_sequence_number_)) { + --transport_sequence_number_; + } + packet->ReserveExtension(); + packet->ReserveExtension(); + rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); } - packet->ReserveExtension(); - packet->ReserveExtension(); - rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); } RTPSender::RTPSender(const RtpRtcp::Configuration& config) @@ -341,7 +343,9 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id) { return -1; } packet->set_packet_type(RtpPacketToSend::Type::kRetransmission); - paced_sender_->EnqueuePacket(std::move(packet)); + std::vector> packets; + packets.emplace_back(std::move(packet)); + paced_sender_->EnqueuePackets(std::move(packets)); return packet_size; } @@ -676,11 +680,29 @@ bool RTPSender::SendToNetwork(std::unique_ptr packet) { packet->set_capture_time_ms(now_ms); } - paced_sender_->EnqueuePacket(std::move(packet)); + std::vector> packets; + packets.emplace_back(std::move(packet)); + paced_sender_->EnqueuePackets(std::move(packets)); return true; } +void RTPSender::EnqueuePackets( + std::vector> 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 bff209021b..d0a8396973 100644 --- a/modules/rtp_rtcp/source/rtp_sender.h +++ b/modules/rtp_rtcp/source/rtp_sender.h @@ -148,8 +148,13 @@ class RTPSender { absl::optional 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 packet); + // Pass a set of packets to RtpPacketSender instance, for paced or immediate + // sending to the network. + void EnqueuePackets(std::vector> packets); + // Called on update of RTP statistics. void RegisterRtpStatisticsCallback(StreamDataCountersCallback* callback); StreamDataCountersCallback* GetRtpStatisticsCallback() const; @@ -180,7 +185,8 @@ class RTPSender { explicit NonPacedPacketSender(RTPSender* rtp_sender); virtual ~NonPacedPacketSender(); - void EnqueuePacket(std::unique_ptr packet) override; + void EnqueuePackets( + std::vector> 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 ef13d80aee..1138591b1d 100644 --- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -73,6 +73,7 @@ const char kNoMid[] = ""; using ::testing::_; using ::testing::AllOf; +using ::testing::Contains; using ::testing::ElementsAreArray; using ::testing::Field; using ::testing::NiceMock; @@ -153,7 +154,8 @@ class MockRtpPacketPacer : public RtpPacketSender { MockRtpPacketPacer() {} virtual ~MockRtpPacketPacer() {} - MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr)); + MOCK_METHOD1(EnqueuePackets, + void(std::vector>)); MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id)); @@ -694,9 +696,9 @@ TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) { 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 @@ TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) { 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(*packet))); fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs); @@ -765,9 +767,8 @@ TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithPacer) { 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(*packet))); fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs); @@ -825,18 +826,18 @@ TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) { 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(*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(*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 @@ TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) { 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(*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(*packet))); + // Immediately process send bucket and send packet. + rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); EXPECT_EQ(1, transport_.packets_sent()); @@ -893,9 +894,9 @@ TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) { 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(packet_size), rtp_sender_->ReSendPacket(kSeqNum)); EXPECT_EQ(1, transport_.packets_sent()); @@ -948,19 +949,19 @@ TEST_P(RtpSenderTest, SendPadding) { 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(*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(*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 @@ TEST_P(RtpSenderTest, SendPadding) { 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(*packet))); rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); @@ -1038,15 +1039,15 @@ TEST_P(RtpSenderTest, OnSendPacketUpdated) { 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(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(kTransportSequenceNumber); + rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); EXPECT_EQ(1, transport_.packets_sent()); } @@ -1059,15 +1060,15 @@ TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) { 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(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(kTransportSequenceNumber); + rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); EXPECT_EQ(1, transport_.packets_sent()); EXPECT_TRUE(transport_.last_options_.is_retransmit); @@ -1176,20 +1177,23 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) { std::unique_ptr media_packet; std::unique_ptr fec_packet; - EXPECT_CALL(mock_paced_sender_, EnqueuePacket) + EXPECT_CALL(mock_paced_sender_, EnqueuePackets) .Times(2) - .WillRepeatedly([&](std::unique_ptr 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> 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 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) { std::unique_ptr 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 packet) { - rtp_packet = std::move(packet); + Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)))))) + .WillOnce([&rtp_packet]( + std::vector> 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 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) { std::unique_ptr media_packet2; std::unique_ptr fec_packet; - EXPECT_CALL(mock_paced_sender_, EnqueuePacket) + EXPECT_CALL(mock_paced_sender_, EnqueuePackets) .Times(2) - .WillRepeatedly([&](std::unique_ptr 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> 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 @@ TEST_P(RtpSenderTest, FecOverheadRate) { 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 @@ TEST_P(RtpSenderTest, SetsCaptureTimeAndPopulatesTransmissionOffset) { packet->AllocatePayload(sizeof(kPayloadData)); std::unique_ptr packet_to_pace; - EXPECT_CALL(mock_paced_sender_, EnqueuePacket) - .WillOnce([&](std::unique_ptr packet) { - EXPECT_GT(packet->capture_time_ms(), 0); - packet_to_pace = std::move(packet); + EXPECT_CALL(mock_paced_sender_, EnqueuePackets) + .WillOnce([&](std::vector> 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 @@ TEST_P(RtpSenderTest, SetsCaptureTimeAndPopulatesTransmissionOffset) { fake_clock_.AdvanceTimeMilliseconds(kOffsetMs); std::unique_ptr rtx_packet_to_pace; - EXPECT_CALL(mock_paced_sender_, EnqueuePacket) - .WillOnce([&](std::unique_ptr packet) { - EXPECT_GT(packet->capture_time_ms(), 0); - rtx_packet_to_pace = std::move(packet); + EXPECT_CALL(mock_paced_sender_, EnqueuePackets) + .WillOnce([&](std::vector> 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 @@ TEST_P(RtpSenderTest, IgnoresNackAfterDisablingMedia) { // Send a packet so it is in the packet history. std::unique_ptr packet_to_pace; - EXPECT_CALL(mock_paced_sender_, EnqueuePacket) - .WillOnce([&](std::unique_ptr packet) { - packet_to_pace = std::move(packet); + EXPECT_CALL(mock_paced_sender_, EnqueuePackets) + .WillOnce([&](std::vector> packets) { + packet_to_pace = std::move(packets[0]); }); SendGenericPacket();