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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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, &timestamp, &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 }