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