• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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