Add ability to disable padding prioritization.
This allows trading off some potential media quality for CPU usage.
Bug: webrtc:8975
Change-Id: I447a03f596e9e711ba5d7038fe71f27bd80bf795
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172085
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30936}
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index 579b2df..095688a 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -149,6 +149,13 @@
bool need_rtp_packet_infos = false;
+ // If true, the RTP packet history will select RTX packets based on
+ // heuristics such as send time, retransmission count etc, in order to
+ // make padding potentially more useful.
+ // If false, the last packet will always be picked. This may reduce CPU
+ // overhead.
+ bool enable_rtx_padding_prioritization = false;
+
private:
RTC_DISALLOW_COPY_AND_ASSIGN(Configuration);
};
diff --git a/modules/rtp_rtcp/source/rtp_packet_history.cc b/modules/rtp_rtcp/source/rtp_packet_history.cc
index 6a2253c..58e971f 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_history.cc
@@ -56,7 +56,7 @@
// Check if this StoredPacket is in the priority set. If so, we need to remove
// it before updating |times_retransmitted_| since that is used in sorting,
// and then add it back.
- const bool in_priority_set = priority_set->erase(this) > 0;
+ const bool in_priority_set = priority_set && priority_set->erase(this) > 0;
++times_retransmitted_;
if (in_priority_set) {
auto it = priority_set->insert(this);
@@ -80,8 +80,9 @@
return lhs->insert_order() > rhs->insert_order();
}
-RtpPacketHistory::RtpPacketHistory(Clock* clock)
+RtpPacketHistory::RtpPacketHistory(Clock* clock, bool enable_padding_prio)
: clock_(clock),
+ enable_padding_prio_(enable_padding_prio),
number_to_store_(0),
mode_(StorageMode::kDisabled),
rtt_ms_(-1),
@@ -158,11 +159,13 @@
packet_history_[packet_index] =
StoredPacket(std::move(packet), send_time_ms, packets_inserted_++);
- if (padding_priority_.size() >= kMaxPaddingtHistory - 1) {
- padding_priority_.erase(std::prev(padding_priority_.end()));
+ if (enable_padding_prio_) {
+ if (padding_priority_.size() >= kMaxPaddingtHistory - 1) {
+ padding_priority_.erase(std::prev(padding_priority_.end()));
+ }
+ auto prio_it = padding_priority_.insert(&packet_history_[packet_index]);
+ RTC_DCHECK(prio_it.second) << "Failed to insert packet into prio set.";
}
- auto prio_it = padding_priority_.insert(&packet_history_[packet_index]);
- RTC_DCHECK(prio_it.second) << "Failed to insert packet into prio set.";
}
std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndSetSendTime(
@@ -183,7 +186,8 @@
}
if (packet->send_time_ms_) {
- packet->IncrementTimesRetransmitted(&padding_priority_);
+ packet->IncrementTimesRetransmitted(
+ enable_padding_prio_ ? &padding_priority_ : nullptr);
}
// Update send-time and mark as no long in pacer queue.
@@ -253,7 +257,8 @@
// transmission count.
packet->send_time_ms_ = clock_->TimeInMilliseconds();
packet->pending_transmission_ = false;
- packet->IncrementTimesRetransmitted(&padding_priority_);
+ packet->IncrementTimesRetransmitted(enable_padding_prio_ ? &padding_priority_
+ : nullptr);
}
absl::optional<RtpPacketHistory::PacketState> RtpPacketHistory::GetPacketState(
@@ -307,12 +312,28 @@
rtc::FunctionView<std::unique_ptr<RtpPacketToSend>(const RtpPacketToSend&)>
encapsulate) {
rtc::CritScope cs(&lock_);
- if (mode_ == StorageMode::kDisabled || padding_priority_.empty()) {
+ if (mode_ == StorageMode::kDisabled) {
return nullptr;
}
- auto best_packet_it = padding_priority_.begin();
- StoredPacket* best_packet = *best_packet_it;
+ StoredPacket* best_packet = nullptr;
+ if (enable_padding_prio_ && !padding_priority_.empty()) {
+ auto best_packet_it = padding_priority_.begin();
+ best_packet = *best_packet_it;
+ } else if (!enable_padding_prio_ && !packet_history_.empty()) {
+ // Prioritization not available, pick the last packet.
+ for (auto it = packet_history_.rbegin(); it != packet_history_.rend();
+ ++it) {
+ if (it->packet_ != nullptr) {
+ best_packet = &(*it);
+ break;
+ }
+ }
+ }
+ if (best_packet == nullptr) {
+ return nullptr;
+ }
+
if (best_packet->pending_transmission_) {
// Because PacedSender releases it's lock when it calls
// GeneratePadding() there is the potential for a race where a new
@@ -328,7 +349,8 @@
}
best_packet->send_time_ms_ = clock_->TimeInMilliseconds();
- best_packet->IncrementTimesRetransmitted(&padding_priority_);
+ best_packet->IncrementTimesRetransmitted(
+ enable_padding_prio_ ? &padding_priority_ : nullptr);
return padding_packet;
}
@@ -414,7 +436,9 @@
std::move(packet_history_[packet_index].packet_);
// Erase from padding priority set, if eligible.
- padding_priority_.erase(&packet_history_[packet_index]);
+ if (enable_padding_prio_) {
+ padding_priority_.erase(&packet_history_[packet_index]);
+ }
if (packet_index == 0) {
while (!packet_history_.empty() &&
diff --git a/modules/rtp_rtcp/source/rtp_packet_history.h b/modules/rtp_rtcp/source/rtp_packet_history.h
index 9253ede..db25b17 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history.h
+++ b/modules/rtp_rtcp/source/rtp_packet_history.h
@@ -62,7 +62,7 @@
// With kStoreAndCull, always remove packets after 3x max(1000ms, 3x rtt).
static constexpr int kPacketCullingDelayFactor = 3;
- explicit RtpPacketHistory(Clock* clock);
+ RtpPacketHistory(Clock* clock, bool enable_padding_prio);
~RtpPacketHistory();
// Set/get storage mode. Note that setting the state will clear the history,
@@ -192,6 +192,7 @@
const StoredPacket& stored_packet);
Clock* const clock_;
+ const bool enable_padding_prio_;
rtc::CriticalSection lock_;
size_t number_to_store_ RTC_GUARDED_BY(lock_);
StorageMode mode_ RTC_GUARDED_BY(lock_);
diff --git a/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
index fdf64d5..2331724 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
@@ -32,9 +32,11 @@
using StorageMode = RtpPacketHistory::StorageMode;
-class RtpPacketHistoryTest : public ::testing::Test {
+class RtpPacketHistoryTest : public ::testing::TestWithParam<bool> {
protected:
- RtpPacketHistoryTest() : fake_clock_(123456), hist_(&fake_clock_) {}
+ RtpPacketHistoryTest()
+ : fake_clock_(123456),
+ hist_(&fake_clock_, /*enable_padding_prio=*/GetParam()) {}
SimulatedClock fake_clock_;
RtpPacketHistory hist_;
@@ -49,7 +51,7 @@
}
};
-TEST_F(RtpPacketHistoryTest, SetStoreStatus) {
+TEST_P(RtpPacketHistoryTest, SetStoreStatus) {
EXPECT_EQ(StorageMode::kDisabled, hist_.GetStorageMode());
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
EXPECT_EQ(StorageMode::kStoreAndCull, hist_.GetStorageMode());
@@ -59,7 +61,7 @@
EXPECT_EQ(StorageMode::kDisabled, hist_.GetStorageMode());
}
-TEST_F(RtpPacketHistoryTest, ClearsHistoryAfterSetStoreStatus) {
+TEST_P(RtpPacketHistoryTest, ClearsHistoryAfterSetStoreStatus) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
// Store a packet, but with send-time. It should then not be removed.
hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), absl::nullopt);
@@ -70,7 +72,7 @@
EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, StartSeqResetAfterReset) {
+TEST_P(RtpPacketHistoryTest, StartSeqResetAfterReset) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
// Store a packet, but with send-time. It should then not be removed.
hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), absl::nullopt);
@@ -96,7 +98,7 @@
EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
}
-TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
+TEST_P(RtpPacketHistoryTest, NoStoreStatus) {
EXPECT_EQ(StorageMode::kDisabled, hist_.GetStorageMode());
std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
hist_.PutRtpPacket(std::move(packet), absl::nullopt);
@@ -104,12 +106,12 @@
EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, GetRtpPacket_NotStored) {
+TEST_P(RtpPacketHistoryTest, GetRtpPacket_NotStored) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
EXPECT_FALSE(hist_.GetPacketState(0));
}
-TEST_F(RtpPacketHistoryTest, PutRtpPacket) {
+TEST_P(RtpPacketHistoryTest, PutRtpPacket) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
@@ -118,7 +120,7 @@
EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, GetRtpPacket) {
+TEST_P(RtpPacketHistoryTest, GetRtpPacket) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
int64_t capture_time_ms = 1;
std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
@@ -133,7 +135,7 @@
EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
}
-TEST_F(RtpPacketHistoryTest, PacketStateIsCorrect) {
+TEST_P(RtpPacketHistoryTest, PacketStateIsCorrect) {
const uint32_t kSsrc = 92384762;
const int64_t kRttMs = 100;
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
@@ -164,7 +166,7 @@
EXPECT_EQ(state->times_retransmitted, 1u);
}
-TEST_F(RtpPacketHistoryTest, MinResendTimeWithPacer) {
+TEST_P(RtpPacketHistoryTest, MinResendTimeWithPacer) {
static const int64_t kMinRetransmitIntervalMs = 100;
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
@@ -205,7 +207,7 @@
EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, MinResendTimeWithoutPacer) {
+TEST_P(RtpPacketHistoryTest, MinResendTimeWithoutPacer) {
static const int64_t kMinRetransmitIntervalMs = 100;
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
@@ -231,7 +233,7 @@
EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, RemovesOldestSentPacketWhenAtMaxSize) {
+TEST_P(RtpPacketHistoryTest, RemovesOldestSentPacketWhenAtMaxSize) {
const size_t kMaxNumPackets = 10;
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kMaxNumPackets);
@@ -262,7 +264,7 @@
EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
}
-TEST_F(RtpPacketHistoryTest, RemovesOldestPacketWhenAtMaxCapacity) {
+TEST_P(RtpPacketHistoryTest, RemovesOldestPacketWhenAtMaxCapacity) {
// Tests the absolute upper bound on number of stored packets. Don't allow
// storing more than this, even if packets have not yet been sent.
const size_t kMaxNumPackets = RtpPacketHistory::kMaxCapacity;
@@ -290,7 +292,12 @@
EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
}
-TEST_F(RtpPacketHistoryTest, RemovesLowestPrioPaddingWhenAtMaxCapacity) {
+TEST_P(RtpPacketHistoryTest, RemovesLowestPrioPaddingWhenAtMaxCapacity) {
+ if (!GetParam()) {
+ // Padding prioritization is off, ignore this test.
+ return;
+ }
+
// Tests the absolute upper bound on number of packets in the prioritized
// set of potential padding packets.
const size_t kMaxNumPackets = RtpPacketHistory::kMaxPaddingtHistory;
@@ -322,7 +329,7 @@
EXPECT_EQ(packet->SequenceNumber(), To16u(kStartSeqNum + kMaxNumPackets));
}
-TEST_F(RtpPacketHistoryTest, DontRemoveUnsentPackets) {
+TEST_P(RtpPacketHistoryTest, DontRemoveUnsentPackets) {
const size_t kMaxNumPackets = 10;
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kMaxNumPackets);
@@ -355,7 +362,7 @@
EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
}
-TEST_F(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPackets) {
+TEST_P(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPackets) {
// Set size to remove old packets as soon as possible.
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
@@ -380,7 +387,7 @@
EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
}
-TEST_F(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPacketsHighRtt) {
+TEST_P(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPacketsHighRtt) {
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
const int64_t kPacketTimeoutMs =
kRttMs * RtpPacketHistory::kMinPacketDurationRtt;
@@ -409,7 +416,7 @@
EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
}
-TEST_F(RtpPacketHistoryTest, RemovesOldWithCulling) {
+TEST_P(RtpPacketHistoryTest, RemovesOldWithCulling) {
const size_t kMaxNumPackets = 10;
// Enable culling. Even without feedback, this can trigger early removal.
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kMaxNumPackets);
@@ -432,7 +439,7 @@
EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, RemovesOldWithCullingHighRtt) {
+TEST_P(RtpPacketHistoryTest, RemovesOldWithCullingHighRtt) {
const size_t kMaxNumPackets = 10;
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
// Enable culling. Even without feedback, this can trigger early removal.
@@ -458,7 +465,7 @@
EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, CullWithAcks) {
+TEST_P(RtpPacketHistoryTest, CullWithAcks) {
const int64_t kPacketLifetime = RtpPacketHistory::kMinPacketDurationMs *
RtpPacketHistory::kPacketCullingDelayFactor;
@@ -511,7 +518,7 @@
EXPECT_FALSE(hist_.GetPacketState(To16u(kStartSeqNum + 2)).has_value());
}
-TEST_F(RtpPacketHistoryTest, SetsPendingTransmissionState) {
+TEST_P(RtpPacketHistoryTest, SetsPendingTransmissionState) {
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
hist_.SetRtt(kRttMs);
@@ -553,7 +560,7 @@
EXPECT_FALSE(packet_state->pending_transmission);
}
-TEST_F(RtpPacketHistoryTest, GetPacketAndSetSent) {
+TEST_P(RtpPacketHistoryTest, GetPacketAndSetSent) {
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
hist_.SetRtt(kRttMs);
@@ -580,7 +587,7 @@
EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, GetPacketWithEncapsulation) {
+TEST_P(RtpPacketHistoryTest, GetPacketWithEncapsulation) {
const uint32_t kSsrc = 92384762;
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
hist_.SetRtt(kRttMs);
@@ -607,7 +614,7 @@
EXPECT_EQ(retransmit_packet->Ssrc(), kSsrc + 1);
}
-TEST_F(RtpPacketHistoryTest, GetPacketWithEncapsulationAbortOnNullptr) {
+TEST_P(RtpPacketHistoryTest, GetPacketWithEncapsulationAbortOnNullptr) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum),
@@ -617,14 +624,14 @@
// not suitable for retransmission (bandwidth exhausted?) so the retransmit is
// aborted and the packet is not marked as pending.
EXPECT_FALSE(hist_.GetPacketAndMarkAsPending(
- kStartSeqNum, [](const RtpPacketToSend& packet) { return nullptr; }));
+ kStartSeqNum, [](const RtpPacketToSend&) { return nullptr; }));
// New try, this time getting the packet should work, and it should not be
// blocked due to any pending status.
EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
}
-TEST_F(RtpPacketHistoryTest, DontRemovePendingTransmissions) {
+TEST_P(RtpPacketHistoryTest, DontRemovePendingTransmissions) {
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
const int64_t kPacketTimeoutMs =
kRttMs * RtpPacketHistory::kMinPacketDurationRtt;
@@ -657,7 +664,12 @@
ASSERT_FALSE(packet_state.has_value());
}
-TEST_F(RtpPacketHistoryTest, PrioritizedPayloadPadding) {
+TEST_P(RtpPacketHistoryTest, PrioritizedPayloadPadding) {
+ if (!GetParam()) {
+ // Padding prioritization is off, ignore this test.
+ return;
+ }
+
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
// Add two sent packets, one millisecond apart.
@@ -694,7 +706,7 @@
EXPECT_EQ(hist_.GetPayloadPaddingPacket(), nullptr);
}
-TEST_F(RtpPacketHistoryTest, NoPendingPacketAsPadding) {
+TEST_P(RtpPacketHistoryTest, NoPendingPacketAsPadding) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum),
@@ -712,7 +724,7 @@
EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(), kStartSeqNum);
}
-TEST_F(RtpPacketHistoryTest, PayloadPaddingWithEncapsulation) {
+TEST_P(RtpPacketHistoryTest, PayloadPaddingWithEncapsulation) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum),
@@ -720,9 +732,8 @@
fake_clock_.AdvanceTimeMilliseconds(1);
// Aborted padding.
- EXPECT_EQ(nullptr,
- hist_.GetPayloadPaddingPacket(
- [](const RtpPacketToSend& packet) { return nullptr; }));
+ EXPECT_EQ(nullptr, hist_.GetPayloadPaddingPacket(
+ [](const RtpPacketToSend&) { return nullptr; }));
// Get copy of packet, but with sequence number modified.
auto padding_packet =
@@ -735,7 +746,7 @@
EXPECT_EQ(padding_packet->SequenceNumber(), kStartSeqNum + 1);
}
-TEST_F(RtpPacketHistoryTest, NackAfterAckIsNoop) {
+TEST_P(RtpPacketHistoryTest, NackAfterAckIsNoop) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 2);
// Add two sent packets.
hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum),
@@ -749,7 +760,7 @@
EXPECT_EQ(packet.get(), nullptr);
}
-TEST_F(RtpPacketHistoryTest, OutOfOrderInsertRemoval) {
+TEST_P(RtpPacketHistoryTest, OutOfOrderInsertRemoval) {
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
// Insert packets, out of order, including both forwards and backwards
@@ -780,4 +791,51 @@
expected_time_offset_ms += 33;
}
}
+
+TEST_P(RtpPacketHistoryTest, UsesLastPacketAsPaddingWithPrioOff) {
+ if (GetParam()) {
+ // Padding prioritization is enabled, ignore this test.
+ return;
+ }
+
+ const size_t kHistorySize = 10;
+ hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kHistorySize);
+
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket(), nullptr);
+
+ for (size_t i = 0; i < kHistorySize; ++i) {
+ hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + i)),
+ fake_clock_.TimeInMilliseconds());
+ hist_.MarkPacketAsSent(To16u(kStartSeqNum + i));
+ fake_clock_.AdvanceTimeMilliseconds(1);
+
+ // Last packet always returned.
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
+ To16u(kStartSeqNum + i));
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
+ To16u(kStartSeqNum + i));
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
+ To16u(kStartSeqNum + i));
+ }
+
+ // Remove packets from the end, last in the list should be returned.
+ for (size_t i = kHistorySize - 1; i > 0; --i) {
+ hist_.CullAcknowledgedPackets(
+ std::vector<uint16_t>{To16u(kStartSeqNum + i)});
+
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
+ To16u(kStartSeqNum + i - 1));
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
+ To16u(kStartSeqNum + i - 1));
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
+ To16u(kStartSeqNum + i - 1));
+ }
+
+ hist_.CullAcknowledgedPackets(std::vector<uint16_t>{kStartSeqNum});
+ EXPECT_EQ(hist_.GetPayloadPaddingPacket(), nullptr);
+}
+
+INSTANTIATE_TEST_SUITE_P(WithAndWithoutPaddingPrio,
+ RtpPacketHistoryTest,
+ ::testing::Bool());
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 204bd8b..25fa545 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -40,7 +40,7 @@
ModuleRtpRtcpImpl::RtpSenderContext::RtpSenderContext(
const RtpRtcp::Configuration& config)
- : packet_history(config.clock),
+ : packet_history(config.clock, config.enable_rtx_padding_prioritization),
packet_sender(config, &packet_history),
non_paced_sender(&packet_sender),
packet_generator(
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index d4a7fa9..355312c 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -223,7 +223,7 @@
// wherever possible.
struct RtpSenderContext {
explicit RtpSenderContext(const RtpRtcp::Configuration& config)
- : packet_history_(config.clock),
+ : packet_history_(config.clock, config.enable_rtx_padding_prioritization),
packet_sender_(config, &packet_history_),
non_paced_sender_(&packet_sender_),
packet_generator_(