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 "testing/gtest/include/gtest/gtest.h" | |
14 #include "webrtc/modules/audio_coding/main/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 | |
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 | |
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 | |
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: | |
65 InitialDelayManagerTest() | |
66 : manager_(new InitialDelayManager(kInitDelayMs, kLatePacketThreshold)), | |
67 rtp_receive_timestamp_(1111) { } // Arbitrary starting point. | |
68 | |
69 virtual void SetUp() { | |
70 ASSERT_TRUE(manager_.get() != NULL); | |
71 InitRtpInfo(&rtp_info_); | |
72 } | |
73 | |
74 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 | |
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 | |
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. | |
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 | |
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 | |
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 | |
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 | |
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 | |
OLD | NEW |