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:
Erik Språng
2019-06-11 18:59:39 +02:00
committed by Commit Bot
parent ef10a4ceb6
commit eceb537086
4 changed files with 142 additions and 0 deletions

View File

@ -206,6 +206,7 @@ rtc_static_library("rtp_rtcp") {
"..:module_fec_api", "..:module_fec_api",
"../..:webrtc_common", "../..:webrtc_common",
"../../api:array_view", "../../api:array_view",
"../../api:function_view",
"../../api:libjingle_peerconnection_api", "../../api:libjingle_peerconnection_api",
"../../api:rtp_headers", "../../api:rtp_headers",
"../../api:scoped_refptr", "../../api:scoped_refptr",

View File

@ -205,6 +205,71 @@ std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndSetSendTime(
return absl::make_unique<RtpPacketToSend>(*packet.packet_); 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( absl::optional<RtpPacketHistory::PacketState> RtpPacketHistory::GetPacketState(
uint16_t sequence_number) const { uint16_t sequence_number) const {
rtc::CritScope cs(&lock_); rtc::CritScope cs(&lock_);

View File

@ -16,6 +16,7 @@
#include <set> #include <set>
#include <vector> #include <vector>
#include "api/function_view.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/constructor_magic.h" #include "rtc_base/constructor_magic.h"
#include "rtc_base/critical_section.h" #include "rtc_base/critical_section.h"
@ -82,6 +83,25 @@ class RtpPacketHistory {
std::unique_ptr<RtpPacketToSend> GetPacketAndSetSendTime( std::unique_ptr<RtpPacketToSend> GetPacketAndSetSendTime(
uint16_t sequence_number); 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 // Similar to GetPacketAndSetSendTime(), but only returns a snapshot of the
// current state for packet, and never updates internal state. // current state for packet, and never updates internal state.
absl::optional<PacketState> GetPacketState(uint16_t sequence_number) const; absl::optional<PacketState> GetPacketState(uint16_t sequence_number) const;

View File

@ -13,6 +13,7 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "absl/memory/memory.h"
#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"
#include "system_wrappers/include/clock.h" #include "system_wrappers/include/clock.h"
@ -678,6 +679,61 @@ TEST_F(RtpPacketHistoryTest, SetsPendingTransmissionState) {
EXPECT_FALSE(packet_state->pending_transmission); 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) { TEST_F(RtpPacketHistoryTest, DontRemovePendingTransmissions) {
const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2; const int64_t kRttMs = RtpPacketHistory::kMinPacketDurationMs * 2;
const int64_t kPacketTimeoutMs = const int64_t kPacketTimeoutMs =