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}
This commit is contained in:
Erik Språng
2019-10-02 14:57:46 +02:00
committed by Commit Bot
parent 79f3287fcf
commit ea55b0872f
9 changed files with 183 additions and 135 deletions

View File

@ -344,9 +344,10 @@ class RtpPacketSenderProxy : public RtpPacketSender {
rtp_packet_pacer_ = rtp_packet_pacer; 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_); rtc::CritScope lock(&crit_);
rtp_packet_pacer_->EnqueuePacket(std::move(packet)); rtp_packet_pacer_->EnqueuePackets(std::move(packets));
} }
private: private:

View File

@ -24,7 +24,8 @@ class MockPacedSender : public PacedSender {
public: public:
MockPacedSender() MockPacedSender()
: PacedSender(Clock::GetRealTimeClock(), nullptr, nullptr) {} : 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(CreateProbeCluster, void(DataRate, int));
MOCK_METHOD2(SetPacingRates, void(DataRate, DataRate)); MOCK_METHOD2(SetPacingRates, void(DataRate, DataRate));
MOCK_CONST_METHOD0(OldestPacketWaitTime, TimeDelta()); MOCK_CONST_METHOD0(OldestPacketWaitTime, TimeDelta());

View File

@ -91,9 +91,12 @@ void PacedSender::SetPacingRates(DataRate pacing_rate, DataRate padding_rate) {
pacing_controller_.SetPacingRates(pacing_rate, padding_rate); 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_); 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) { void PacedSender::SetAccountForAudioPackets(bool account_for_audio) {

View File

@ -72,7 +72,8 @@ class PacedSender : public Module,
// Adds the packet to the queue and calls PacketRouter::SendPacket() when // Adds the packet to the queue and calls PacketRouter::SendPacket() when
// it's time to send. // 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: // Methods implementing RtpPacketPacer:

View File

@ -88,9 +88,11 @@ TEST(PacedSenderTest, PacesPackets) {
static constexpr size_t kPacketsToSend = 42; static constexpr size_t kPacketsToSend = 42;
pacer.SetPacingRates(DataRate::bps(kDefaultPacketSize * 8 * kPacketsToSend), pacer.SetPacingRates(DataRate::bps(kDefaultPacketSize * 8 * kPacketsToSend),
DataRate::Zero()); DataRate::Zero());
std::vector<std::unique_ptr<RtpPacketToSend>> packets;
for (size_t i = 0; i < kPacketsToSend; ++i) { 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. // Expect all of them to be sent.
size_t packets_sent = 0; size_t packets_sent = 0;

View File

@ -12,6 +12,7 @@
#define MODULES_RTP_RTCP_INCLUDE_RTP_PACKET_SENDER_H_ #define MODULES_RTP_RTCP_INCLUDE_RTP_PACKET_SENDER_H_
#include <memory> #include <memory>
#include <vector>
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
@ -22,10 +23,11 @@ class RtpPacketSender {
public: public:
virtual ~RtpPacketSender() = default; virtual ~RtpPacketSender() = default;
// Insert packet into queue, for eventual transmission. Based on the type of // Insert a set of packets into queue, for eventual transmission. Based on the
// the packet, it will be prioritized and scheduled relative to other packets // type of packets, they will be prioritized and scheduled relative to other
// and the current target send rate. // packets and the current target send rate.
virtual void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) = 0; virtual void EnqueuePackets(
std::vector<std::unique_ptr<RtpPacketToSend>> packets) = 0;
}; };
} // namespace webrtc } // namespace webrtc

View File

@ -107,15 +107,17 @@ RTPSender::NonPacedPacketSender::NonPacedPacketSender(RTPSender* rtp_sender)
: transport_sequence_number_(0), rtp_sender_(rtp_sender) {} : transport_sequence_number_(0), rtp_sender_(rtp_sender) {}
RTPSender::NonPacedPacketSender::~NonPacedPacketSender() = default; RTPSender::NonPacedPacketSender::~NonPacedPacketSender() = default;
void RTPSender::NonPacedPacketSender::EnqueuePacket( void RTPSender::NonPacedPacketSender::EnqueuePackets(
std::unique_ptr<RtpPacketToSend> packet) { std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
if (!packet->SetExtension<TransportSequenceNumber>( for (auto& packet : packets) {
++transport_sequence_number_)) { if (!packet->SetExtension<TransportSequenceNumber>(
--transport_sequence_number_; ++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) RTPSender::RTPSender(const RtpRtcp::Configuration& config)
@ -341,7 +343,9 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id) {
return -1; return -1;
} }
packet->set_packet_type(RtpPacketToSend::Type::kRetransmission); 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; return packet_size;
} }
@ -676,11 +680,29 @@ bool RTPSender::SendToNetwork(std::unique_ptr<RtpPacketToSend> packet) {
packet->set_capture_time_ms(now_ms); 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; 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() { void RTPSender::RecomputeMaxSendDelay() {
max_delay_it_ = send_delays_.begin(); max_delay_it_ = send_delays_.begin();
for (auto it = send_delays_.begin(); it != send_delays_.end(); ++it) { for (auto it = send_delays_.begin(); it != send_delays_.end(); ++it) {

View File

@ -148,8 +148,13 @@ class RTPSender {
absl::optional<uint32_t> FlexfecSsrc() const; absl::optional<uint32_t> FlexfecSsrc() const;
// Sends packet to |transport_| or to the pacer, depending on configuration. // 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); 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. // Called on update of RTP statistics.
void RegisterRtpStatisticsCallback(StreamDataCountersCallback* callback); void RegisterRtpStatisticsCallback(StreamDataCountersCallback* callback);
StreamDataCountersCallback* GetRtpStatisticsCallback() const; StreamDataCountersCallback* GetRtpStatisticsCallback() const;
@ -180,7 +185,8 @@ class RTPSender {
explicit NonPacedPacketSender(RTPSender* rtp_sender); explicit NonPacedPacketSender(RTPSender* rtp_sender);
virtual ~NonPacedPacketSender(); virtual ~NonPacedPacketSender();
void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) override; void EnqueuePackets(
std::vector<std::unique_ptr<RtpPacketToSend>> packets) override;
private: private:
uint16_t transport_sequence_number_; uint16_t transport_sequence_number_;

View File

@ -73,6 +73,7 @@ const char kNoMid[] = "";
using ::testing::_; using ::testing::_;
using ::testing::AllOf; using ::testing::AllOf;
using ::testing::Contains;
using ::testing::ElementsAreArray; using ::testing::ElementsAreArray;
using ::testing::Field; using ::testing::Field;
using ::testing::NiceMock; using ::testing::NiceMock;
@ -153,7 +154,8 @@ class MockRtpPacketPacer : public RtpPacketSender {
MockRtpPacketPacer() {} MockRtpPacketPacer() {}
virtual ~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)); MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id));
@ -694,9 +696,9 @@ TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) {
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket( EnqueuePackets(Contains(AllOf(
AllOf(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
auto packet = SendGenericPacket(); auto packet = SendGenericPacket();
packet->set_packet_type(RtpPacketToSend::Type::kVideo); packet->set_packet_type(RtpPacketToSend::Type::kVideo);
// Transport sequence number is set by PacketRouter, before TrySendPacket(). // Transport sequence number is set by PacketRouter, before TrySendPacket().
@ -729,8 +731,8 @@ TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) {
const int kStoredTimeInMs = 100; const int kStoredTimeInMs = 100;
packet->set_packet_type(RtpPacketToSend::Type::kVideo); packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->set_allow_retransmission(true); packet->set_allow_retransmission(true);
EXPECT_CALL(mock_paced_sender_, EXPECT_CALL(mock_paced_sender_, EnqueuePackets(Contains(Pointee(Property(
EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)))); &RtpPacketToSend::Ssrc, kSsrc)))));
EXPECT_TRUE( EXPECT_TRUE(
rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet))); rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs); fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
@ -765,9 +767,8 @@ TEST_P(RtpSenderTest, WritesNetwork2ToTimingExtensionWithPacer) {
packet->set_packet_type(RtpPacketToSend::Type::kVideo); packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->set_allow_retransmission(true); packet->set_allow_retransmission(true);
EXPECT_CALL( EXPECT_CALL(mock_paced_sender_, EnqueuePackets(Contains(Pointee(Property(
mock_paced_sender_, &RtpPacketToSend::Ssrc, kSsrc)))));
EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc))));
EXPECT_TRUE( EXPECT_TRUE(
rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet))); rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs); fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
@ -825,18 +826,18 @@ TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) {
size_t packet_size = packet->size(); size_t packet_size = packet->size();
const int kStoredTimeInMs = 100; const int kStoredTimeInMs = 100;
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
packet->set_packet_type(RtpPacketToSend::Type::kVideo); packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->set_allow_retransmission(true); packet->set_allow_retransmission(true);
EXPECT_TRUE( EXPECT_TRUE(
rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet))); rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
EXPECT_EQ(0, transport_.packets_sent()); EXPECT_EQ(0, transport_.packets_sent());
fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs); fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
// Process send bucket. Packet should now be sent. // Process send bucket. Packet should now be sent.
EXPECT_EQ(1, transport_.packets_sent()); EXPECT_EQ(1, transport_.packets_sent());
@ -869,17 +870,17 @@ TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) {
size_t packet_size = packet->size(); size_t packet_size = packet->size();
// Packet should be stored in a send bucket. // Packet should be stored in a send bucket.
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
packet->set_packet_type(RtpPacketToSend::Type::kVideo); packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->set_allow_retransmission(true); packet->set_allow_retransmission(true);
EXPECT_TRUE( EXPECT_TRUE(
rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet))); rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
// Immediately process send bucket and send packet. // Immediately process send bucket and send packet.
rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
EXPECT_EQ(1, transport_.packets_sent()); EXPECT_EQ(1, transport_.packets_sent());
@ -893,9 +894,9 @@ TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) {
packet->set_retransmitted_sequence_number(kSeqNum); packet->set_retransmitted_sequence_number(kSeqNum);
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
EXPECT_EQ(static_cast<int>(packet_size), EXPECT_EQ(static_cast<int>(packet_size),
rtp_sender_->ReSendPacket(kSeqNum)); rtp_sender_->ReSendPacket(kSeqNum));
EXPECT_EQ(1, transport_.packets_sent()); EXPECT_EQ(1, transport_.packets_sent());
@ -948,19 +949,19 @@ TEST_P(RtpSenderTest, SendPadding) {
const int kStoredTimeInMs = 100; const int kStoredTimeInMs = 100;
// Packet should be stored in a send bucket. // Packet should be stored in a send bucket.
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
packet->set_packet_type(RtpPacketToSend::Type::kVideo); packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->set_allow_retransmission(true); packet->set_allow_retransmission(true);
EXPECT_TRUE( EXPECT_TRUE(
rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet))); rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
EXPECT_EQ(total_packets_sent, transport_.packets_sent()); EXPECT_EQ(total_packets_sent, transport_.packets_sent());
fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs); fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
++seq_num; ++seq_num;
// Packet should now be sent. This test doesn't verify the regular video // Packet should now be sent. This test doesn't verify the regular video
// packet, since it is tested in another test. // packet, since it is tested in another test.
@ -1006,9 +1007,9 @@ TEST_P(RtpSenderTest, SendPadding) {
packet->set_allow_retransmission(true); packet->set_allow_retransmission(true);
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, seq_num))))));
EXPECT_TRUE( EXPECT_TRUE(
rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet))); rtp_sender_->SendToNetwork(std::make_unique<RtpPacketToSend>(*packet)));
rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
@ -1038,15 +1039,15 @@ TEST_P(RtpSenderTest, OnSendPacketUpdated) {
OnSendPacket(kTransportSequenceNumber, _, _)) OnSendPacket(kTransportSequenceNumber, _, _))
.Times(1); .Times(1);
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
auto packet = SendGenericPacket(); auto packet = SendGenericPacket();
packet->set_packet_type(RtpPacketToSend::Type::kVideo); packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber); packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
EXPECT_EQ(1, transport_.packets_sent()); EXPECT_EQ(1, transport_.packets_sent());
} }
@ -1059,15 +1060,15 @@ TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0); EXPECT_CALL(send_packet_observer_, OnSendPacket(_, _, _)).Times(0);
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))); Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))));
auto packet = SendGenericPacket(); auto packet = SendGenericPacket();
packet->set_packet_type(RtpPacketToSend::Type::kRetransmission); packet->set_packet_type(RtpPacketToSend::Type::kRetransmission);
packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber); packet->SetExtension<TransportSequenceNumber>(kTransportSequenceNumber);
rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo()); rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
EXPECT_EQ(1, transport_.packets_sent()); EXPECT_EQ(1, transport_.packets_sent());
EXPECT_TRUE(transport_.last_options_.is_retransmit); EXPECT_TRUE(transport_.last_options_.is_retransmit);
@ -1176,20 +1177,23 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
std::unique_ptr<RtpPacketToSend> media_packet; std::unique_ptr<RtpPacketToSend> media_packet;
std::unique_ptr<RtpPacketToSend> fec_packet; std::unique_ptr<RtpPacketToSend> fec_packet;
EXPECT_CALL(mock_paced_sender_, EnqueuePacket) EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
.Times(2) .Times(2)
.WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) { .WillRepeatedly(
if (packet->packet_type() == RtpPacketToSend::Type::kVideo) { [&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
EXPECT_EQ(packet->Ssrc(), kSsrc); for (auto& packet : packets) {
EXPECT_EQ(packet->SequenceNumber(), kSeqNum); if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
media_packet = std::move(packet); EXPECT_EQ(packet->Ssrc(), kSsrc);
} else { EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
EXPECT_EQ(packet->packet_type(), media_packet = std::move(packet);
RtpPacketToSend::Type::kForwardErrorCorrection); } else {
EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc); EXPECT_EQ(packet->packet_type(),
fec_packet = std::move(packet); RtpPacketToSend::Type::kForwardErrorCorrection);
} EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
}); fec_packet = std::move(packet);
}
}
});
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kMediaPayloadType, kCodecType, VideoFrameType::kVideoFrameKey, kMediaPayloadType, kCodecType,
@ -1268,16 +1272,18 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
std::unique_ptr<RtpPacketToSend> rtp_packet; std::unique_ptr<RtpPacketToSend> rtp_packet;
EXPECT_CALL( EXPECT_CALL(
mock_paced_sender_, mock_paced_sender_,
EnqueuePacket(AllOf( EnqueuePackets(Contains(AllOf(
Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)),
Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))) Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum))))))
.WillOnce([&rtp_packet](std::unique_ptr<RtpPacketToSend> packet) { .WillOnce([&rtp_packet](
rtp_packet = std::move(packet); std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
EXPECT_EQ(packets.size(), 1u);
rtp_packet = std::move(packets[0]);
}); });
EXPECT_CALL( EXPECT_CALL(mock_paced_sender_,
mock_paced_sender_, EnqueuePackets(Contains(
EnqueuePacket(Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc)))) Pointee(Property(&RtpPacketToSend::Ssrc, kFlexFecSsrc)))))
.Times(0); // Not called because packet should not be protected. .Times(0); // Not called because packet should not be protected.
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
@ -1303,20 +1309,23 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
std::unique_ptr<RtpPacketToSend> media_packet2; std::unique_ptr<RtpPacketToSend> media_packet2;
std::unique_ptr<RtpPacketToSend> fec_packet; std::unique_ptr<RtpPacketToSend> fec_packet;
EXPECT_CALL(mock_paced_sender_, EnqueuePacket) EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
.Times(2) .Times(2)
.WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet) { .WillRepeatedly(
if (packet->packet_type() == RtpPacketToSend::Type::kVideo) { [&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
EXPECT_EQ(packet->Ssrc(), kSsrc); for (auto& packet : packets) {
EXPECT_EQ(packet->SequenceNumber(), kSeqNum + 1); if (packet->packet_type() == RtpPacketToSend::Type::kVideo) {
media_packet2 = std::move(packet); EXPECT_EQ(packet->Ssrc(), kSsrc);
} else { EXPECT_EQ(packet->SequenceNumber(), kSeqNum + 1);
EXPECT_EQ(packet->packet_type(), media_packet2 = std::move(packet);
RtpPacketToSend::Type::kForwardErrorCorrection); } else {
EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc); EXPECT_EQ(packet->packet_type(),
fec_packet = std::move(packet); RtpPacketToSend::Type::kForwardErrorCorrection);
} EXPECT_EQ(packet->Ssrc(), kFlexFecSsrc);
}); fec_packet = std::move(packet);
}
}
});
video_header.video_timing.flags = VideoSendTiming::kInvalid; video_header.video_timing.flags = VideoSendTiming::kInvalid;
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
@ -1647,8 +1656,8 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
constexpr size_t kNumMediaPackets = 10; constexpr size_t kNumMediaPackets = 10;
constexpr size_t kNumFecPackets = kNumMediaPackets; constexpr size_t kNumFecPackets = kNumMediaPackets;
constexpr int64_t kTimeBetweenPacketsMs = 10; constexpr int64_t kTimeBetweenPacketsMs = 10;
EXPECT_CALL(mock_paced_sender_, EnqueuePacket) EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
.Times(kNumMediaPackets + kNumFecPackets); .Times(kNumMediaPackets + kNumFecPackets);
for (size_t i = 0; i < kNumMediaPackets; ++i) { for (size_t i = 0; i < kNumMediaPackets; ++i) {
RTPVideoHeader video_header; RTPVideoHeader video_header;
@ -2441,10 +2450,11 @@ TEST_P(RtpSenderTest, SetsCaptureTimeAndPopulatesTransmissionOffset) {
packet->AllocatePayload(sizeof(kPayloadData)); packet->AllocatePayload(sizeof(kPayloadData));
std::unique_ptr<RtpPacketToSend> packet_to_pace; std::unique_ptr<RtpPacketToSend> packet_to_pace;
EXPECT_CALL(mock_paced_sender_, EnqueuePacket) EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
.WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) { .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
EXPECT_GT(packet->capture_time_ms(), 0); EXPECT_EQ(packets.size(), 1u);
packet_to_pace = std::move(packet); EXPECT_GT(packets[0]->capture_time_ms(), 0);
packet_to_pace = std::move(packets[0]);
}); });
packet->set_allow_retransmission(true); packet->set_allow_retransmission(true);
@ -2465,10 +2475,10 @@ TEST_P(RtpSenderTest, SetsCaptureTimeAndPopulatesTransmissionOffset) {
fake_clock_.AdvanceTimeMilliseconds(kOffsetMs); fake_clock_.AdvanceTimeMilliseconds(kOffsetMs);
std::unique_ptr<RtpPacketToSend> rtx_packet_to_pace; std::unique_ptr<RtpPacketToSend> rtx_packet_to_pace;
EXPECT_CALL(mock_paced_sender_, EnqueuePacket) EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
.WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) { .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
EXPECT_GT(packet->capture_time_ms(), 0); EXPECT_GT(packets[0]->capture_time_ms(), 0);
rtx_packet_to_pace = std::move(packet); rtx_packet_to_pace = std::move(packets[0]);
}); });
EXPECT_GT(rtp_sender_->ReSendPacket(kSeqNum), 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. // Send a packet so it is in the packet history.
std::unique_ptr<RtpPacketToSend> packet_to_pace; std::unique_ptr<RtpPacketToSend> packet_to_pace;
EXPECT_CALL(mock_paced_sender_, EnqueuePacket) EXPECT_CALL(mock_paced_sender_, EnqueuePackets)
.WillOnce([&](std::unique_ptr<RtpPacketToSend> packet) { .WillOnce([&](std::vector<std::unique_ptr<RtpPacketToSend>> packets) {
packet_to_pace = std::move(packet); packet_to_pace = std::move(packets[0]);
}); });
SendGenericPacket(); SendGenericPacket();