Add RtpPacketHistory::SetSendTime()
This method will be used instead of GetPacketAndSetSendTime() when the new pacer code path is used, where the packet isn't stored in the history during pacing. Bug: webrtc:10633 Change-Id: Ie168125d949cef617ade3868a1858ed1dffe909c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/140892 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28240}
This commit is contained in:
@ -206,6 +206,7 @@ rtc_static_library("rtp_rtcp") {
|
||||
"..:module_fec_api",
|
||||
"../..:webrtc_common",
|
||||
"../../api:array_view",
|
||||
"../../api:function_view",
|
||||
"../../api:libjingle_peerconnection_api",
|
||||
"../../api:rtp_headers",
|
||||
"../../api:scoped_refptr",
|
||||
|
@ -205,6 +205,71 @@ std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndSetSendTime(
|
||||
return absl::make_unique<RtpPacketToSend>(*packet.packet_);
|
||||
}
|
||||
|
||||
std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndMarkAsPending(
|
||||
uint16_t sequence_number) {
|
||||
return GetPacketAndMarkAsPending(
|
||||
sequence_number, [](const RtpPacketToSend& packet) {
|
||||
return absl::make_unique<RtpPacketToSend>(packet);
|
||||
});
|
||||
}
|
||||
|
||||
std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndMarkAsPending(
|
||||
uint16_t sequence_number,
|
||||
rtc::FunctionView<std::unique_ptr<RtpPacketToSend>(const RtpPacketToSend&)>
|
||||
encapsulate) {
|
||||
rtc::CritScope cs(&lock_);
|
||||
if (mode_ == StorageMode::kDisabled) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
StoredPacketIterator rtp_it = packet_history_.find(sequence_number);
|
||||
if (rtp_it == packet_history_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StoredPacket& packet = rtp_it->second;
|
||||
RTC_DCHECK(packet.storage_type() != StorageType::kDontRetransmit);
|
||||
|
||||
if (packet.pending_transmission_) {
|
||||
// Packet already in pacer queue, ignore this request.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!VerifyRtt(rtp_it->second, now_ms)) {
|
||||
// Packet already resent within too short a time window, ignore.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
packet.pending_transmission_ = true;
|
||||
|
||||
// Copy and/or encapsulate packet.
|
||||
return encapsulate(*packet.packet_);
|
||||
}
|
||||
|
||||
void RtpPacketHistory::MarkPacketAsSent(uint16_t sequence_number) {
|
||||
rtc::CritScope cs(&lock_);
|
||||
if (mode_ == StorageMode::kDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
StoredPacketIterator rtp_it = packet_history_.find(sequence_number);
|
||||
if (rtp_it == packet_history_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StoredPacket& packet = rtp_it->second;
|
||||
RTC_CHECK(packet.storage_type() != StorageType::kDontRetransmit);
|
||||
RTC_DCHECK(packet.send_time_ms_);
|
||||
|
||||
// Update send-time, mark as no longer in pacer queue, and increment
|
||||
// transmission count.
|
||||
packet.send_time_ms_ = now_ms;
|
||||
packet.pending_transmission_ = false;
|
||||
packet.IncrementTimesRetransmitted(&padding_priority_);
|
||||
}
|
||||
|
||||
absl::optional<RtpPacketHistory::PacketState> RtpPacketHistory::GetPacketState(
|
||||
uint16_t sequence_number) const {
|
||||
rtc::CritScope cs(&lock_);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "api/function_view.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
#include "rtc_base/critical_section.h"
|
||||
@ -82,6 +83,25 @@ class RtpPacketHistory {
|
||||
std::unique_ptr<RtpPacketToSend> GetPacketAndSetSendTime(
|
||||
uint16_t sequence_number);
|
||||
|
||||
// Gets stored RTP packet corresponding to the input |sequence number|.
|
||||
// Returns nullptr if packet is not found or was (re)sent too recently.
|
||||
// If a packet copy is returned, it will be marked as pending transmission but
|
||||
// does not update send time, that must be done by MarkPacketAsSent().
|
||||
std::unique_ptr<RtpPacketToSend> GetPacketAndMarkAsPending(
|
||||
uint16_t sequence_number);
|
||||
|
||||
// In addition to getting packet and marking as sent, this method takes an
|
||||
// encapsulator function that takes a reference to the packet and outputs a
|
||||
// copy that may be wrapped in a container, eg RTX.
|
||||
std::unique_ptr<RtpPacketToSend> GetPacketAndMarkAsPending(
|
||||
uint16_t sequence_number,
|
||||
rtc::FunctionView<std::unique_ptr<RtpPacketToSend>(
|
||||
const RtpPacketToSend&)> encapsulate);
|
||||
|
||||
// Updates the send time for the given packet and increments the transmission
|
||||
// counter. Marks the packet as no longer being in the pacer queue.
|
||||
void MarkPacketAsSent(uint16_t sequence_number);
|
||||
|
||||
// Similar to GetPacketAndSetSendTime(), but only returns a snapshot of the
|
||||
// current state for packet, and never updates internal state.
|
||||
absl::optional<PacketState> GetPacketState(uint16_t sequence_number) const;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
@ -678,6 +679,61 @@ TEST_F(RtpPacketHistoryTest, SetsPendingTransmissionState) {
|
||||
EXPECT_FALSE(packet_state->pending_transmission);
|
||||
}
|
||||
|
||||
TEST_F(RtpPacketHistoryTest, GetPacketAndSetSent) {
|
||||
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
|
||||
hist_.SetRtt(kRttMs);
|
||||
|
||||
// Set size to remove old packets as soon as possible.
|
||||
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
|
||||
|
||||
// Add a sent packet to the history.
|
||||
hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), kAllowRetransmission,
|
||||
fake_clock_.TimeInMicroseconds());
|
||||
|
||||
// Retransmission request, first retransmission is allowed immediately.
|
||||
EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
|
||||
|
||||
// Packet not yet sent, new retransmission not allowed.
|
||||
fake_clock_.AdvanceTimeMilliseconds(kRttMs);
|
||||
EXPECT_FALSE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
|
||||
|
||||
// Mark as sent, but too early for retransmission.
|
||||
hist_.MarkPacketAsSent(kStartSeqNum);
|
||||
EXPECT_FALSE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
|
||||
|
||||
// Enough time has passed, retransmission is allowed again.
|
||||
fake_clock_.AdvanceTimeMilliseconds(kRttMs);
|
||||
EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
|
||||
}
|
||||
|
||||
TEST_F(RtpPacketHistoryTest, GetPacketWithEncapsulation) {
|
||||
const uint32_t kSsrc = 92384762;
|
||||
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
|
||||
hist_.SetRtt(kRttMs);
|
||||
|
||||
// Set size to remove old packets as soon as possible.
|
||||
hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
|
||||
|
||||
// Add a sent packet to the history, with a set SSRC.
|
||||
std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
|
||||
packet->SetSsrc(kSsrc);
|
||||
hist_.PutRtpPacket(std::move(packet), kAllowRetransmission,
|
||||
fake_clock_.TimeInMicroseconds());
|
||||
|
||||
// Retransmission request, simulate an RTX-like encapsulation, were the packet
|
||||
// is sent on a different SSRC.
|
||||
std::unique_ptr<RtpPacketToSend> retransmit_packet =
|
||||
hist_.GetPacketAndMarkAsPending(
|
||||
kStartSeqNum, [](const RtpPacketToSend& packet) {
|
||||
auto encapsulated_packet =
|
||||
absl::make_unique<RtpPacketToSend>(packet);
|
||||
encapsulated_packet->SetSsrc(packet.Ssrc() + 1);
|
||||
return encapsulated_packet;
|
||||
});
|
||||
ASSERT_TRUE(retransmit_packet);
|
||||
EXPECT_EQ(retransmit_packet->Ssrc(), kSsrc + 1);
|
||||
}
|
||||
|
||||
TEST_F(RtpPacketHistoryTest, DontRemovePendingTransmissions) {
|
||||
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
|
||||
const int64_t kPacketTimeoutMs =
|
||||
|
Reference in New Issue
Block a user