1 /**
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18 #include <AudioJitterBuffer.h>
19
20 #define TEST_BUFFER_SIZE 10
21 #define TEST_FRAME_INTERVAL 20
22
23 class AudioJitterBufferCallback : public BaseSessionCallback
24 {
25 public:
AudioJitterBufferCallback()26 AudioJitterBufferCallback()
27 {
28 numNormal = 0;
29 numLost = 0;
30 numDuplicated = 0;
31 numDiscarded = 0;
32 }
~AudioJitterBufferCallback()33 virtual ~AudioJitterBufferCallback() {}
34
onEvent(int32_t type,uint64_t param1,uint64_t)35 virtual void onEvent(int32_t type, uint64_t param1, uint64_t /*param2*/)
36 {
37 if (type == kCollectRxRtpStatus)
38 {
39 SessionCallbackParameter* param = reinterpret_cast<SessionCallbackParameter*>(param1);
40
41 if (param == nullptr)
42 {
43 return;
44 }
45
46 switch (param->param1)
47 {
48 case kRtpStatusDuplicated:
49 numDuplicated++;
50 break;
51 case kRtpStatusLate:
52 case kRtpStatusDiscarded:
53 numDiscarded++;
54 break;
55 case kRtpStatusNormal:
56 numNormal++;
57 break;
58 default:
59 break;
60 }
61
62 delete param;
63 }
64 else if (type == kCollectOptionalInfo)
65 {
66 SessionCallbackParameter* param = reinterpret_cast<SessionCallbackParameter*>(param1);
67
68 if (param == nullptr)
69 {
70 return;
71 }
72
73 if (param->type == kReportPacketLossGap)
74 {
75 numLost += param->param2;
76 }
77
78 delete param;
79 }
80 }
81
getNumNormal()82 int32_t getNumNormal() { return numNormal; }
getNumLost()83 int32_t getNumLost() { return numLost; }
getNumDuplicated()84 int32_t getNumDuplicated() { return numDuplicated; }
getNumDiscarded()85 int32_t getNumDiscarded() { return numDiscarded; }
86
87 private:
88 int32_t numNormal;
89 int32_t numLost;
90 int32_t numDuplicated;
91 int32_t numDiscarded;
92 };
93
94 class AudioJitterBufferTest : public ::testing::Test
95 {
96 public:
AudioJitterBufferTest()97 AudioJitterBufferTest() {}
~AudioJitterBufferTest()98 virtual ~AudioJitterBufferTest() {}
99
100 protected:
101 AudioJitterBuffer* mJitterBuffer;
102 AudioJitterBufferCallback mCallback;
103 int32_t mStartJitterBufferSize;
104 int32_t mMinJitterBufferSize;
105 int32_t mMaxJitterBufferSize;
106
SetUp()107 virtual void SetUp() override
108 {
109 mStartJitterBufferSize = 4;
110 mMinJitterBufferSize = 4;
111 mMaxJitterBufferSize = 9;
112
113 mJitterBuffer = new AudioJitterBuffer();
114 mJitterBuffer->SetCodecType(kAudioCodecAmr);
115 mJitterBuffer->SetSessionCallback(&mCallback);
116 mJitterBuffer->SetJitterBufferSize(
117 mStartJitterBufferSize, mMinJitterBufferSize, mMaxJitterBufferSize);
118 mJitterBuffer->SetJitterOptions(200, 100, 2, 1.8f);
119 mJitterBuffer->SetStartTime(0);
120 }
121
TearDown()122 virtual void TearDown() override { delete mJitterBuffer; }
123 };
124
TEST_F(AudioJitterBufferTest,TestNormalAddGet)125 TEST_F(AudioJitterBufferTest, TestNormalAddGet)
126 {
127 const int32_t kNumFrames = 50;
128 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
129 int32_t countGet = 0;
130 int32_t countGetFrame = 0;
131 int32_t countNotGet = 0;
132 int32_t getTime = 0;
133
134 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
135 uint8_t* data = nullptr;
136 uint32_t size = 0;
137 uint32_t timestamp = 0;
138 bool mark = false;
139 uint32_t seq = 0;
140
141 for (int32_t i = 0; i < kNumFrames; i++)
142 {
143 int32_t addTime = i * TEST_FRAME_INTERVAL;
144 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
145 sizeof(buffer), i * TEST_FRAME_INTERVAL, false, i, MEDIASUBTYPE_UNDEFINED, addTime);
146
147 getTime = countGet * TEST_FRAME_INTERVAL;
148
149 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
150 {
151 EXPECT_EQ(size, sizeof(buffer));
152 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
153 EXPECT_EQ(seq, countGetFrame);
154 mJitterBuffer->Delete();
155 countGetFrame++;
156 }
157 else
158 {
159 countNotGet++;
160 }
161
162 countGet++;
163 }
164
165 while (mJitterBuffer->GetCount() > 0)
166 {
167 getTime = countGet * TEST_FRAME_INTERVAL;
168
169 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
170 {
171 EXPECT_EQ(size, sizeof(buffer));
172 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
173 EXPECT_EQ(seq, countGetFrame);
174 mJitterBuffer->Delete();
175 countGetFrame++;
176 }
177 else
178 {
179 countNotGet++;
180 }
181
182 countGet++;
183 }
184
185 EXPECT_EQ(countNotGet, mStartJitterBufferSize);
186 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
187 }
188
TEST_F(AudioJitterBufferTest,TestNormalAddGetSeqRounding)189 TEST_F(AudioJitterBufferTest, TestNormalAddGetSeqRounding)
190 {
191 const int32_t kNumFrames = 20;
192 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
193 int32_t countGet = 0;
194 int32_t countGetFrame = 0;
195 int32_t countNotGet = 0;
196 int32_t getTime = 0;
197
198 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
199 uint8_t* data = nullptr;
200 uint32_t size = 0;
201 uint32_t timestamp = 0;
202 bool mark = false;
203 uint32_t seq = 0;
204 uint16_t startSeq = 65530;
205 uint16_t addSeq = 0;
206 uint16_t getSeq = 0;
207
208 for (int32_t i = 0; i < kNumFrames; i++)
209 {
210 addSeq = startSeq + (uint16_t)i;
211 int32_t addTime = i * TEST_FRAME_INTERVAL;
212 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
213 sizeof(buffer), i * TEST_FRAME_INTERVAL, false, addSeq, MEDIASUBTYPE_UNDEFINED,
214 addTime);
215
216 getTime = countGet * TEST_FRAME_INTERVAL;
217
218 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
219 {
220 getSeq = startSeq + (uint16_t)countGetFrame;
221 EXPECT_EQ(size, sizeof(buffer));
222 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
223 EXPECT_EQ(seq, getSeq);
224 mJitterBuffer->Delete();
225 countGetFrame++;
226 }
227 else
228 {
229 countNotGet++;
230 }
231 countGet++;
232 }
233
234 while (mJitterBuffer->GetCount() > 0)
235 {
236 getTime = countGet * TEST_FRAME_INTERVAL;
237
238 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
239 {
240 getSeq = startSeq + (uint16_t)countGetFrame;
241 EXPECT_EQ(size, sizeof(buffer));
242 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
243 EXPECT_EQ(seq, getSeq);
244 mJitterBuffer->Delete();
245 countGetFrame++;
246 }
247 else
248 {
249 countNotGet++;
250 }
251
252 countGet++;
253 }
254
255 EXPECT_EQ(countNotGet, mStartJitterBufferSize);
256 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
257 }
258
TEST_F(AudioJitterBufferTest,TestNormalAddGetTimestampRounding)259 TEST_F(AudioJitterBufferTest, TestNormalAddGetTimestampRounding)
260 {
261 const int32_t kNumFrames = 50;
262 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
263 int32_t countGet = 0;
264 int32_t countGetFrame = 0;
265 int32_t countNotGet = 0;
266 int32_t getTime = 0;
267
268 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
269 uint8_t* data = nullptr;
270 uint32_t size = 0;
271 uint32_t timestamp = 0;
272 bool mark = false;
273 uint32_t seq = 0;
274 uint32_t startTimestamp = 4294967295 - 200;
275 uint32_t addTimestamp = 0;
276 uint32_t getTimestamp = 0;
277
278 for (int32_t i = 0; i < kNumFrames; i++)
279 {
280 addTimestamp = startTimestamp + i * TEST_FRAME_INTERVAL;
281 int32_t addTime = i * TEST_FRAME_INTERVAL;
282 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
283 sizeof(buffer), addTimestamp, false, i, MEDIASUBTYPE_UNDEFINED, addTime);
284
285 getTime = countGet * TEST_FRAME_INTERVAL;
286
287 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
288 {
289 getTimestamp = startTimestamp + countGetFrame * TEST_FRAME_INTERVAL;
290 EXPECT_EQ(size, sizeof(buffer));
291 EXPECT_EQ(timestamp, getTimestamp);
292 EXPECT_EQ(seq, countGetFrame);
293 mJitterBuffer->Delete();
294 countGetFrame++;
295 }
296 else
297 {
298 countNotGet++;
299 }
300
301 countGet++;
302 }
303
304 while (mJitterBuffer->GetCount() > 0)
305 {
306 getTime = countGet * TEST_FRAME_INTERVAL;
307
308 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
309 {
310 getTimestamp = startTimestamp + countGetFrame * TEST_FRAME_INTERVAL;
311 EXPECT_EQ(size, sizeof(buffer));
312 EXPECT_EQ(timestamp, getTimestamp);
313 EXPECT_EQ(seq, countGetFrame);
314 mJitterBuffer->Delete();
315 countGetFrame++;
316 }
317 else
318 {
319 countNotGet++;
320 }
321
322 countGet++;
323 }
324
325 EXPECT_EQ(countNotGet, mStartJitterBufferSize);
326 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
327 }
328
TEST_F(AudioJitterBufferTest,TestAddGetDuplicatedSeqDetection)329 TEST_F(AudioJitterBufferTest, TestAddGetDuplicatedSeqDetection)
330 {
331 const int32_t kNumFrames = 10;
332 const int32_t kNumDuplicated = 2;
333 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
334 int32_t countGet = 0;
335 int32_t countGetFrame = 0;
336 int32_t countNotGet = 0;
337 int32_t getTime = 0;
338 uint32_t seq = 0;
339 uint32_t addTime = 0;
340 uint32_t listSeq[kNumFrames + kNumDuplicated] = {0, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9};
341 uint32_t listTimestamp[kNumFrames + kNumDuplicated] = {
342 0, 20, 40, 60, 80, 100, 100, 100, 120, 140, 160, 180};
343
344 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
345 uint8_t* data = nullptr;
346 uint32_t size = 0;
347 uint32_t timestamp = 0;
348 bool mark = false;
349
350 for (int32_t i = 0; i < kNumFrames + kNumDuplicated; i++)
351 {
352 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
353 sizeof(buffer), listTimestamp[i], false, listSeq[i], MEDIASUBTYPE_UNDEFINED,
354 addTime);
355 addTime += TEST_FRAME_INTERVAL;
356
357 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq,
358 getTime += TEST_FRAME_INTERVAL))
359 {
360 EXPECT_EQ(size, sizeof(buffer));
361 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
362 EXPECT_EQ(seq, countGetFrame);
363 mJitterBuffer->Delete();
364 countGetFrame++;
365 }
366 else
367 {
368 countNotGet++;
369 }
370
371 countGet++;
372 }
373
374 while (mJitterBuffer->GetCount() > 0)
375 {
376 getTime = countGet * TEST_FRAME_INTERVAL;
377
378 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
379 {
380 EXPECT_EQ(size, sizeof(buffer));
381 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
382 EXPECT_EQ(seq, countGetFrame);
383 mJitterBuffer->Delete();
384 countGetFrame++;
385 }
386 else
387 {
388 countNotGet++;
389 }
390
391 countGet++;
392 }
393
394 EXPECT_EQ(mCallback.getNumLost(), 0);
395 EXPECT_EQ(mCallback.getNumDuplicated(), kNumDuplicated);
396 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
397 EXPECT_EQ(countNotGet, mStartJitterBufferSize - 1);
398 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
399 }
400
TEST_F(AudioJitterBufferTest,TestAddGetInBurstIncoming)401 TEST_F(AudioJitterBufferTest, TestAddGetInBurstIncoming)
402 {
403 const int32_t kNumFrames = 30;
404 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
405 int32_t getTime = 0;
406
407 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
408 uint8_t* data = nullptr;
409 uint32_t size = 0;
410 uint32_t timestamp = 0;
411 bool mark = false;
412 uint32_t seq = 0;
413 uint16_t startSeq = 0;
414 uint16_t addSeq = startSeq;
415 uint32_t addTimestamp = 0;
416 int32_t iter = 0;
417 int32_t addTime = 0;
418 uint32_t numBurstFrames = 11;
419
420 while (addSeq < kNumFrames)
421 {
422 if (iter > 5 && iter < 5 + numBurstFrames) // not added for 10 frame interval
423 {
424 addTime += TEST_FRAME_INTERVAL;
425 }
426 else if (iter == 5 + numBurstFrames)
427 {
428 do // 11 frames burst added
429 {
430 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
431 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_AUDIO_NORMAL,
432 addTime);
433 addTime += 1; // 1ms burst
434 addTimestamp += TEST_FRAME_INTERVAL;
435 } while (++iter < 14);
436 }
437 else // normal
438 {
439 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
440 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_AUDIO_NORMAL,
441 addTime);
442 addTime += TEST_FRAME_INTERVAL;
443 addTimestamp += TEST_FRAME_INTERVAL;
444 }
445
446 iter++;
447
448 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq,
449 getTime += TEST_FRAME_INTERVAL))
450 {
451 mJitterBuffer->Delete();
452 }
453 }
454
455 while (mJitterBuffer->GetCount() > 0)
456 {
457 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq,
458 getTime += TEST_FRAME_INTERVAL))
459 {
460 mJitterBuffer->Delete();
461 }
462 }
463
464 int kdiscarded = 24;
465
466 EXPECT_EQ(mCallback.getNumLost(), 0);
467 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
468 EXPECT_EQ(mCallback.getNumDiscarded(), kdiscarded);
469 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames - kdiscarded);
470 }
471
TEST_F(AudioJitterBufferTest,TestAddGetInReceivingSid)472 TEST_F(AudioJitterBufferTest, TestAddGetInReceivingSid)
473 {
474 const int32_t kNumFrames = 20;
475 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
476 int32_t countGetFrame = 0;
477 int32_t getTime = 0;
478
479 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
480 uint8_t* data = nullptr;
481 uint32_t size = 0;
482 uint32_t timestamp = 0;
483 bool mark = false;
484 uint32_t seq = 0;
485 uint16_t startSeq = 0;
486 uint16_t addSeq = startSeq;
487 uint16_t getSeq = startSeq;
488 uint32_t addTimestamp = 0;
489
490 int32_t addTime = 0;
491 const int32_t kSidInterval = 160; // ms
492
493 while (addSeq < kNumFrames)
494 {
495 if (getTime % kSidInterval == 0)
496 {
497 addTime = kSidInterval * addSeq;
498 addTimestamp = addTime;
499 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
500 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
501 }
502
503 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
504 {
505 EXPECT_EQ(size, sizeof(buffer));
506 EXPECT_EQ(timestamp, countGetFrame * kSidInterval);
507 EXPECT_EQ(seq, getSeq++);
508 mJitterBuffer->Delete();
509 countGetFrame++;
510 }
511
512 getTime += TEST_FRAME_INTERVAL;
513 }
514
515 while (mJitterBuffer->GetCount() > 0)
516 {
517 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
518 {
519 getSeq = startSeq + (uint16_t)countGetFrame;
520 EXPECT_EQ(size, sizeof(buffer));
521 EXPECT_EQ(timestamp, countGetFrame * kSidInterval);
522 EXPECT_EQ(seq, getSeq);
523 mJitterBuffer->Delete();
524 countGetFrame++;
525 }
526
527 getTime += TEST_FRAME_INTERVAL;
528 }
529
530 EXPECT_EQ(mCallback.getNumLost(), 0);
531 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
532 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
533 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
534 }
535
TEST_F(AudioJitterBufferTest,TestAddGetWithShortLost)536 TEST_F(AudioJitterBufferTest, TestAddGetWithShortLost)
537 {
538 const int32_t kNumFrames = 20;
539 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
540 int32_t countGetFrame = 0;
541 int32_t countNotGetFrame = 0;
542 int32_t getTime = 0;
543
544 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
545 uint8_t* data = nullptr;
546 uint32_t size = 0;
547 uint32_t timestamp = 0;
548 bool mark = false;
549 uint32_t seq = 0;
550 uint16_t startSeq = 0;
551 uint16_t addSeq = startSeq;
552 uint32_t addTimestamp = 0;
553 int32_t addTime = 0;
554 uint32_t numLostFrames = 4;
555
556 while (addSeq < kNumFrames)
557 {
558 addTime = 20 * addSeq;
559 addTimestamp = addTime;
560
561 if (addSeq >= 10 && addSeq < 10 + numLostFrames) // 4 packet lost
562 {
563 addSeq++;
564 }
565 else
566 {
567 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
568 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
569 }
570
571 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
572 {
573 mJitterBuffer->Delete();
574 countGetFrame++;
575 }
576 else
577 {
578 countNotGetFrame++;
579 }
580
581 getTime += TEST_FRAME_INTERVAL;
582 }
583
584 while (mJitterBuffer->GetCount() > 0)
585 {
586 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
587 {
588 mJitterBuffer->Delete();
589 countGetFrame++;
590 }
591 else
592 {
593 countNotGetFrame++;
594 }
595
596 getTime += TEST_FRAME_INTERVAL;
597 }
598
599 EXPECT_EQ(countNotGetFrame, numLostFrames + mStartJitterBufferSize);
600 EXPECT_EQ(countGetFrame, kNumFrames - numLostFrames);
601 EXPECT_EQ(mCallback.getNumLost(), numLostFrames);
602 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
603 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
604 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames - numLostFrames);
605 }
606
TEST_F(AudioJitterBufferTest,TestAddGetWithLongLost)607 TEST_F(AudioJitterBufferTest, TestAddGetWithLongLost)
608 {
609 const int32_t kNumFrames = 30;
610 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
611 int32_t countGetFrame = 0;
612 int32_t countNotGetFrame = 0;
613 int32_t getTime = 0;
614
615 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
616 uint8_t* data = nullptr;
617 uint32_t size = 0;
618 uint32_t timestamp = 0;
619 bool mark = false;
620 uint32_t seq = 0;
621 uint16_t startSeq = 0;
622 uint16_t addSeq = startSeq;
623 uint32_t addTimestamp = 0;
624 int32_t addTime = 0;
625 uint32_t numLostFrames = mMaxJitterBufferSize + 1;
626
627 while (addSeq < kNumFrames)
628 {
629 addTime = 20 * addSeq;
630 addTimestamp = addTime;
631
632 if (addSeq >= 10 && addSeq < 10 + numLostFrames) // 10 packet lost
633 {
634 addSeq++;
635 }
636 else
637 {
638 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
639 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
640 }
641
642 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
643 {
644 mJitterBuffer->Delete();
645 countGetFrame++;
646 }
647 else
648 {
649 countNotGetFrame++;
650 }
651
652 getTime += TEST_FRAME_INTERVAL;
653 }
654
655 while (mJitterBuffer->GetCount() > 0)
656 {
657 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
658 {
659 mJitterBuffer->Delete();
660 countGetFrame++;
661 }
662 else
663 {
664 countNotGetFrame++;
665 }
666
667 getTime += TEST_FRAME_INTERVAL;
668 }
669
670 EXPECT_EQ(countNotGetFrame, numLostFrames + mStartJitterBufferSize);
671 EXPECT_EQ(countGetFrame, kNumFrames - numLostFrames);
672 EXPECT_EQ(mCallback.getNumLost(), numLostFrames);
673 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
674 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
675 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames - numLostFrames);
676 }
677
TEST_F(AudioJitterBufferTest,TestAddGetWithLostOverOutlier)678 TEST_F(AudioJitterBufferTest, TestAddGetWithLostOverOutlier)
679 {
680 const int32_t kNumFrames = 20;
681 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
682 int32_t countGetFrame = 0;
683 int32_t countNotGetFrame = 0;
684 int32_t getTime = 0;
685
686 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
687 uint8_t* data = nullptr;
688 uint32_t size = 0;
689 uint32_t timestamp = 0;
690 bool mark = false;
691 uint32_t seq = 0;
692 uint32_t countAdd = 0;
693 uint16_t startSeq = 30000;
694 uint16_t addSeq = startSeq;
695 uint32_t addTimestamp = 0;
696 int32_t addTime = 0;
697
698 while (countAdd++ < kNumFrames)
699 {
700 addTime = 20 * countAdd;
701 addTimestamp = addTime;
702
703 if (countAdd > 10)
704 {
705 addSeq += 3000;
706 }
707
708 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
709 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
710
711 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
712 {
713 mJitterBuffer->Delete();
714 countGetFrame++;
715 }
716 else
717 {
718 countNotGetFrame++;
719 }
720
721 getTime += TEST_FRAME_INTERVAL;
722 }
723
724 while (mJitterBuffer->GetCount() > 0)
725 {
726 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
727 {
728 mJitterBuffer->Delete();
729 countGetFrame++;
730 }
731 else
732 {
733 countNotGetFrame++;
734 }
735
736 getTime += TEST_FRAME_INTERVAL;
737 }
738
739 EXPECT_EQ(countNotGetFrame, mStartJitterBufferSize);
740 EXPECT_EQ(countGetFrame, kNumFrames);
741 EXPECT_EQ(mCallback.getNumLost(), 0);
742 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
743 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
744 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
745 }
746
TEST_F(AudioJitterBufferTest,TestAdditionalDelay)747 TEST_F(AudioJitterBufferTest, TestAdditionalDelay)
748 {
749 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
750
751 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
752 uint8_t* data = nullptr;
753 uint32_t size = 0;
754 uint32_t timestamp = 0;
755 bool mark = false;
756 uint32_t seq = 0;
757 const uint16_t startSeq = 10000;
758 uint16_t addSeq = startSeq;
759 uint32_t addTimestamp = 0;
760 int32_t addTime = 0;
761 int32_t getTime = addTime + mStartJitterBufferSize * TEST_FRAME_INTERVAL;
762
763 for (int i = 0; i < mStartJitterBufferSize; i++)
764 {
765 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
766 sizeof(buffer), addTimestamp += TEST_FRAME_INTERVAL, false, addSeq++,
767 MEDIASUBTYPE_UNDEFINED, addTime += TEST_FRAME_INTERVAL);
768
769 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq,
770 getTime += TEST_FRAME_INTERVAL))
771 {
772 mJitterBuffer->Delete();
773 }
774 }
775
776 int32_t additionalDelay = 100;
777 mJitterBuffer->SetAdditionalDelay(additionalDelay);
778
779 EXPECT_EQ(mJitterBuffer->GetCurrentSize(),
780 additionalDelay / TEST_FRAME_INTERVAL + mStartJitterBufferSize);
781
782 additionalDelay = 200;
783 mJitterBuffer->SetAdditionalDelay(additionalDelay);
784
785 EXPECT_EQ(mJitterBuffer->GetCurrentSize(),
786 additionalDelay / TEST_FRAME_INTERVAL + mStartJitterBufferSize);
787 }