Add support for deferred sequence numbering.

With this turned on, packets will be sequence number after the pacing
stage rather that during packetization.
This avoids a race where packets may be sent out of order, and paves
the way for the ability to cull packets from the pacer queue without
causing sequence number gaps.

For now, the feature is off by default. Follow-ups will enable it for
video and audio separately.

Bug: webrtc:11340, webrtc:12470
Change-Id: I6d411d8c85b9047e3e9b05ff4c2c3ed97c579aa1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/208584
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34661}
This commit is contained in:
Erik Språng
2021-08-06 13:10:11 +02:00
committed by WebRTC LUCI CQ
parent 82c2248511
commit bb90497eaa
11 changed files with 164 additions and 41 deletions

View File

@ -152,9 +152,12 @@ class SendTransport : public Transport,
};
struct TestConfig {
explicit TestConfig(bool with_overhead) : with_overhead(with_overhead) {}
explicit TestConfig(bool with_overhead, bool with_deferred_sequencing)
: with_overhead(with_overhead),
with_deferred_sequencing(with_deferred_sequencing) {}
bool with_overhead = false;
bool with_deferred_sequencing = false;
};
class FieldTrialConfig : public WebRtcKeyValueConfig {
@ -201,10 +204,12 @@ class RtpRtcpModule : public RtcpPacketTypeCounterObserver,
RtpRtcpModule(GlobalSimulatedTimeController* time_controller,
bool is_sender,
const FieldTrialConfig& trials)
const FieldTrialConfig& trials,
bool deferred_sequencing)
: time_controller_(time_controller),
is_sender_(is_sender),
trials_(trials),
deferred_sequencing_(deferred_sequencing),
receive_statistics_(
ReceiveStatistics::Create(time_controller->GetClock())),
transport_(kOneWayNetworkDelay, time_controller) {
@ -214,6 +219,7 @@ class RtpRtcpModule : public RtcpPacketTypeCounterObserver,
TimeController* const time_controller_;
const bool is_sender_;
const FieldTrialConfig& trials_;
const bool deferred_sequencing_;
RtcpPacketTypeCounter packets_sent_;
RtcpPacketTypeCounter packets_received_;
std::unique_ptr<ReceiveStatistics> receive_statistics_;
@ -283,6 +289,7 @@ class RtpRtcpModule : public RtcpPacketTypeCounterObserver,
config.field_trials = &trials_;
config.send_packet_observer = this;
config.fec_generator = fec_generator_;
config.use_deferred_sequencing = deferred_sequencing_;
impl_.reset(new ModuleRtpRtcpImpl2(config));
impl_->SetRemoteSSRC(is_sender_ ? kReceiverSsrc : kSenderSsrc);
impl_->SetRTCPStatus(RtcpMode::kCompound);
@ -303,10 +310,12 @@ class RtpRtcpImpl2Test : public ::testing::TestWithParam<TestConfig> {
field_trials_(FieldTrialConfig::GetFromTestConfig(GetParam())),
sender_(&time_controller_,
/*is_sender=*/true,
field_trials_),
field_trials_,
GetParam().with_deferred_sequencing),
receiver_(&time_controller_,
/*is_sender=*/false,
field_trials_) {}
field_trials_,
GetParam().with_deferred_sequencing) {}
void SetUp() override {
// Send module.
@ -408,6 +417,12 @@ class RtpRtcpImpl2Test : public ::testing::TestWithParam<TestConfig> {
rtc::Buffer packet = nack.Build();
module->impl_->IncomingRtcpPacket(packet.data(), packet.size());
}
void MaybeAssignSequenceNumber(RtpPacketToSend* packet) {
if (!GetParam().with_deferred_sequencing) {
sender_.impl_->RtpSender()->AssignSequenceNumber(packet);
}
}
};
TEST_P(RtpRtcpImpl2Test, RetransmitsAllLayers) {
@ -738,7 +753,7 @@ TEST_P(RtpRtcpImpl2Test, StoresPacketInfoForSentPackets) {
// Single-packet frame.
packet.SetTimestamp(1);
packet.SetSequenceNumber(1);
MaybeAssignSequenceNumber(&packet);
packet.set_first_packet_of_frame(true);
packet.SetMarker(true);
sender_.impl_->TrySendPacket(&packet, pacing_info);
@ -754,16 +769,16 @@ TEST_P(RtpRtcpImpl2Test, StoresPacketInfoForSentPackets) {
// Three-packet frame.
packet.SetTimestamp(2);
packet.SetSequenceNumber(2);
MaybeAssignSequenceNumber(&packet);
packet.set_first_packet_of_frame(true);
packet.SetMarker(false);
sender_.impl_->TrySendPacket(&packet, pacing_info);
packet.SetSequenceNumber(3);
MaybeAssignSequenceNumber(&packet);
packet.set_first_packet_of_frame(false);
sender_.impl_->TrySendPacket(&packet, pacing_info);
packet.SetSequenceNumber(4);
MaybeAssignSequenceNumber(&packet);
packet.SetMarker(true);
sender_.impl_->TrySendPacket(&packet, pacing_info);
@ -922,7 +937,7 @@ TEST_P(RtpRtcpImpl2Test, PaddingNotAllowedInMiddleOfFrame) {
packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->set_first_packet_of_frame(true);
packet->SetMarker(false); // Marker false - not last packet of frame.
sender_.impl_->RtpSender()->AssignSequenceNumber(packet.get());
MaybeAssignSequenceNumber(packet.get());
EXPECT_TRUE(sender_.impl_->TrySendPacket(packet.get(), pacing_info));
@ -933,7 +948,7 @@ TEST_P(RtpRtcpImpl2Test, PaddingNotAllowedInMiddleOfFrame) {
packet->set_packet_type(RtpPacketToSend::Type::kVideo);
packet->set_first_packet_of_frame(true);
packet->SetMarker(true);
sender_.impl_->RtpSender()->AssignSequenceNumber(packet.get());
MaybeAssignSequenceNumber(packet.get());
EXPECT_TRUE(sender_.impl_->TrySendPacket(packet.get(), pacing_info));
@ -1172,9 +1187,11 @@ TEST_P(RtpRtcpImpl2Test, RtxRtpStateReflectsCurrentState) {
EXPECT_EQ(rtx_state.sequence_number, rtx_packet.SequenceNumber() + 1);
}
INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverheadAndDeferredSequencing,
RtpRtcpImpl2Test,
::testing::Values(TestConfig{false},
TestConfig{true}));
::testing::Values(TestConfig{false, false},
TestConfig{false, true},
TestConfig{true, false},
TestConfig{true, true}));
} // namespace webrtc