Move ownership of PacketSequencer from RTPSender to RtpRtcp module.
This prepares for deferred sequence numbering, and is (sort of) extracted from https://webrtc-review.googlesource.com/c/src/+/208584 Bug: webrtc:11340, webrtc:12470 Change-Id: I2f3695309e1591b9f7a1ee98556f4f0758de7f69 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/227352 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34643}
This commit is contained in:
parent
06bb4649dc
commit
bfcfe034f4
@ -11,6 +11,7 @@
|
||||
#include "modules/rtp_rtcp/source/packet_sequencer.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/random.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -36,7 +37,15 @@ PacketSequencer::PacketSequencer(uint32_t media_ssrc,
|
||||
last_rtp_timestamp_(0),
|
||||
last_capture_time_ms_(0),
|
||||
last_timestamp_time_ms_(0),
|
||||
last_packet_marker_bit_(false) {}
|
||||
last_packet_marker_bit_(false) {
|
||||
Random random(clock_->TimeInMicroseconds());
|
||||
// TODO(bugs.webrtc.org/11340): Check if we can allow the full range of
|
||||
// [0, 2^16[ to be used instead.
|
||||
// Random start, 16 bits. Can't be 0.
|
||||
constexpr uint16_t kMaxInitRtpSeqNumber = 0x7fff; // 2^15 - 1.
|
||||
media_sequence_number_ = random.Rand(1, kMaxInitRtpSeqNumber);
|
||||
rtx_sequence_number_ = random.Rand(1, kMaxInitRtpSeqNumber);
|
||||
}
|
||||
|
||||
void PacketSequencer::Sequence(RtpPacketToSend& packet) {
|
||||
if (packet.Ssrc() == media_ssrc_) {
|
||||
|
||||
@ -44,12 +44,17 @@ const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
|
||||
ModuleRtpRtcpImpl::RtpSenderContext::RtpSenderContext(
|
||||
const RtpRtcpInterface::Configuration& config)
|
||||
: packet_history(config.clock, config.enable_rtx_padding_prioritization),
|
||||
sequencer_(config.local_media_ssrc,
|
||||
config.rtx_send_ssrc,
|
||||
/*require_marker_before_media_padding=*/!config.audio,
|
||||
config.clock),
|
||||
packet_sender(config, &packet_history),
|
||||
non_paced_sender(&packet_sender),
|
||||
packet_generator(
|
||||
config,
|
||||
&packet_history,
|
||||
config.paced_sender ? config.paced_sender : &non_paced_sender) {}
|
||||
config.paced_sender ? config.paced_sender : &non_paced_sender,
|
||||
&sequencer_) {}
|
||||
|
||||
std::unique_ptr<RtpRtcp> RtpRtcp::DEPRECATED_Create(
|
||||
const Configuration& configuration) {
|
||||
@ -440,7 +445,8 @@ std::vector<std::unique_ptr<RtpPacketToSend>>
|
||||
ModuleRtpRtcpImpl::GeneratePadding(size_t target_size_bytes) {
|
||||
RTC_DCHECK(rtp_sender_);
|
||||
return rtp_sender_->packet_generator.GeneratePadding(
|
||||
target_size_bytes, rtp_sender_->packet_sender.MediaHasBeenSent());
|
||||
target_size_bytes, rtp_sender_->packet_sender.MediaHasBeenSent(),
|
||||
rtp_sender_->sequencer_.CanSendPaddingOnMediaSsrc());
|
||||
}
|
||||
|
||||
std::vector<RtpSequenceNumberMap::Info>
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" // RTCPPacketType
|
||||
#include "modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h"
|
||||
#include "modules/rtp_rtcp/source/packet_sequencer.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_receiver.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_sender.h"
|
||||
@ -273,6 +274,8 @@ class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp {
|
||||
explicit RtpSenderContext(const RtpRtcpInterface::Configuration& config);
|
||||
// Storage of packets, for retransmissions and padding, if applicable.
|
||||
RtpPacketHistory packet_history;
|
||||
// Handles sequence number assignment and padding timestamp generation.
|
||||
PacketSequencer sequencer_;
|
||||
// Handles final time timestamping/stats/etc and handover to Transport.
|
||||
DEPRECATED_RtpSenderEgress packet_sender;
|
||||
// If no paced sender configured, this class will be used to pass packets
|
||||
|
||||
@ -63,12 +63,17 @@ int DelayMillisForDuration(TimeDelta duration) {
|
||||
ModuleRtpRtcpImpl2::RtpSenderContext::RtpSenderContext(
|
||||
const RtpRtcpInterface::Configuration& config)
|
||||
: packet_history(config.clock, config.enable_rtx_padding_prioritization),
|
||||
sequencer_(config.local_media_ssrc,
|
||||
config.rtx_send_ssrc,
|
||||
/*require_marker_before_media_padding=*/!config.audio,
|
||||
config.clock),
|
||||
packet_sender(config, &packet_history),
|
||||
non_paced_sender(&packet_sender, this),
|
||||
packet_generator(
|
||||
config,
|
||||
&packet_history,
|
||||
config.paced_sender ? config.paced_sender : &non_paced_sender) {}
|
||||
config.paced_sender ? config.paced_sender : &non_paced_sender,
|
||||
&sequencer_) {}
|
||||
void ModuleRtpRtcpImpl2::RtpSenderContext::AssignSequenceNumber(
|
||||
RtpPacketToSend* packet) {
|
||||
packet_generator.AssignSequenceNumber(packet);
|
||||
@ -394,7 +399,8 @@ std::vector<std::unique_ptr<RtpPacketToSend>>
|
||||
ModuleRtpRtcpImpl2::GeneratePadding(size_t target_size_bytes) {
|
||||
RTC_DCHECK(rtp_sender_);
|
||||
return rtp_sender_->packet_generator.GeneratePadding(
|
||||
target_size_bytes, rtp_sender_->packet_sender.MediaHasBeenSent());
|
||||
target_size_bytes, rtp_sender_->packet_sender.MediaHasBeenSent(),
|
||||
rtp_sender_->sequencer_.CanSendPaddingOnMediaSsrc());
|
||||
}
|
||||
|
||||
std::vector<RtpSequenceNumberMap::Info>
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "modules/include/module_fec_types.h"
|
||||
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" // RTCPPacketType
|
||||
#include "modules/rtp_rtcp/source/packet_sequencer.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_receiver.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_sender.h"
|
||||
@ -265,6 +266,8 @@ class ModuleRtpRtcpImpl2 final : public RtpRtcpInterface,
|
||||
void AssignSequenceNumber(RtpPacketToSend* packet) override;
|
||||
// Storage of packets, for retransmissions and padding, if applicable.
|
||||
RtpPacketHistory packet_history;
|
||||
// Handles sequence number assignment and padding timestamp generation.
|
||||
PacketSequencer sequencer_;
|
||||
// Handles final time timestamping/stats/etc and handover to Transport.
|
||||
RtpSenderEgress packet_sender;
|
||||
// If no paced sender configured, this class will be used to pass packets
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/rtc_event_log/rtc_event_log.h"
|
||||
@ -41,7 +42,6 @@ namespace {
|
||||
constexpr size_t kMaxPaddingLength = 224;
|
||||
constexpr size_t kMinAudioPaddingLength = 50;
|
||||
constexpr size_t kRtpHeaderLength = 12;
|
||||
constexpr uint16_t kMaxInitRtpSeqNumber = 32767; // 2^15 -1.
|
||||
|
||||
// Min size needed to get payload padding from packet history.
|
||||
constexpr int kMinPayloadPaddingBytes = 50;
|
||||
@ -158,7 +158,8 @@ double GetMaxPaddingSizeFactor(const WebRtcKeyValueConfig* field_trials) {
|
||||
|
||||
RTPSender::RTPSender(const RtpRtcpInterface::Configuration& config,
|
||||
RtpPacketHistory* packet_history,
|
||||
RtpPacketSender* packet_sender)
|
||||
RtpPacketSender* packet_sender,
|
||||
PacketSequencer* packet_sequencer)
|
||||
: clock_(config.clock),
|
||||
random_(clock_->TimeInMicroseconds()),
|
||||
audio_configured_(config.audio),
|
||||
@ -173,10 +174,7 @@ RTPSender::RTPSender(const RtpRtcpInterface::Configuration& config,
|
||||
max_packet_size_(IP_PACKET_SIZE - 28), // Default is IP-v4/UDP.
|
||||
rtp_header_extension_map_(config.extmap_allow_mixed),
|
||||
// RTP variables
|
||||
sequencer_(config.local_media_ssrc,
|
||||
rtx_ssrc_,
|
||||
/*require_marker_before_media_padding_=*/!config.audio,
|
||||
config.clock),
|
||||
sequencer_(packet_sequencer),
|
||||
always_send_mid_and_rid_(config.always_send_mid_and_rid),
|
||||
ssrc_has_acked_(false),
|
||||
rtx_ssrc_has_acked_(false),
|
||||
@ -187,14 +185,25 @@ RTPSender::RTPSender(const RtpRtcpInterface::Configuration& config,
|
||||
UpdateHeaderSizes();
|
||||
// This random initialization is not intended to be cryptographic strong.
|
||||
timestamp_offset_ = random_.Rand<uint32_t>();
|
||||
// Random start, 16 bits. Can't be 0.
|
||||
sequencer_.set_rtx_sequence_number(random_.Rand(1, kMaxInitRtpSeqNumber));
|
||||
sequencer_.set_media_sequence_number(random_.Rand(1, kMaxInitRtpSeqNumber));
|
||||
|
||||
RTC_DCHECK(paced_sender_);
|
||||
RTC_DCHECK(packet_history_);
|
||||
}
|
||||
|
||||
RTPSender::RTPSender(const RtpRtcpInterface::Configuration& config,
|
||||
RtpPacketHistory* packet_history,
|
||||
RtpPacketSender* packet_sender)
|
||||
: RTPSender(config,
|
||||
packet_history,
|
||||
packet_sender,
|
||||
new PacketSequencer(
|
||||
config.local_media_ssrc,
|
||||
config.rtx_send_ssrc,
|
||||
/*require_marker_before_media_padding_=*/!config.audio,
|
||||
config.clock)) {
|
||||
owned_sequencer_ = absl::WrapUnique(sequencer_);
|
||||
}
|
||||
|
||||
RTPSender::~RTPSender() {
|
||||
// TODO(tommi): Use a thread checker to ensure the object is created and
|
||||
// deleted on the same thread. At the moment this isn't possible due to
|
||||
@ -384,7 +393,8 @@ bool RTPSender::SupportsRtxPayloadPadding() const {
|
||||
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> RTPSender::GeneratePadding(
|
||||
size_t target_size_bytes,
|
||||
bool media_has_been_sent) {
|
||||
bool media_has_been_sent,
|
||||
bool can_send_padding_on_media_ssrc) {
|
||||
// This method does not actually send packets, it just generates
|
||||
// them and puts them in the pacer queue. Since this should incur
|
||||
// low overhead, keep the lock for the scope of the method in order
|
||||
@ -446,11 +456,16 @@ std::vector<std::unique_ptr<RtpPacketToSend>> RTPSender::GeneratePadding(
|
||||
padding_packet->set_packet_type(RtpPacketMediaType::kPadding);
|
||||
padding_packet->SetMarker(false);
|
||||
if (rtx_ == kRtxOff) {
|
||||
if (!sequencer_.CanSendPaddingOnMediaSsrc()) {
|
||||
bool can_send_padding = sequencer_
|
||||
? sequencer_->CanSendPaddingOnMediaSsrc()
|
||||
: can_send_padding_on_media_ssrc;
|
||||
if (!can_send_padding) {
|
||||
break;
|
||||
}
|
||||
padding_packet->SetSsrc(ssrc_);
|
||||
sequencer_.Sequence(*padding_packet);
|
||||
if (sequencer_) {
|
||||
sequencer_->Sequence(*padding_packet);
|
||||
}
|
||||
} else {
|
||||
// Without abs-send-time or transport sequence number a media packet
|
||||
// must be sent before padding so that the timestamps used for
|
||||
@ -465,7 +480,9 @@ std::vector<std::unique_ptr<RtpPacketToSend>> RTPSender::GeneratePadding(
|
||||
RTC_DCHECK(rtx_ssrc_);
|
||||
padding_packet->SetSsrc(*rtx_ssrc_);
|
||||
padding_packet->SetPayloadType(rtx_payload_type_map_.begin()->second);
|
||||
sequencer_.Sequence(*padding_packet);
|
||||
if (sequencer_) {
|
||||
sequencer_->Sequence(*padding_packet);
|
||||
}
|
||||
}
|
||||
|
||||
if (rtp_header_extension_map_.IsRegistered(TransportSequenceNumber::kId)) {
|
||||
@ -574,9 +591,10 @@ std::unique_ptr<RtpPacketToSend> RTPSender::AllocatePacket() const {
|
||||
|
||||
bool RTPSender::AssignSequenceNumber(RtpPacketToSend* packet) {
|
||||
MutexLock lock(&send_mutex_);
|
||||
RTC_DCHECK(sequencer_);
|
||||
if (!sending_media_)
|
||||
return false;
|
||||
sequencer_.Sequence(*packet);
|
||||
sequencer_->Sequence(*packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -584,10 +602,11 @@ bool RTPSender::AssignSequenceNumbersAndStoreLastPacketState(
|
||||
rtc::ArrayView<std::unique_ptr<RtpPacketToSend>> packets) {
|
||||
RTC_DCHECK(!packets.empty());
|
||||
MutexLock lock(&send_mutex_);
|
||||
RTC_DCHECK(sequencer_);
|
||||
if (!sending_media_)
|
||||
return false;
|
||||
for (auto& packet : packets) {
|
||||
sequencer_.Sequence(*packet);
|
||||
sequencer_->Sequence(*packet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -643,10 +662,11 @@ void RTPSender::SetSequenceNumber(uint16_t seq) {
|
||||
bool updated_sequence_number = false;
|
||||
{
|
||||
MutexLock lock(&send_mutex_);
|
||||
if (sequencer_.media_sequence_number() != seq) {
|
||||
RTC_DCHECK(sequencer_);
|
||||
if (sequencer_->media_sequence_number() != seq) {
|
||||
updated_sequence_number = true;
|
||||
}
|
||||
sequencer_.set_media_sequence_number(seq);
|
||||
sequencer_->set_media_sequence_number(seq);
|
||||
}
|
||||
|
||||
if (updated_sequence_number) {
|
||||
@ -658,7 +678,8 @@ void RTPSender::SetSequenceNumber(uint16_t seq) {
|
||||
|
||||
uint16_t RTPSender::SequenceNumber() const {
|
||||
MutexLock lock(&send_mutex_);
|
||||
return sequencer_.media_sequence_number();
|
||||
RTC_DCHECK(sequencer_);
|
||||
return sequencer_->media_sequence_number();
|
||||
}
|
||||
|
||||
static void CopyHeaderAndExtensionsToRtxPacket(const RtpPacketToSend& packet,
|
||||
@ -735,7 +756,9 @@ std::unique_ptr<RtpPacketToSend> RTPSender::BuildRtxPacket(
|
||||
rtx_packet->SetSsrc(*rtx_ssrc_);
|
||||
|
||||
// Replace sequence number.
|
||||
sequencer_.Sequence(*rtx_packet);
|
||||
if (sequencer_) {
|
||||
sequencer_->Sequence(*rtx_packet);
|
||||
}
|
||||
|
||||
CopyHeaderAndExtensionsToRtxPacket(packet, rtx_packet.get());
|
||||
|
||||
@ -784,7 +807,9 @@ void RTPSender::SetRtpState(const RtpState& rtp_state) {
|
||||
MutexLock lock(&send_mutex_);
|
||||
|
||||
timestamp_offset_ = rtp_state.start_timestamp;
|
||||
sequencer_.SetRtpState(rtp_state);
|
||||
if (sequencer_) {
|
||||
sequencer_->SetRtpState(rtp_state);
|
||||
}
|
||||
ssrc_has_acked_ = rtp_state.ssrc_has_acked;
|
||||
UpdateHeaderSizes();
|
||||
}
|
||||
@ -795,13 +820,17 @@ RtpState RTPSender::GetRtpState() const {
|
||||
RtpState state;
|
||||
state.start_timestamp = timestamp_offset_;
|
||||
state.ssrc_has_acked = ssrc_has_acked_;
|
||||
sequencer_.PupulateRtpState(state);
|
||||
if (sequencer_) {
|
||||
sequencer_->PupulateRtpState(state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
void RTPSender::SetRtxRtpState(const RtpState& rtp_state) {
|
||||
MutexLock lock(&send_mutex_);
|
||||
sequencer_.set_rtx_sequence_number(rtp_state.sequence_number);
|
||||
if (sequencer_) {
|
||||
sequencer_->set_rtx_sequence_number(rtp_state.sequence_number);
|
||||
}
|
||||
rtx_ssrc_has_acked_ = rtp_state.ssrc_has_acked;
|
||||
}
|
||||
|
||||
@ -809,7 +838,9 @@ RtpState RTPSender::GetRtxRtpState() const {
|
||||
MutexLock lock(&send_mutex_);
|
||||
|
||||
RtpState state;
|
||||
state.sequence_number = sequencer_.rtx_sequence_number();
|
||||
if (sequencer_) {
|
||||
state.sequence_number = sequencer_->rtx_sequence_number();
|
||||
}
|
||||
state.start_timestamp = timestamp_offset_;
|
||||
state.ssrc_has_acked = rtx_ssrc_has_acked_;
|
||||
|
||||
|
||||
@ -46,7 +46,14 @@ class RTPSender {
|
||||
public:
|
||||
RTPSender(const RtpRtcpInterface::Configuration& config,
|
||||
RtpPacketHistory* packet_history,
|
||||
RtpPacketSender* packet_sender);
|
||||
RtpPacketSender* packet_sender,
|
||||
PacketSequencer* packet_sequencer);
|
||||
|
||||
// TODO(bugs.webrtc.org/11340): Remove when downstream usage is gone.
|
||||
RTPSender(const RtpRtcpInterface::Configuration& config,
|
||||
RtpPacketHistory* packet_history,
|
||||
RtpPacketSender* packet_sender)
|
||||
ABSL_DEPRECATED("bugs.webrtc.org/11340");
|
||||
|
||||
RTPSender() = delete;
|
||||
RTPSender(const RTPSender&) = delete;
|
||||
@ -92,7 +99,11 @@ class RTPSender {
|
||||
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
||||
size_t target_size_bytes,
|
||||
bool media_has_been_sent) RTC_LOCKS_EXCLUDED(send_mutex_);
|
||||
bool media_has_been_sent,
|
||||
// TODO(bugs.webrtc.org/11340): Remove default value when downstream usage
|
||||
// is fixed.
|
||||
bool can_send_padding_on_media_ssrc = false)
|
||||
RTC_LOCKS_EXCLUDED(send_mutex_);
|
||||
|
||||
// NACK.
|
||||
void OnReceivedNack(const std::vector<uint16_t>& nack_sequence_numbers,
|
||||
@ -209,7 +220,9 @@ class RTPSender {
|
||||
|
||||
// RTP variables
|
||||
uint32_t timestamp_offset_ RTC_GUARDED_BY(send_mutex_);
|
||||
PacketSequencer sequencer_ RTC_GUARDED_BY(send_mutex_);
|
||||
// TODO(bugs.webrtc.org/11340): Remove when downstream usage is gone.
|
||||
std::unique_ptr<PacketSequencer> owned_sequencer_ RTC_GUARDED_BY(send_mutex_);
|
||||
PacketSequencer* const sequencer_ RTC_GUARDED_BY(send_mutex_);
|
||||
// RID value to send in the RID or RepairedRID header extension.
|
||||
std::string rid_ RTC_GUARDED_BY(send_mutex_);
|
||||
// MID value to send in the MID header extension.
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_packet_sender.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/packet_sequencer.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
|
||||
@ -137,8 +138,8 @@ class RtpSenderTest : public ::testing::Test {
|
||||
std::vector<RtpExtensionSize>(),
|
||||
nullptr,
|
||||
clock_),
|
||||
kMarkerBit(true) {
|
||||
}
|
||||
deferred_sequencing_(false),
|
||||
kMarkerBit(true) {}
|
||||
|
||||
void SetUp() override { SetUpRtpSender(true, false, nullptr); }
|
||||
|
||||
@ -167,10 +168,29 @@ class RtpSenderTest : public ::testing::Test {
|
||||
void CreateSender(const RtpRtcpInterface::Configuration& config) {
|
||||
packet_history_ = std::make_unique<RtpPacketHistory>(
|
||||
config.clock, config.enable_rtx_padding_prioritization);
|
||||
rtp_sender_ = std::make_unique<RTPSender>(config, packet_history_.get(),
|
||||
config.paced_sender);
|
||||
sequencer_.emplace(kSsrc, kRtxSsrc,
|
||||
/*require_marker_before_media_padding=*/!config.audio,
|
||||
clock_);
|
||||
rtp_sender_ =
|
||||
std::make_unique<RTPSender>(config, packet_history_.get(),
|
||||
config.paced_sender, &sequencer_.value());
|
||||
rtp_sender_->SetSequenceNumber(kSeqNum);
|
||||
rtp_sender_->SetTimestampOffset(0);
|
||||
deferred_sequencing_ = false;
|
||||
}
|
||||
|
||||
void CreateSenderWithDeferredSequencing(
|
||||
const RtpRtcpInterface::Configuration& config) {
|
||||
packet_history_ = std::make_unique<RtpPacketHistory>(
|
||||
config.clock, config.enable_rtx_padding_prioritization);
|
||||
sequencer_.emplace(kSsrc, kRtxSsrc,
|
||||
/*require_marker_before_media_padding=*/!config.audio,
|
||||
clock_);
|
||||
rtp_sender_ = std::make_unique<RTPSender>(config, packet_history_.get(),
|
||||
config.paced_sender, nullptr);
|
||||
sequencer_->set_media_sequence_number(kSeqNum);
|
||||
rtp_sender_->SetTimestampOffset(0);
|
||||
deferred_sequencing_ = true;
|
||||
}
|
||||
|
||||
GlobalSimulatedTimeController time_controller_;
|
||||
@ -180,6 +200,8 @@ class RtpSenderTest : public ::testing::Test {
|
||||
RateLimiter retransmission_rate_limiter_;
|
||||
FlexfecSender flexfec_sender_;
|
||||
|
||||
bool deferred_sequencing_;
|
||||
absl::optional<PacketSequencer> sequencer_;
|
||||
std::unique_ptr<RtpPacketHistory> packet_history_;
|
||||
std::unique_ptr<RTPSender> rtp_sender_;
|
||||
|
||||
@ -196,7 +218,9 @@ class RtpSenderTest : public ::testing::Test {
|
||||
packet->SetMarker(marker_bit);
|
||||
packet->SetTimestamp(timestamp);
|
||||
packet->set_capture_time_ms(capture_time_ms);
|
||||
EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
||||
if (!deferred_sequencing_) {
|
||||
EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
@ -224,9 +248,16 @@ class RtpSenderTest : public ::testing::Test {
|
||||
rtp_sender_->ExpectedPerPacketOverhead());
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
||||
size_t target_size_bytes) {
|
||||
return rtp_sender_->GeneratePadding(
|
||||
target_size_bytes, /*media_has_been_sent=*/true,
|
||||
sequencer_->CanSendPaddingOnMediaSsrc());
|
||||
}
|
||||
|
||||
size_t GenerateAndSendPadding(size_t target_size_bytes) {
|
||||
size_t generated_bytes = 0;
|
||||
for (auto& packet : rtp_sender_->GeneratePadding(target_size_bytes, true)) {
|
||||
for (auto& packet : GeneratePadding(target_size_bytes)) {
|
||||
generated_bytes += packet->payload_size() + packet->padding_size();
|
||||
rtp_sender_->SendToNetwork(std::move(packet));
|
||||
}
|
||||
@ -395,7 +426,8 @@ TEST_F(RtpSenderTest, SendPadding) {
|
||||
media_packet->Timestamp()))))));
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
|
||||
rtp_sender_->GeneratePadding(kPaddingTargetBytes,
|
||||
/*media_has_been_sent=*/true);
|
||||
/*media_has_been_sent=*/true,
|
||||
/*can_send_padding_on_media_ssrc=*/true);
|
||||
ASSERT_THAT(padding_packets, SizeIs(1));
|
||||
rtp_sender_->SendToNetwork(std::move(padding_packets[0]));
|
||||
}
|
||||
@ -415,14 +447,18 @@ TEST_F(RtpSenderTest, SendPadding) {
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderTest, NoPaddingAsFirstPacketWithoutBweExtensions) {
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false),
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false,
|
||||
/*can_send_padding_on_media_ssrc=*/false),
|
||||
IsEmpty());
|
||||
|
||||
// Don't send padding before media even with RTX.
|
||||
EnableRtx();
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false),
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false,
|
||||
/*can_send_padding_on_media_ssrc=*/false),
|
||||
IsEmpty());
|
||||
}
|
||||
|
||||
@ -432,14 +468,18 @@ TEST_F(RtpSenderTest, AllowPaddingAsFirstPacketOnRtxWithTransportCc) {
|
||||
|
||||
// Padding can't be sent as first packet on media SSRC since we don't know
|
||||
// what payload type to assign.
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false),
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false,
|
||||
/*can_send_padding_on_media_ssrc=*/false),
|
||||
IsEmpty());
|
||||
|
||||
// With transportcc padding can be sent as first packet on the RTX SSRC.
|
||||
EnableRtx();
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false),
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false,
|
||||
/*can_send_padding_on_media_ssrc=*/false),
|
||||
Not(IsEmpty()));
|
||||
}
|
||||
|
||||
@ -449,14 +489,18 @@ TEST_F(RtpSenderTest, AllowPaddingAsFirstPacketOnRtxWithAbsSendTime) {
|
||||
|
||||
// Padding can't be sent as first packet on media SSRC since we don't know
|
||||
// what payload type to assign.
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false),
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false,
|
||||
/*can_send_padding_on_media_ssrc=*/false),
|
||||
IsEmpty());
|
||||
|
||||
// With abs send time, padding can be sent as first packet on the RTX SSRC.
|
||||
EnableRtx();
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false),
|
||||
EXPECT_THAT(rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/false,
|
||||
/*can_send_padding_on_media_ssrc=*/false),
|
||||
Not(IsEmpty()));
|
||||
}
|
||||
|
||||
@ -482,8 +526,7 @@ TEST_F(RtpSenderTest, UpdatesTimestampsOnPlainRtxPadding) {
|
||||
|
||||
// Timestamps on padding should be offset from the sent media.
|
||||
EXPECT_THAT(
|
||||
rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/true),
|
||||
GeneratePadding(/*target_size_bytes=*/100),
|
||||
Each(AllOf(
|
||||
Pointee(Property(&RtpPacketToSend::padding_size, kMaxPaddingLength)),
|
||||
Pointee(Property(
|
||||
@ -520,8 +563,7 @@ TEST_F(RtpSenderTest, KeepsTimestampsOnPayloadPadding) {
|
||||
|
||||
// Timestamps on payload padding should be set to original.
|
||||
EXPECT_THAT(
|
||||
rtp_sender_->GeneratePadding(/*target_size_bytes=*/100,
|
||||
/*media_has_been_sent=*/true),
|
||||
GeneratePadding(/*target_size_bytes=*/100),
|
||||
Each(AllOf(
|
||||
Pointee(Property(&RtpPacketToSend::padding_size, 0u)),
|
||||
Pointee(Property(&RtpPacketToSend::payload_size,
|
||||
@ -1004,7 +1046,7 @@ TEST_F(RtpSenderTest, GeneratedPaddingHasBweExtensions) {
|
||||
|
||||
// Generate a plain padding packet, check that extensions are registered.
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> generated_packets =
|
||||
rtp_sender_->GeneratePadding(/*target_size_bytes=*/1, true);
|
||||
GeneratePadding(/*target_size_bytes=*/1);
|
||||
ASSERT_THAT(generated_packets, SizeIs(1));
|
||||
auto& plain_padding = generated_packets.front();
|
||||
EXPECT_GT(plain_padding->padding_size(), 0u);
|
||||
@ -1014,7 +1056,7 @@ TEST_F(RtpSenderTest, GeneratedPaddingHasBweExtensions) {
|
||||
EXPECT_GT(plain_padding->padding_size(), 0u);
|
||||
|
||||
// Generate a payload padding packets, check that extensions are registered.
|
||||
generated_packets = rtp_sender_->GeneratePadding(kMinPaddingSize, true);
|
||||
generated_packets = GeneratePadding(kMinPaddingSize);
|
||||
ASSERT_EQ(generated_packets.size(), 1u);
|
||||
auto& payload_padding = generated_packets.front();
|
||||
EXPECT_EQ(payload_padding->padding_size(), 0u);
|
||||
@ -1048,7 +1090,7 @@ TEST_F(RtpSenderTest, GeneratePaddingResendsOldPacketsWithRtx) {
|
||||
// Generated padding has large enough budget that the video packet should be
|
||||
// retransmitted as padding.
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> generated_packets =
|
||||
rtp_sender_->GeneratePadding(kMinPaddingSize, true);
|
||||
GeneratePadding(kMinPaddingSize);
|
||||
ASSERT_EQ(generated_packets.size(), 1u);
|
||||
auto& padding_packet = generated_packets.front();
|
||||
EXPECT_EQ(padding_packet->packet_type(), RtpPacketMediaType::kPadding);
|
||||
@ -1060,8 +1102,7 @@ TEST_F(RtpSenderTest, GeneratePaddingResendsOldPacketsWithRtx) {
|
||||
const size_t kPaddingBytesRequested = kMinPaddingSize - 1;
|
||||
|
||||
size_t padding_bytes_generated = 0;
|
||||
generated_packets =
|
||||
rtp_sender_->GeneratePadding(kPaddingBytesRequested, true);
|
||||
generated_packets = GeneratePadding(kPaddingBytesRequested);
|
||||
EXPECT_EQ(generated_packets.size(), 1u);
|
||||
for (auto& packet : generated_packets) {
|
||||
EXPECT_EQ(packet->packet_type(), RtpPacketMediaType::kPadding);
|
||||
@ -1105,14 +1146,14 @@ TEST_F(RtpSenderTest, LimitsPayloadPaddingSize) {
|
||||
// Generated padding has large enough budget that the video packet should be
|
||||
// retransmitted as padding.
|
||||
EXPECT_THAT(
|
||||
rtp_sender_->GeneratePadding(kMinTargerSizeForPayload, true),
|
||||
GeneratePadding(kMinTargerSizeForPayload),
|
||||
AllOf(Not(IsEmpty()),
|
||||
Each(Pointee(Property(&RtpPacketToSend::padding_size, Eq(0u))))));
|
||||
|
||||
// If payload padding is > 2x requested size, plain padding is returned
|
||||
// instead.
|
||||
EXPECT_THAT(
|
||||
rtp_sender_->GeneratePadding(kMinTargerSizeForPayload - 1, true),
|
||||
GeneratePadding(kMinTargerSizeForPayload - 1),
|
||||
AllOf(Not(IsEmpty()),
|
||||
Each(Pointee(Property(&RtpPacketToSend::padding_size, Gt(0u))))));
|
||||
}
|
||||
@ -1148,7 +1189,7 @@ TEST_F(RtpSenderTest, GeneratePaddingCreatesPurePaddingWithoutRtx) {
|
||||
(kPaddingBytesRequested + kMaxPaddingSize - 1) / kMaxPaddingSize;
|
||||
size_t padding_bytes_generated = 0;
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
|
||||
rtp_sender_->GeneratePadding(kPaddingBytesRequested, true);
|
||||
GeneratePadding(kPaddingBytesRequested);
|
||||
EXPECT_EQ(padding_packets.size(), kExpectedNumPaddingPackets);
|
||||
for (auto& packet : padding_packets) {
|
||||
EXPECT_EQ(packet->packet_type(), RtpPacketMediaType::kPadding);
|
||||
@ -1337,4 +1378,70 @@ TEST_F(RtpSenderTest, MarksPacketsWithKeyframeStatus) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderTest, PlainPaddingWithDeferredSequencing) {
|
||||
CreateSenderWithDeferredSequencing(GetDefaultConfig());
|
||||
|
||||
EXPECT_THAT(
|
||||
rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/500,
|
||||
/*media_has_been_sent=*/true,
|
||||
/*can_send_padding_on_media_ssrc=*/true),
|
||||
Each(Pointee(AllOf(Property(&RtpPacketToSend::SequenceNumber, 0),
|
||||
Property(&RtpPacketToSend::padding_size, Gt(0u)),
|
||||
Property(&RtpPacketToSend::Ssrc, kSsrc)))));
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderTest, PlainRtxPaddingWithDeferredSequencing) {
|
||||
CreateSenderWithDeferredSequencing(GetDefaultConfig());
|
||||
EnableRtx();
|
||||
|
||||
EXPECT_THAT(
|
||||
rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/500,
|
||||
/*media_has_been_sent=*/true,
|
||||
/*can_send_padding_on_media_ssrc=*/true),
|
||||
Each(Pointee(AllOf(Property(&RtpPacketToSend::SequenceNumber, 0),
|
||||
Property(&RtpPacketToSend::padding_size, Gt(0u)),
|
||||
Property(&RtpPacketToSend::Ssrc, kRtxSsrc)))));
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderTest, PayloadPaddingWithDeferredSequencing) {
|
||||
CreateSenderWithDeferredSequencing(GetDefaultConfig());
|
||||
EnableRtx();
|
||||
ASSERT_TRUE(rtp_sender_->RegisterRtpHeaderExtension(
|
||||
TransportSequenceNumber::kUri, kTransportSequenceNumberExtensionId));
|
||||
|
||||
EXPECT_CALL(mock_paced_sender_, EnqueuePackets);
|
||||
std::unique_ptr<RtpPacketToSend> media_packet =
|
||||
SendPacket(clock_->TimeInMilliseconds(), /*payload_size=*/500);
|
||||
packet_history_->PutRtpPacket(std::move(media_packet),
|
||||
clock_->TimeInMilliseconds());
|
||||
|
||||
EXPECT_THAT(
|
||||
rtp_sender_->GeneratePadding(
|
||||
/*target_size_bytes=*/500,
|
||||
/*media_has_been_sent=*/true,
|
||||
/*can_send_padding_on_media_ssrc=*/true),
|
||||
Each(Pointee(AllOf(Property(&RtpPacketToSend::SequenceNumber, 0),
|
||||
Property(&RtpPacketToSend::payload_size, Gt(0u)),
|
||||
Property(&RtpPacketToSend::Ssrc, kRtxSsrc)))));
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderTest, RtxRetransmissionWithDeferredSequencing) {
|
||||
CreateSenderWithDeferredSequencing(GetDefaultConfig());
|
||||
EnableRtx();
|
||||
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
auto packet = BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, now_ms);
|
||||
packet->SetSequenceNumber(kSeqNum);
|
||||
packet->set_allow_retransmission(true);
|
||||
packet_history_->PutRtpPacket(std::move(packet), now_ms);
|
||||
|
||||
EXPECT_CALL(mock_paced_sender_,
|
||||
EnqueuePackets(ElementsAre(Pointee(
|
||||
AllOf(Property(&RtpPacketToSend::Ssrc, kRtxSsrc),
|
||||
Property(&RtpPacketToSend::SequenceNumber, 0u))))));
|
||||
EXPECT_TRUE(rtp_sender_->ReSendPacket(kSeqNum));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user