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 = 20;
332 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
333 int32_t countGet = 0;
334 int32_t countGetFrame = 0;
335 int32_t countNotGet = 0;
336 int32_t getTime = 0;
337
338 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
339 uint8_t* data = nullptr;
340 uint32_t size = 0;
341 uint32_t timestamp = 0;
342 bool mark = false;
343 uint32_t seq = 0;
344 uint16_t startSeq = 0;
345 uint16_t addSeq = 0;
346 uint16_t getSeq = 0;
347
348 for (int32_t i = 0; i < kNumFrames; i++)
349 {
350 addSeq = startSeq + (uint16_t)i;
351 int32_t addTime = i * TEST_FRAME_INTERVAL;
352 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
353 sizeof(buffer), i * TEST_FRAME_INTERVAL, false, addSeq, MEDIASUBTYPE_UNDEFINED,
354 addTime);
355
356 if (i == 5)
357 {
358 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer), 1,
359 i * TEST_FRAME_INTERVAL, false, addSeq, MEDIASUBTYPE_UNDEFINED, addTime);
360 }
361
362 getTime = countGet * TEST_FRAME_INTERVAL;
363
364 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
365 {
366 getSeq = startSeq + (uint16_t)countGetFrame;
367 EXPECT_EQ(size, sizeof(buffer));
368 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
369 EXPECT_EQ(seq, getSeq);
370 mJitterBuffer->Delete();
371 countGetFrame++;
372 }
373 else
374 {
375 countNotGet++;
376 }
377
378 countGet++;
379 }
380
381 while (mJitterBuffer->GetCount() > 0)
382 {
383 getTime = countGet * TEST_FRAME_INTERVAL;
384
385 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
386 {
387 getSeq = startSeq + (uint16_t)countGetFrame;
388 EXPECT_EQ(size, sizeof(buffer));
389 EXPECT_EQ(timestamp, countGetFrame * TEST_FRAME_INTERVAL);
390 EXPECT_EQ(seq, getSeq);
391 mJitterBuffer->Delete();
392 countGetFrame++;
393 }
394 else
395 {
396 countNotGet++;
397 }
398
399 countGet++;
400 }
401
402 EXPECT_EQ(mCallback.getNumLost(), 0);
403 EXPECT_EQ(mCallback.getNumDuplicated(), 1);
404 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
405 EXPECT_EQ(countNotGet, mStartJitterBufferSize);
406 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
407 }
408
TEST_F(AudioJitterBufferTest,TestAddGetInBurstIncoming)409 TEST_F(AudioJitterBufferTest, TestAddGetInBurstIncoming)
410 {
411 const int32_t kNumFrames = 30;
412 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
413 int32_t getTime = 0;
414
415 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
416 uint8_t* data = nullptr;
417 uint32_t size = 0;
418 uint32_t timestamp = 0;
419 bool mark = false;
420 uint32_t seq = 0;
421 uint16_t startSeq = 0;
422 uint16_t addSeq = startSeq;
423 uint32_t addTimestamp = 0;
424 int32_t iter = 0;
425 int32_t addTime = 0;
426 uint32_t numBurstFrames = 11;
427
428 while (addSeq < kNumFrames)
429 {
430 if (iter > 5 && iter < 5 + numBurstFrames) // not added for 10 frame interval
431 {
432 addTime += TEST_FRAME_INTERVAL;
433 }
434 else if (iter == 5 + numBurstFrames)
435 {
436 do // 11 frames burst added
437 {
438 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
439 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_AUDIO_NORMAL,
440 addTime);
441 addTime += 1; // 1ms burst
442 addTimestamp += TEST_FRAME_INTERVAL;
443 } while (++iter < 14);
444 }
445 else // normal
446 {
447 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
448 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_AUDIO_NORMAL,
449 addTime);
450 addTime += TEST_FRAME_INTERVAL;
451 addTimestamp += TEST_FRAME_INTERVAL;
452 }
453
454 iter++;
455
456 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq,
457 getTime += TEST_FRAME_INTERVAL))
458 {
459 mJitterBuffer->Delete();
460 }
461 }
462
463 while (mJitterBuffer->GetCount() > 0)
464 {
465 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq,
466 getTime += TEST_FRAME_INTERVAL))
467 {
468 mJitterBuffer->Delete();
469 }
470 }
471
472 int kdiscarded = 24;
473
474 EXPECT_EQ(mCallback.getNumLost(), 0);
475 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
476 EXPECT_EQ(mCallback.getNumDiscarded(), kdiscarded);
477 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames - kdiscarded);
478 }
479
TEST_F(AudioJitterBufferTest,TestAddGetInReceivingSid)480 TEST_F(AudioJitterBufferTest, TestAddGetInReceivingSid)
481 {
482 const int32_t kNumFrames = 20;
483 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
484 int32_t countGetFrame = 0;
485 int32_t getTime = 0;
486
487 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
488 uint8_t* data = nullptr;
489 uint32_t size = 0;
490 uint32_t timestamp = 0;
491 bool mark = false;
492 uint32_t seq = 0;
493 uint16_t startSeq = 0;
494 uint16_t addSeq = startSeq;
495 uint16_t getSeq = startSeq;
496 uint32_t addTimestamp = 0;
497
498 int32_t addTime = 0;
499 const int32_t kSidInterval = 160; // ms
500
501 while (addSeq < kNumFrames)
502 {
503 if (getTime % kSidInterval == 0)
504 {
505 addTime = kSidInterval * addSeq;
506 addTimestamp = addTime;
507 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
508 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
509 }
510
511 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
512 {
513 EXPECT_EQ(size, sizeof(buffer));
514 EXPECT_EQ(timestamp, countGetFrame * kSidInterval);
515 EXPECT_EQ(seq, getSeq++);
516 mJitterBuffer->Delete();
517 countGetFrame++;
518 }
519
520 getTime += TEST_FRAME_INTERVAL;
521 }
522
523 while (mJitterBuffer->GetCount() > 0)
524 {
525 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
526 {
527 getSeq = startSeq + (uint16_t)countGetFrame;
528 EXPECT_EQ(size, sizeof(buffer));
529 EXPECT_EQ(timestamp, countGetFrame * kSidInterval);
530 EXPECT_EQ(seq, getSeq);
531 mJitterBuffer->Delete();
532 countGetFrame++;
533 }
534
535 getTime += TEST_FRAME_INTERVAL;
536 }
537
538 EXPECT_EQ(mCallback.getNumLost(), 0);
539 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
540 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
541 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
542 }
543
TEST_F(AudioJitterBufferTest,TestAddGetWithShortLost)544 TEST_F(AudioJitterBufferTest, TestAddGetWithShortLost)
545 {
546 const int32_t kNumFrames = 20;
547 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
548 int32_t countGetFrame = 0;
549 int32_t countNotGetFrame = 0;
550 int32_t getTime = 0;
551
552 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
553 uint8_t* data = nullptr;
554 uint32_t size = 0;
555 uint32_t timestamp = 0;
556 bool mark = false;
557 uint32_t seq = 0;
558 uint16_t startSeq = 0;
559 uint16_t addSeq = startSeq;
560 uint32_t addTimestamp = 0;
561 int32_t addTime = 0;
562 uint32_t numLostFrames = 4;
563
564 while (addSeq < kNumFrames)
565 {
566 addTime = 20 * addSeq;
567 addTimestamp = addTime;
568
569 if (addSeq >= 10 && addSeq < 10 + numLostFrames) // 4 packet lost
570 {
571 addSeq++;
572 }
573 else
574 {
575 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
576 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
577 }
578
579 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
580 {
581 mJitterBuffer->Delete();
582 countGetFrame++;
583 }
584 else
585 {
586 countNotGetFrame++;
587 }
588
589 getTime += TEST_FRAME_INTERVAL;
590 }
591
592 while (mJitterBuffer->GetCount() > 0)
593 {
594 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
595 {
596 mJitterBuffer->Delete();
597 countGetFrame++;
598 }
599 else
600 {
601 countNotGetFrame++;
602 }
603
604 getTime += TEST_FRAME_INTERVAL;
605 }
606
607 EXPECT_EQ(countNotGetFrame, numLostFrames + mStartJitterBufferSize);
608 EXPECT_EQ(countGetFrame, kNumFrames - numLostFrames);
609 EXPECT_EQ(mCallback.getNumLost(), numLostFrames);
610 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
611 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
612 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames - numLostFrames);
613 }
614
TEST_F(AudioJitterBufferTest,TestAddGetWithLongLost)615 TEST_F(AudioJitterBufferTest, TestAddGetWithLongLost)
616 {
617 const int32_t kNumFrames = 30;
618 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
619 int32_t countGetFrame = 0;
620 int32_t countNotGetFrame = 0;
621 int32_t getTime = 0;
622
623 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
624 uint8_t* data = nullptr;
625 uint32_t size = 0;
626 uint32_t timestamp = 0;
627 bool mark = false;
628 uint32_t seq = 0;
629 uint16_t startSeq = 0;
630 uint16_t addSeq = startSeq;
631 uint32_t addTimestamp = 0;
632 int32_t addTime = 0;
633 uint32_t numLostFrames = mMaxJitterBufferSize + 1;
634
635 while (addSeq < kNumFrames)
636 {
637 addTime = 20 * addSeq;
638 addTimestamp = addTime;
639
640 if (addSeq >= 10 && addSeq < 10 + numLostFrames) // 10 packet lost
641 {
642 addSeq++;
643 }
644 else
645 {
646 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
647 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
648 }
649
650 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
651 {
652 mJitterBuffer->Delete();
653 countGetFrame++;
654 }
655 else
656 {
657 countNotGetFrame++;
658 }
659
660 getTime += TEST_FRAME_INTERVAL;
661 }
662
663 while (mJitterBuffer->GetCount() > 0)
664 {
665 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
666 {
667 mJitterBuffer->Delete();
668 countGetFrame++;
669 }
670 else
671 {
672 countNotGetFrame++;
673 }
674
675 getTime += TEST_FRAME_INTERVAL;
676 }
677
678 EXPECT_EQ(countNotGetFrame, numLostFrames + mStartJitterBufferSize);
679 EXPECT_EQ(countGetFrame, kNumFrames - numLostFrames);
680 EXPECT_EQ(mCallback.getNumLost(), numLostFrames);
681 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
682 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
683 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames - numLostFrames);
684 }
685
TEST_F(AudioJitterBufferTest,TestAddGetWithLostOverOutlier)686 TEST_F(AudioJitterBufferTest, TestAddGetWithLostOverOutlier)
687 {
688 const int32_t kNumFrames = 20;
689 char buffer[TEST_BUFFER_SIZE] = {"\x1\x2\x3\x4\x5\x6\x7\x0"};
690 int32_t countGetFrame = 0;
691 int32_t countNotGetFrame = 0;
692 int32_t getTime = 0;
693
694 ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
695 uint8_t* data = nullptr;
696 uint32_t size = 0;
697 uint32_t timestamp = 0;
698 bool mark = false;
699 uint32_t seq = 0;
700 uint32_t countAdd = 0;
701 uint16_t startSeq = 30000;
702 uint16_t addSeq = startSeq;
703 uint32_t addTimestamp = 0;
704 int32_t addTime = 0;
705
706 while (countAdd++ < kNumFrames)
707 {
708 addTime = 20 * countAdd;
709 addTimestamp = addTime;
710
711 if (countAdd > 10)
712 {
713 addSeq += 3000;
714 }
715
716 mJitterBuffer->Add(MEDIASUBTYPE_UNDEFINED, reinterpret_cast<uint8_t*>(buffer),
717 sizeof(buffer), addTimestamp, false, addSeq++, MEDIASUBTYPE_UNDEFINED, addTime);
718
719 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
720 {
721 mJitterBuffer->Delete();
722 countGetFrame++;
723 }
724 else
725 {
726 countNotGetFrame++;
727 }
728
729 getTime += TEST_FRAME_INTERVAL;
730 }
731
732 while (mJitterBuffer->GetCount() > 0)
733 {
734 if (mJitterBuffer->Get(&subtype, &data, &size, ×tamp, &mark, &seq, getTime))
735 {
736 mJitterBuffer->Delete();
737 countGetFrame++;
738 }
739 else
740 {
741 countNotGetFrame++;
742 }
743
744 getTime += TEST_FRAME_INTERVAL;
745 }
746
747 EXPECT_EQ(countNotGetFrame, mStartJitterBufferSize);
748 EXPECT_EQ(countGetFrame, kNumFrames);
749 EXPECT_EQ(mCallback.getNumLost(), 0);
750 EXPECT_EQ(mCallback.getNumDuplicated(), 0);
751 EXPECT_EQ(mCallback.getNumDiscarded(), 0);
752 EXPECT_EQ(mCallback.getNumNormal(), kNumFrames);
753 }