1 /*
2 * Copyright (c) 2013 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 <string.h>
12
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webrtc/modules/audio_coding/acm2/initial_delay_manager.h"
15
16 namespace webrtc {
17
18 namespace acm2 {
19
20 namespace {
21
22 const uint8_t kAudioPayloadType = 0;
23 const uint8_t kCngPayloadType = 1;
24 const uint8_t kAvtPayloadType = 2;
25
26 const int kSamplingRateHz = 16000;
27 const int kInitDelayMs = 200;
28 const int kFrameSizeMs = 20;
29 const uint32_t kTimestampStep = kFrameSizeMs * kSamplingRateHz / 1000;
30 const int kLatePacketThreshold = 5;
31
InitRtpInfo(WebRtcRTPHeader * rtp_info)32 void InitRtpInfo(WebRtcRTPHeader* rtp_info) {
33 memset(rtp_info, 0, sizeof(*rtp_info));
34 rtp_info->header.markerBit = false;
35 rtp_info->header.payloadType = kAudioPayloadType;
36 rtp_info->header.sequenceNumber = 1234;
37 rtp_info->header.timestamp = 0xFFFFFFFD; // Close to wrap around.
38 rtp_info->header.ssrc = 0x87654321; // Arbitrary.
39 rtp_info->header.numCSRCs = 0; // Arbitrary.
40 rtp_info->header.paddingLength = 0;
41 rtp_info->header.headerLength = sizeof(RTPHeader);
42 rtp_info->header.payload_type_frequency = kSamplingRateHz;
43 rtp_info->header.extension.absoluteSendTime = 0;
44 rtp_info->header.extension.transmissionTimeOffset = 0;
45 rtp_info->frameType = kAudioFrameSpeech;
46 }
47
ForwardRtpHeader(int n,WebRtcRTPHeader * rtp_info,uint32_t * rtp_receive_timestamp)48 void ForwardRtpHeader(int n,
49 WebRtcRTPHeader* rtp_info,
50 uint32_t* rtp_receive_timestamp) {
51 rtp_info->header.sequenceNumber += n;
52 rtp_info->header.timestamp += n * kTimestampStep;
53 *rtp_receive_timestamp += n * kTimestampStep;
54 }
55
NextRtpHeader(WebRtcRTPHeader * rtp_info,uint32_t * rtp_receive_timestamp)56 void NextRtpHeader(WebRtcRTPHeader* rtp_info,
57 uint32_t* rtp_receive_timestamp) {
58 ForwardRtpHeader(1, rtp_info, rtp_receive_timestamp);
59 }
60
61 } // namespace
62
63 class InitialDelayManagerTest : public ::testing::Test {
64 protected:
InitialDelayManagerTest()65 InitialDelayManagerTest()
66 : manager_(new InitialDelayManager(kInitDelayMs, kLatePacketThreshold)),
67 rtp_receive_timestamp_(1111) { } // Arbitrary starting point.
68
SetUp()69 virtual void SetUp() {
70 ASSERT_TRUE(manager_.get() != NULL);
71 InitRtpInfo(&rtp_info_);
72 }
73
GetNextRtpHeader(WebRtcRTPHeader * rtp_info,uint32_t * rtp_receive_timestamp) const74 void GetNextRtpHeader(WebRtcRTPHeader* rtp_info,
75 uint32_t* rtp_receive_timestamp) const {
76 memcpy(rtp_info, &rtp_info_, sizeof(*rtp_info));
77 *rtp_receive_timestamp = rtp_receive_timestamp_;
78 NextRtpHeader(rtp_info, rtp_receive_timestamp);
79 }
80
81 rtc::scoped_ptr<InitialDelayManager> manager_;
82 WebRtcRTPHeader rtp_info_;
83 uint32_t rtp_receive_timestamp_;
84 };
85
TEST_F(InitialDelayManagerTest,Init)86 TEST_F(InitialDelayManagerTest, Init) {
87 EXPECT_TRUE(manager_->buffering());
88 EXPECT_FALSE(manager_->PacketBuffered());
89 manager_->DisableBuffering();
90 EXPECT_FALSE(manager_->buffering());
91 InitialDelayManager::SyncStream sync_stream;
92
93 // Call before any packet inserted.
94 manager_->LatePackets(0x6789ABCD, &sync_stream); // Arbitrary but large
95 // receive timestamp.
96 EXPECT_EQ(0, sync_stream.num_sync_packets);
97
98 // Insert non-audio packets, a CNG and DTMF.
99 rtp_info_.header.payloadType = kCngPayloadType;
100 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
101 InitialDelayManager::kCngPacket, false,
102 kSamplingRateHz, &sync_stream);
103 EXPECT_EQ(0, sync_stream.num_sync_packets);
104 ForwardRtpHeader(5, &rtp_info_, &rtp_receive_timestamp_);
105 rtp_info_.header.payloadType = kAvtPayloadType;
106 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
107 InitialDelayManager::kAvtPacket, false,
108 kSamplingRateHz, &sync_stream);
109 // Gap in sequence numbers but no audio received, sync-stream should be empty.
110 EXPECT_EQ(0, sync_stream.num_sync_packets);
111 manager_->LatePackets(0x45678987, &sync_stream); // Large arbitrary receive
112 // timestamp.
113 // |manager_| has no estimate of timestamp-step and has not received any
114 // audio packet.
115 EXPECT_EQ(0, sync_stream.num_sync_packets);
116
117
118 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
119 rtp_info_.header.payloadType = kAudioPayloadType;
120 // First packet.
121 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
122 InitialDelayManager::kAudioPacket, true,
123 kSamplingRateHz, &sync_stream);
124 EXPECT_EQ(0, sync_stream.num_sync_packets);
125
126 // Call LatePAcket() after only one packet inserted.
127 manager_->LatePackets(0x6789ABCD, &sync_stream); // Arbitrary but large
128 // receive timestamp.
129 EXPECT_EQ(0, sync_stream.num_sync_packets);
130
131 // Gap in timestamp, but this packet is also flagged as "new," therefore,
132 // expecting empty sync-stream.
133 ForwardRtpHeader(5, &rtp_info_, &rtp_receive_timestamp_);
134 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
135 InitialDelayManager::kAudioPacket, true,
136 kSamplingRateHz, &sync_stream);
137 }
138
TEST_F(InitialDelayManagerTest,MissingPacket)139 TEST_F(InitialDelayManagerTest, MissingPacket) {
140 InitialDelayManager::SyncStream sync_stream;
141 // First packet.
142 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
143 InitialDelayManager::kAudioPacket, true,
144 kSamplingRateHz, &sync_stream);
145 ASSERT_EQ(0, sync_stream.num_sync_packets);
146
147 // Second packet.
148 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
149 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
150 InitialDelayManager::kAudioPacket, false,
151 kSamplingRateHz, &sync_stream);
152 ASSERT_EQ(0, sync_stream.num_sync_packets);
153
154 // Third packet, missing packets start from here.
155 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
156
157 // First sync-packet in sync-stream is one after the above packet.
158 WebRtcRTPHeader expected_rtp_info;
159 uint32_t expected_receive_timestamp;
160 GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp);
161
162 const int kNumMissingPackets = 10;
163 ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_);
164 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
165 InitialDelayManager::kAudioPacket, false,
166 kSamplingRateHz, &sync_stream);
167 EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets);
168 EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info,
169 sizeof(expected_rtp_info)));
170 EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step);
171 EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp);
172 }
173
174 // There hasn't been any consecutive packets to estimate timestamp-step.
TEST_F(InitialDelayManagerTest,MissingPacketEstimateTimestamp)175 TEST_F(InitialDelayManagerTest, MissingPacketEstimateTimestamp) {
176 InitialDelayManager::SyncStream sync_stream;
177 // First packet.
178 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
179 InitialDelayManager::kAudioPacket, true,
180 kSamplingRateHz, &sync_stream);
181 ASSERT_EQ(0, sync_stream.num_sync_packets);
182
183 // Second packet, missing packets start here.
184 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
185
186 // First sync-packet in sync-stream is one after the above.
187 WebRtcRTPHeader expected_rtp_info;
188 uint32_t expected_receive_timestamp;
189 GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp);
190
191 const int kNumMissingPackets = 10;
192 ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_);
193 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
194 InitialDelayManager::kAudioPacket, false,
195 kSamplingRateHz, &sync_stream);
196 EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets);
197 EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info,
198 sizeof(expected_rtp_info)));
199 }
200
TEST_F(InitialDelayManagerTest,MissingPacketWithCng)201 TEST_F(InitialDelayManagerTest, MissingPacketWithCng) {
202 InitialDelayManager::SyncStream sync_stream;
203
204 // First packet.
205 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
206 InitialDelayManager::kAudioPacket, true,
207 kSamplingRateHz, &sync_stream);
208 ASSERT_EQ(0, sync_stream.num_sync_packets);
209
210 // Second packet as CNG.
211 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
212 rtp_info_.header.payloadType = kCngPayloadType;
213 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
214 InitialDelayManager::kCngPacket, false,
215 kSamplingRateHz, &sync_stream);
216 ASSERT_EQ(0, sync_stream.num_sync_packets);
217
218 // Audio packet after CNG. Missing packets start from this packet.
219 rtp_info_.header.payloadType = kAudioPayloadType;
220 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
221
222 // Timestamps are increased higher than regular packet.
223 const uint32_t kCngTimestampStep = 5 * kTimestampStep;
224 rtp_info_.header.timestamp += kCngTimestampStep;
225 rtp_receive_timestamp_ += kCngTimestampStep;
226
227 // First sync-packet in sync-stream is the one after the above packet.
228 WebRtcRTPHeader expected_rtp_info;
229 uint32_t expected_receive_timestamp;
230 GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp);
231
232 const int kNumMissingPackets = 10;
233 ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_);
234 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
235 InitialDelayManager::kAudioPacket, false,
236 kSamplingRateHz, &sync_stream);
237 EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets);
238 EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info,
239 sizeof(expected_rtp_info)));
240 EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step);
241 EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp);
242 }
243
TEST_F(InitialDelayManagerTest,LatePacket)244 TEST_F(InitialDelayManagerTest, LatePacket) {
245 InitialDelayManager::SyncStream sync_stream;
246 // First packet.
247 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
248 InitialDelayManager::kAudioPacket, true,
249 kSamplingRateHz, &sync_stream);
250 ASSERT_EQ(0, sync_stream.num_sync_packets);
251
252 // Second packet.
253 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
254 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
255 InitialDelayManager::kAudioPacket, false,
256 kSamplingRateHz, &sync_stream);
257 ASSERT_EQ(0, sync_stream.num_sync_packets);
258
259 // Timestamp increment for 10ms;
260 const uint32_t kTimestampStep10Ms = kSamplingRateHz / 100;
261
262 // 10 ms after the second packet is inserted.
263 uint32_t timestamp_now = rtp_receive_timestamp_ + kTimestampStep10Ms;
264
265 // Third packet, late packets start from this packet.
266 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
267
268 // First sync-packet in sync-stream, which is one after the above packet.
269 WebRtcRTPHeader expected_rtp_info;
270 uint32_t expected_receive_timestamp;
271 GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp);
272
273 const int kLatePacketThreshold = 5;
274
275 int expected_num_late_packets = kLatePacketThreshold - 1;
276 for (int k = 0; k < 2; ++k) {
277 for (int n = 1; n < kLatePacketThreshold * kFrameSizeMs / 10; ++n) {
278 manager_->LatePackets(timestamp_now, &sync_stream);
279 EXPECT_EQ(0, sync_stream.num_sync_packets) <<
280 "try " << k << " loop number " << n;
281 timestamp_now += kTimestampStep10Ms;
282 }
283 manager_->LatePackets(timestamp_now, &sync_stream);
284
285 EXPECT_EQ(expected_num_late_packets, sync_stream.num_sync_packets) <<
286 "try " << k;
287 EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step) <<
288 "try " << k;
289 EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp) <<
290 "try " << k;
291 EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info,
292 sizeof(expected_rtp_info)));
293
294 timestamp_now += kTimestampStep10Ms;
295
296 // |manger_| assumes the |sync_stream| obtained by LatePacket() is fully
297 // injected. The last injected packet is sync-packet, therefore, there will
298 // not be any gap between sync stream of this and the next iteration.
299 ForwardRtpHeader(sync_stream.num_sync_packets, &expected_rtp_info,
300 &expected_receive_timestamp);
301 expected_num_late_packets = kLatePacketThreshold;
302 }
303
304 // Test "no-gap" for missing packet after late packet.
305 // |expected_rtp_info| is the expected sync-packet if any packet is missing.
306 memcpy(&rtp_info_, &expected_rtp_info, sizeof(rtp_info_));
307 rtp_receive_timestamp_ = expected_receive_timestamp;
308
309 int kNumMissingPackets = 3; // Arbitrary.
310 ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_);
311 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
312 InitialDelayManager::kAudioPacket, false,
313 kSamplingRateHz, &sync_stream);
314
315 // Note that there is one packet gap between the last sync-packet and the
316 // latest inserted packet.
317 EXPECT_EQ(kNumMissingPackets - 1, sync_stream.num_sync_packets);
318 EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step);
319 EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp);
320 EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info,
321 sizeof(expected_rtp_info)));
322 }
323
TEST_F(InitialDelayManagerTest,NoLatePacketAfterCng)324 TEST_F(InitialDelayManagerTest, NoLatePacketAfterCng) {
325 InitialDelayManager::SyncStream sync_stream;
326
327 // First packet.
328 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
329 InitialDelayManager::kAudioPacket, true,
330 kSamplingRateHz, &sync_stream);
331 ASSERT_EQ(0, sync_stream.num_sync_packets);
332
333 // Second packet as CNG.
334 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
335 rtp_info_.header.payloadType = kCngPayloadType;
336 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
337 InitialDelayManager::kCngPacket, false,
338 kSamplingRateHz, &sync_stream);
339 ASSERT_EQ(0, sync_stream.num_sync_packets);
340
341 // Forward the time more then |kLatePacketThreshold| packets.
342 uint32_t timestamp_now = rtp_receive_timestamp_ + kTimestampStep * (3 +
343 kLatePacketThreshold);
344
345 manager_->LatePackets(timestamp_now, &sync_stream);
346 EXPECT_EQ(0, sync_stream.num_sync_packets);
347 }
348
TEST_F(InitialDelayManagerTest,BufferingAudio)349 TEST_F(InitialDelayManagerTest, BufferingAudio) {
350 InitialDelayManager::SyncStream sync_stream;
351
352 // Very first packet is not counted in calculation of buffered audio.
353 for (int n = 0; n < kInitDelayMs / kFrameSizeMs; ++n) {
354 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
355 InitialDelayManager::kAudioPacket,
356 n == 0, kSamplingRateHz, &sync_stream);
357 EXPECT_EQ(0, sync_stream.num_sync_packets);
358 EXPECT_TRUE(manager_->buffering());
359 const uint32_t expected_playout_timestamp = rtp_info_.header.timestamp -
360 kInitDelayMs * kSamplingRateHz / 1000;
361 uint32_t actual_playout_timestamp = 0;
362 EXPECT_TRUE(manager_->GetPlayoutTimestamp(&actual_playout_timestamp));
363 EXPECT_EQ(expected_playout_timestamp, actual_playout_timestamp);
364 NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_);
365 }
366
367 manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_,
368 InitialDelayManager::kAudioPacket,
369 false, kSamplingRateHz, &sync_stream);
370 EXPECT_EQ(0, sync_stream.num_sync_packets);
371 EXPECT_FALSE(manager_->buffering());
372 }
373
374 } // namespace acm2
375
376 } // namespace webrtc
377