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 }