xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/packet_sequencer_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/rtp_rtcp/source/packet_sequencer.h"
12 
13 #include "api/units/timestamp.h"
14 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
15 #include "system_wrappers/include/clock.h"
16 #include "test/gmock.h"
17 #include "test/gtest.h"
18 
19 namespace webrtc {
20 namespace {
21 constexpr Timestamp kStartTime = Timestamp::Millis(98765);
22 constexpr uint32_t kMediaSsrc = 123456;
23 constexpr uint32_t kRtxSsrc = 123457;
24 constexpr uint8_t kMediaPayloadType = 42;
25 constexpr uint16_t kMediaStartSequenceNumber = 123;
26 constexpr uint16_t kRtxStartSequenceNumber = 234;
27 constexpr uint16_t kDefaultSequenceNumber = 0x1234;
28 constexpr uint32_t kStartRtpTimestamp = 798;
29 
30 class PacketSequencerTest : public ::testing::Test {
31  public:
PacketSequencerTest()32   PacketSequencerTest()
33       : clock_(kStartTime),
34         sequencer_(kMediaSsrc,
35                    kRtxSsrc,
36                    /*require_marker_before_media_padding=*/true,
37                    &clock_) {}
38 
CreatePacket(RtpPacketMediaType type,uint32_t ssrc)39   RtpPacketToSend CreatePacket(RtpPacketMediaType type, uint32_t ssrc) {
40     RtpPacketToSend packet(/*extension_manager=*/nullptr);
41     packet.set_packet_type(type);
42     packet.SetSsrc(ssrc);
43     packet.SetSequenceNumber(kDefaultSequenceNumber);
44     packet.set_capture_time(clock_.CurrentTime());
45     packet.SetTimestamp(
46         kStartRtpTimestamp +
47         static_cast<uint32_t>(packet.capture_time().ms() - kStartTime.ms()));
48     return packet;
49   }
50 
51  protected:
52   SimulatedClock clock_;
53   PacketSequencer sequencer_;
54 };
55 
TEST_F(PacketSequencerTest,IgnoresMediaSsrcRetransmissions)56 TEST_F(PacketSequencerTest, IgnoresMediaSsrcRetransmissions) {
57   RtpPacketToSend packet =
58       CreatePacket(RtpPacketMediaType::kRetransmission, kMediaSsrc);
59   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
60   sequencer_.Sequence(packet);
61   EXPECT_EQ(packet.SequenceNumber(), kDefaultSequenceNumber);
62   EXPECT_EQ(sequencer_.media_sequence_number(), kMediaStartSequenceNumber);
63 }
64 
TEST_F(PacketSequencerTest,SequencesAudio)65 TEST_F(PacketSequencerTest, SequencesAudio) {
66   RtpPacketToSend packet = CreatePacket(RtpPacketMediaType::kAudio, kMediaSsrc);
67   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
68   sequencer_.Sequence(packet);
69   EXPECT_EQ(packet.SequenceNumber(), kMediaStartSequenceNumber);
70   EXPECT_EQ(sequencer_.media_sequence_number(), kMediaStartSequenceNumber + 1);
71 }
72 
TEST_F(PacketSequencerTest,SequencesVideo)73 TEST_F(PacketSequencerTest, SequencesVideo) {
74   RtpPacketToSend packet = CreatePacket(RtpPacketMediaType::kVideo, kMediaSsrc);
75   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
76   sequencer_.Sequence(packet);
77   EXPECT_EQ(packet.SequenceNumber(), kMediaStartSequenceNumber);
78   EXPECT_EQ(sequencer_.media_sequence_number(), kMediaStartSequenceNumber + 1);
79 }
80 
TEST_F(PacketSequencerTest,SequencesUlpFec)81 TEST_F(PacketSequencerTest, SequencesUlpFec) {
82   RtpPacketToSend packet =
83       CreatePacket(RtpPacketMediaType::kForwardErrorCorrection, kMediaSsrc);
84   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
85   sequencer_.Sequence(packet);
86   EXPECT_EQ(packet.SequenceNumber(), kMediaStartSequenceNumber);
87   EXPECT_EQ(sequencer_.media_sequence_number(), kMediaStartSequenceNumber + 1);
88 }
89 
TEST_F(PacketSequencerTest,SequencesRtxRetransmissions)90 TEST_F(PacketSequencerTest, SequencesRtxRetransmissions) {
91   RtpPacketToSend packet =
92       CreatePacket(RtpPacketMediaType::kRetransmission, kRtxSsrc);
93   sequencer_.set_rtx_sequence_number(kRtxStartSequenceNumber);
94   sequencer_.Sequence(packet);
95   EXPECT_EQ(packet.SequenceNumber(), kRtxStartSequenceNumber);
96   EXPECT_EQ(sequencer_.rtx_sequence_number(), kRtxStartSequenceNumber + 1);
97 }
98 
TEST_F(PacketSequencerTest,ProhibitsPaddingWithinVideoFrame)99 TEST_F(PacketSequencerTest, ProhibitsPaddingWithinVideoFrame) {
100   // Send a video packet with the marker bit set to false (indicating it is not
101   // the last packet of a frame).
102   RtpPacketToSend media_packet =
103       CreatePacket(RtpPacketMediaType::kVideo, kMediaSsrc);
104   media_packet.SetPayloadType(kMediaPayloadType);
105   media_packet.SetMarker(false);
106   sequencer_.Sequence(media_packet);
107 
108   // Sending padding on the media SSRC should not be allowed at this point.
109   EXPECT_FALSE(sequencer_.CanSendPaddingOnMediaSsrc());
110 
111   // Send a video packet with marker set to true, padding should be allowed
112   // again.
113   media_packet.SetMarker(true);
114   sequencer_.Sequence(media_packet);
115   EXPECT_TRUE(sequencer_.CanSendPaddingOnMediaSsrc());
116 }
117 
TEST_F(PacketSequencerTest,AllowsPaddingAtAnyTimeIfSoConfigured)118 TEST_F(PacketSequencerTest, AllowsPaddingAtAnyTimeIfSoConfigured) {
119   PacketSequencer packet_sequencer(
120       kMediaSsrc, kRtxSsrc,
121       /*require_marker_before_media_padding=*/false, &clock_);
122 
123   // Send an audio packet with the marker bit set to false.
124   RtpPacketToSend media_packet =
125       CreatePacket(RtpPacketMediaType::kAudio, kMediaSsrc);
126   media_packet.SetPayloadType(kMediaPayloadType);
127   media_packet.SetMarker(false);
128   packet_sequencer.Sequence(media_packet);
129 
130   // Sending padding on the media SSRC should be allowed despite no marker bit.
131   EXPECT_TRUE(packet_sequencer.CanSendPaddingOnMediaSsrc());
132 }
133 
TEST_F(PacketSequencerTest,UpdatesPaddingBasedOnLastMediaPacket)134 TEST_F(PacketSequencerTest, UpdatesPaddingBasedOnLastMediaPacket) {
135   // First send a media packet.
136   RtpPacketToSend media_packet =
137       CreatePacket(RtpPacketMediaType::kVideo, kMediaSsrc);
138   media_packet.SetPayloadType(kMediaPayloadType);
139   media_packet.SetMarker(true);
140   // Advance time so current time doesn't exactly match timestamp.
141   clock_.AdvanceTime(TimeDelta::Millis(5));
142   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
143   sequencer_.Sequence(media_packet);
144 
145   // Next send a padding packet and verify the media packet's timestamps and
146   // payload type is transferred to the padding packet.
147   RtpPacketToSend padding_packet =
148       CreatePacket(RtpPacketMediaType::kPadding, kMediaSsrc);
149   padding_packet.SetPadding(/*padding_size=*/100);
150   sequencer_.Sequence(padding_packet);
151 
152   EXPECT_EQ(padding_packet.SequenceNumber(), kMediaStartSequenceNumber + 1);
153   EXPECT_EQ(padding_packet.PayloadType(), kMediaPayloadType);
154   EXPECT_EQ(padding_packet.Timestamp(), media_packet.Timestamp());
155   EXPECT_EQ(padding_packet.capture_time(), media_packet.capture_time());
156 }
157 
TEST_F(PacketSequencerTest,UpdatesPaddingBasedOnLastRedPacket)158 TEST_F(PacketSequencerTest, UpdatesPaddingBasedOnLastRedPacket) {
159   // First send a media packet.
160   RtpPacketToSend media_packet =
161       CreatePacket(RtpPacketMediaType::kVideo, kMediaSsrc);
162   media_packet.SetPayloadType(kMediaPayloadType);
163   // Simulate a packet with RED encapsulation;
164   media_packet.set_is_red(true);
165   uint8_t* payload_buffer = media_packet.SetPayloadSize(1);
166   payload_buffer[0] = kMediaPayloadType + 1;
167 
168   media_packet.SetMarker(true);
169   // Advance time so current time doesn't exactly match timestamp.
170   clock_.AdvanceTime(TimeDelta::Millis(5));
171   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
172   sequencer_.Sequence(media_packet);
173 
174   // Next send a padding packet and verify the media packet's timestamps and
175   // payload type is transferred to the padding packet.
176   RtpPacketToSend padding_packet =
177       CreatePacket(RtpPacketMediaType::kPadding, kMediaSsrc);
178   padding_packet.SetPadding(100);
179   sequencer_.Sequence(padding_packet);
180 
181   EXPECT_EQ(padding_packet.SequenceNumber(), kMediaStartSequenceNumber + 1);
182   EXPECT_EQ(padding_packet.PayloadType(), kMediaPayloadType + 1);
183   EXPECT_EQ(padding_packet.Timestamp(), media_packet.Timestamp());
184   EXPECT_EQ(padding_packet.capture_time(), media_packet.capture_time());
185 }
186 
TEST_F(PacketSequencerTest,DoesNotUpdateFieldsOnPayloadPadding)187 TEST_F(PacketSequencerTest, DoesNotUpdateFieldsOnPayloadPadding) {
188   // First send a media packet.
189   RtpPacketToSend media_packet =
190       CreatePacket(RtpPacketMediaType::kVideo, kMediaSsrc);
191   media_packet.SetPayloadType(kMediaPayloadType);
192   media_packet.SetMarker(true);
193   // Advance time so current time doesn't exactly match timestamp.
194   clock_.AdvanceTime(TimeDelta::Millis(5));
195   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
196   sequencer_.Sequence(media_packet);
197 
198   // Simulate a payload padding packet on the RTX SSRC.
199   RtpPacketToSend padding_packet =
200       CreatePacket(RtpPacketMediaType::kPadding, kRtxSsrc);
201   padding_packet.SetPayloadSize(100);
202   padding_packet.SetPayloadType(kMediaPayloadType + 1);
203   padding_packet.SetTimestamp(kStartRtpTimestamp + 1);
204   padding_packet.set_capture_time(kStartTime + TimeDelta::Millis(1));
205   sequencer_.set_rtx_sequence_number(kRtxStartSequenceNumber);
206   sequencer_.Sequence(padding_packet);
207 
208   // The sequence number should be updated, but timestamps kept.
209   EXPECT_EQ(padding_packet.SequenceNumber(), kRtxStartSequenceNumber);
210   EXPECT_EQ(padding_packet.PayloadType(), kMediaPayloadType + 1);
211   EXPECT_EQ(padding_packet.Timestamp(), kStartRtpTimestamp + 1);
212   EXPECT_EQ(padding_packet.capture_time(), kStartTime + TimeDelta::Millis(1));
213 }
214 
TEST_F(PacketSequencerTest,UpdatesRtxPaddingBasedOnLastMediaPacket)215 TEST_F(PacketSequencerTest, UpdatesRtxPaddingBasedOnLastMediaPacket) {
216   constexpr uint32_t kTimestampTicksPerMs = 90;
217 
218   // First send a media packet.
219   RtpPacketToSend media_packet =
220       CreatePacket(RtpPacketMediaType::kVideo, kMediaSsrc);
221   media_packet.SetPayloadType(kMediaPayloadType);
222   media_packet.SetMarker(true);
223   sequencer_.set_media_sequence_number(kMediaStartSequenceNumber);
224   sequencer_.Sequence(media_packet);
225 
226   // Advance time, this time delta will be used to interpolate padding
227   // timestamps.
228   constexpr TimeDelta kTimeDelta = TimeDelta::Millis(10);
229   clock_.AdvanceTime(kTimeDelta);
230 
231   RtpPacketToSend padding_packet =
232       CreatePacket(RtpPacketMediaType::kPadding, kRtxSsrc);
233   padding_packet.SetPadding(100);
234   padding_packet.SetPayloadType(kMediaPayloadType + 1);
235   sequencer_.set_rtx_sequence_number(kRtxStartSequenceNumber);
236   sequencer_.Sequence(padding_packet);
237 
238   // Assigned RTX sequence number, but payload type unchanged in this case.
239   EXPECT_EQ(padding_packet.SequenceNumber(), kRtxStartSequenceNumber);
240   EXPECT_EQ(padding_packet.PayloadType(), kMediaPayloadType + 1);
241   // Timestamps are offset realtive to last media packet.
242   EXPECT_EQ(
243       padding_packet.Timestamp(),
244       media_packet.Timestamp() + (kTimeDelta.ms() * kTimestampTicksPerMs));
245   EXPECT_EQ(padding_packet.capture_time(),
246             media_packet.capture_time() + kTimeDelta);
247 }
248 
249 }  // namespace
250 }  // namespace webrtc
251