Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(749)

Side by Side Diff: webrtc/modules/audio_coding/main/test/APITest.cc

Issue 1481493004: audio_coding: remove "main" directory (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/audio_coding/main/test/APITest.h"
12
13 #include <ctype.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include <iostream>
19 #include <ostream>
20 #include <string>
21
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "webrtc/base/platform_thread.h"
24 #include "webrtc/common.h"
25 #include "webrtc/common_types.h"
26 #include "webrtc/engine_configurations.h"
27 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
28 #include "webrtc/modules/audio_coding/main/test/utility.h"
29 #include "webrtc/system_wrappers/include/event_wrapper.h"
30 #include "webrtc/system_wrappers/include/tick_util.h"
31 #include "webrtc/system_wrappers/include/trace.h"
32 #include "webrtc/test/testsupport/fileutils.h"
33
34 namespace webrtc {
35
36 #define TEST_DURATION_SEC 600
37 #define NUMBER_OF_SENDER_TESTS 6
38 #define MAX_FILE_NAME_LENGTH_BYTE 500
39 #define CHECK_THREAD_NULLITY(myThread, S) \
40 if(myThread != NULL) { \
41 (myThread)->Start(); \
42 } else { \
43 ADD_FAILURE() << S; \
44 }
45
46 void APITest::Wait(uint32_t waitLengthMs) {
47 if (_randomTest) {
48 return;
49 } else {
50 EventWrapper* myEvent = EventWrapper::Create();
51 myEvent->Wait(waitLengthMs);
52 delete myEvent;
53 return;
54 }
55 }
56
57 APITest::APITest(const Config& config)
58 : _acmA(AudioCodingModule::Create(1)),
59 _acmB(AudioCodingModule::Create(2)),
60 _channel_A2B(NULL),
61 _channel_B2A(NULL),
62 _writeToFile(true),
63 _pullEventA(NULL),
64 _pushEventA(NULL),
65 _processEventA(NULL),
66 _apiEventA(NULL),
67 _pullEventB(NULL),
68 _pushEventB(NULL),
69 _processEventB(NULL),
70 _apiEventB(NULL),
71 _codecCntrA(0),
72 _codecCntrB(0),
73 _thereIsEncoderA(false),
74 _thereIsEncoderB(false),
75 _thereIsDecoderA(false),
76 _thereIsDecoderB(false),
77 _sendVADA(false),
78 _sendDTXA(false),
79 _sendVADModeA(VADNormal),
80 _sendVADB(false),
81 _sendDTXB(false),
82 _sendVADModeB(VADNormal),
83 _minDelayA(0),
84 _minDelayB(0),
85 _dotPositionA(0),
86 _dotMoveDirectionA(1),
87 _dotPositionB(39),
88 _dotMoveDirectionB(-1),
89 _vadCallbackA(NULL),
90 _vadCallbackB(NULL),
91 _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
92 _randomTest(false),
93 _testNumA(0),
94 _testNumB(1) {
95 int n;
96 for (n = 0; n < 32; n++) {
97 _payloadUsed[n] = false;
98 }
99
100 _movingDot[40] = '\0';
101
102 for (int n = 0; n < 40; n++) {
103 _movingDot[n] = ' ';
104 }
105 }
106
107 APITest::~APITest() {
108 DELETE_POINTER(_channel_A2B);
109 DELETE_POINTER(_channel_B2A);
110
111 DELETE_POINTER(_pushEventA);
112 DELETE_POINTER(_pullEventA);
113 DELETE_POINTER(_processEventA);
114 DELETE_POINTER(_apiEventA);
115
116 DELETE_POINTER(_pushEventB);
117 DELETE_POINTER(_pullEventB);
118 DELETE_POINTER(_processEventB);
119 DELETE_POINTER(_apiEventB);
120
121 _inFileA.Close();
122 _outFileA.Close();
123
124 _inFileB.Close();
125 _outFileB.Close();
126
127 DELETE_POINTER(_vadCallbackA);
128 DELETE_POINTER(_vadCallbackB);
129
130 delete &_apiTestRWLock;
131 }
132
133 int16_t APITest::SetUp() {
134 CodecInst dummyCodec;
135 int lastPayloadType = 0;
136
137 int16_t numCodecs = _acmA->NumberOfCodecs();
138 for (uint8_t n = 0; n < numCodecs; n++) {
139 AudioCodingModule::Codec(n, &dummyCodec);
140 if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
141 && (dummyCodec.plfreq == 32000)) {
142 continue;
143 }
144
145 printf("Register Receive Codec %s ", dummyCodec.plname);
146
147 if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
148 // Check registration with an already occupied payload type
149 int currentPayloadType = dummyCodec.pltype;
150 dummyCodec.pltype = 97; //lastPayloadType;
151 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
152 dummyCodec.pltype = currentPayloadType;
153 }
154
155 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
156 // test if re-registration works;
157 CodecInst nextCodec;
158 int currentPayloadType = dummyCodec.pltype;
159 AudioCodingModule::Codec(n + 1, &nextCodec);
160 dummyCodec.pltype = nextCodec.pltype;
161 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
162 _acmB->RegisterReceiveCodec(dummyCodec);
163 }
164 dummyCodec.pltype = currentPayloadType;
165 }
166
167 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
168 // test if un-registration works;
169 CodecInst nextCodec;
170 AudioCodingModule::Codec(n + 1, &nextCodec);
171 nextCodec.pltype = dummyCodec.pltype;
172 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
173 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
174 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
175 }
176 }
177
178 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
179 printf(" side A done!");
180 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
181 printf(" side B done!\n");
182
183 if (!strcmp(dummyCodec.plname, "CN")) {
184 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
185 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
186 }
187 lastPayloadType = dummyCodec.pltype;
188 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
189 _payloadUsed[lastPayloadType - 96] = true;
190 }
191 }
192 _thereIsDecoderA = true;
193 _thereIsDecoderB = true;
194
195 // Register Send Codec
196 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
197 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
198 _thereIsEncoderA = true;
199 //
200 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
201 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
202 _thereIsEncoderB = true;
203
204 uint16_t frequencyHz;
205
206 printf("\n\nAPI Test\n");
207 printf("========\n");
208 printf("Hit enter to accept the default values indicated in []\n\n");
209
210 //--- Input A
211 std::string file_name = webrtc::test::ResourcePath(
212 "audio_coding/testfile32kHz", "pcm");
213 frequencyHz = 32000;
214 printf("Enter input file at side A [%s]: ", file_name.c_str());
215 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
216 _inFileA.Open(file_name, frequencyHz, "rb", true);
217
218 //--- Output A
219 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
220 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
221 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
222 _outFileA.Open(out_file_a, frequencyHz, "wb");
223
224 //--- Input B
225 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
226 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
227 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
228 _inFileB.Open(file_name, frequencyHz, "rb", true);
229
230 //--- Output B
231 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
232 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
233 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
234 _outFileB.Open(out_file_b, frequencyHz, "wb");
235
236 //--- Set A-to-B channel
237 _channel_A2B = new Channel(2);
238 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
239 _channel_A2B->RegisterReceiverACM(_acmB.get());
240
241 //--- Set B-to-A channel
242 _channel_B2A = new Channel(1);
243 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
244 _channel_B2A->RegisterReceiverACM(_acmA.get());
245
246 //--- EVENT TIMERS
247 // A
248 _pullEventA = EventTimerWrapper::Create();
249 _pushEventA = EventTimerWrapper::Create();
250 _processEventA = EventTimerWrapper::Create();
251 _apiEventA = EventWrapper::Create();
252 // B
253 _pullEventB = EventTimerWrapper::Create();
254 _pushEventB = EventTimerWrapper::Create();
255 _processEventB = EventTimerWrapper::Create();
256 _apiEventB = EventWrapper::Create();
257
258 //--- I/O params
259 // A
260 _outFreqHzA = _outFileA.SamplingFrequency();
261 // B
262 _outFreqHzB = _outFileB.SamplingFrequency();
263
264 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
265
266 char print[11];
267
268 // Create a trace file.
269 Trace::CreateTrace();
270 Trace::SetTraceFile(
271 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
272
273 printf("\nRandom Test (y/n)?");
274 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
275 print[10] = '\0';
276 if (strstr(print, "y") != NULL) {
277 _randomTest = true;
278 _verbose = false;
279 _writeToFile = false;
280 } else {
281 _randomTest = false;
282 printf("\nPrint Tests (y/n)? ");
283 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
284 print[10] = '\0';
285 if (strstr(print, "y") == NULL) {
286 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
287 _verbose = false;
288 }
289 }
290
291 _vadCallbackA = new VADCallback;
292 _vadCallbackB = new VADCallback;
293
294 return 0;
295 }
296
297 bool APITest::PushAudioThreadA(void* obj) {
298 return static_cast<APITest*>(obj)->PushAudioRunA();
299 }
300
301 bool APITest::PushAudioThreadB(void* obj) {
302 return static_cast<APITest*>(obj)->PushAudioRunB();
303 }
304
305 bool APITest::PullAudioThreadA(void* obj) {
306 return static_cast<APITest*>(obj)->PullAudioRunA();
307 }
308
309 bool APITest::PullAudioThreadB(void* obj) {
310 return static_cast<APITest*>(obj)->PullAudioRunB();
311 }
312
313 bool APITest::ProcessThreadA(void* obj) {
314 return static_cast<APITest*>(obj)->ProcessRunA();
315 }
316
317 bool APITest::ProcessThreadB(void* obj) {
318 return static_cast<APITest*>(obj)->ProcessRunB();
319 }
320
321 bool APITest::APIThreadA(void* obj) {
322 return static_cast<APITest*>(obj)->APIRunA();
323 }
324
325 bool APITest::APIThreadB(void* obj) {
326 return static_cast<APITest*>(obj)->APIRunB();
327 }
328
329 bool APITest::PullAudioRunA() {
330 _pullEventA->Wait(100);
331 AudioFrame audioFrame;
332 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0) {
333 bool thereIsDecoder;
334 {
335 ReadLockScoped rl(_apiTestRWLock);
336 thereIsDecoder = _thereIsDecoderA;
337 }
338 if (thereIsDecoder) {
339 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
340 }
341 } else {
342 if (_writeToFile) {
343 _outFileA.Write10MsData(audioFrame);
344 }
345 }
346 return true;
347 }
348
349 bool APITest::PullAudioRunB() {
350 _pullEventB->Wait(100);
351 AudioFrame audioFrame;
352 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0) {
353 bool thereIsDecoder;
354 {
355 ReadLockScoped rl(_apiTestRWLock);
356 thereIsDecoder = _thereIsDecoderB;
357 }
358 if (thereIsDecoder) {
359 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
360 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
361 }
362 } else {
363 if (_writeToFile) {
364 _outFileB.Write10MsData(audioFrame);
365 }
366 }
367 return true;
368 }
369
370 bool APITest::PushAudioRunA() {
371 _pushEventA->Wait(100);
372 AudioFrame audioFrame;
373 _inFileA.Read10MsData(audioFrame);
374 if (_acmA->Add10MsData(audioFrame) < 0) {
375 bool thereIsEncoder;
376 {
377 ReadLockScoped rl(_apiTestRWLock);
378 thereIsEncoder = _thereIsEncoderA;
379 }
380 if (thereIsEncoder) {
381 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
382 }
383 }
384 return true;
385 }
386
387 bool APITest::PushAudioRunB() {
388 _pushEventB->Wait(100);
389 AudioFrame audioFrame;
390 _inFileB.Read10MsData(audioFrame);
391 if (_acmB->Add10MsData(audioFrame) < 0) {
392 bool thereIsEncoder;
393 {
394 ReadLockScoped rl(_apiTestRWLock);
395 thereIsEncoder = _thereIsEncoderB;
396 }
397
398 if (thereIsEncoder) {
399 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
400 }
401 }
402
403 return true;
404 }
405
406 bool APITest::ProcessRunA() {
407 _processEventA->Wait(100);
408 return true;
409 }
410
411 bool APITest::ProcessRunB() {
412 _processEventB->Wait(100);
413 return true;
414 }
415
416 /*/
417 *
418 * In side A we test the APIs which are related to sender Side.
419 *
420 /*/
421
422 void APITest::RunTest(char thread) {
423 int testNum;
424 {
425 WriteLockScoped cs(_apiTestRWLock);
426 if (thread == 'A') {
427 _testNumA = (_testNumB + 1 + (rand() % 3)) % 4;
428 testNum = _testNumA;
429
430 _movingDot[_dotPositionA] = ' ';
431 if (_dotPositionA == 0) {
432 _dotMoveDirectionA = 1;
433 }
434 if (_dotPositionA == 19) {
435 _dotMoveDirectionA = -1;
436 }
437 _dotPositionA += _dotMoveDirectionA;
438 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
439 } else {
440 _testNumB = (_testNumA + 1 + (rand() % 3)) % 4;
441 testNum = _testNumB;
442
443 _movingDot[_dotPositionB] = ' ';
444 if (_dotPositionB == 20) {
445 _dotMoveDirectionB = 1;
446 }
447 if (_dotPositionB == 39) {
448 _dotMoveDirectionB = -1;
449 }
450 _dotPositionB += _dotMoveDirectionB;
451 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
452 }
453 //fprintf(stderr, "%c: %d \n", thread, testNum);
454 //fflush(stderr);
455 }
456 switch (testNum) {
457 case 0:
458 CurrentCodec('A');
459 ChangeCodec('A');
460 break;
461 case 1:
462 if (!_randomTest) {
463 fprintf(stdout, "\nTesting Delay ...\n");
464 }
465 TestDelay('A');
466 break;
467 case 2:
468 TestSendVAD('A');
469 break;
470 case 3:
471 TestRegisteration('A');
472 break;
473 default:
474 fprintf(stderr, "Wrong Test Number\n");
475 getc(stdin);
476 exit(1);
477 }
478 }
479
480 bool APITest::APIRunA() {
481 _apiEventA->Wait(50);
482
483 bool randomTest;
484 {
485 ReadLockScoped rl(_apiTestRWLock);
486 randomTest = _randomTest;
487 }
488 if (randomTest) {
489 RunTest('A');
490 } else {
491 CurrentCodec('A');
492 ChangeCodec('A');
493 if (_codecCntrA == 0) {
494 fprintf(stdout, "\nTesting Delay ...\n");
495 TestDelay('A');
496 }
497 // VAD TEST
498 TestSendVAD('A');
499 TestRegisteration('A');
500 }
501 return true;
502 }
503
504 bool APITest::APIRunB() {
505 _apiEventB->Wait(50);
506 bool randomTest;
507 {
508 ReadLockScoped rl(_apiTestRWLock);
509 randomTest = _randomTest;
510 }
511 //_apiEventB->Wait(2000);
512 if (randomTest) {
513 RunTest('B');
514 }
515
516 return true;
517 }
518
519 void APITest::Perform() {
520 SetUp();
521
522 //--- THREADS
523 // A
524 // PUSH
525 rtc::scoped_ptr<PlatformThread> myPushAudioThreadA =
526 PlatformThread::CreateThread(PushAudioThreadA, this, "PushAudioThreadA");
527 CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
528 // PULL
529 rtc::scoped_ptr<PlatformThread> myPullAudioThreadA =
530 PlatformThread::CreateThread(PullAudioThreadA, this, "PullAudioThreadA");
531 CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
532 // Process
533 rtc::scoped_ptr<PlatformThread> myProcessThreadA =
534 PlatformThread::CreateThread(ProcessThreadA, this, "ProcessThreadA");
535 CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
536 // API
537 rtc::scoped_ptr<PlatformThread> myAPIThreadA =
538 PlatformThread::CreateThread(APIThreadA, this, "APIThreadA");
539 CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
540 // B
541 // PUSH
542 rtc::scoped_ptr<PlatformThread> myPushAudioThreadB =
543 PlatformThread::CreateThread(PushAudioThreadB, this, "PushAudioThreadB");
544 CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
545 // PULL
546 rtc::scoped_ptr<PlatformThread> myPullAudioThreadB =
547 PlatformThread::CreateThread(PullAudioThreadB, this, "PullAudioThreadB");
548 CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
549 // Process
550 rtc::scoped_ptr<PlatformThread> myProcessThreadB =
551 PlatformThread::CreateThread(ProcessThreadB, this, "ProcessThreadB");
552 CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
553 // API
554 rtc::scoped_ptr<PlatformThread> myAPIThreadB =
555 PlatformThread::CreateThread(APIThreadB, this, "APIThreadB");
556 CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
557
558 //_apiEventA->StartTimer(true, 5000);
559 //_apiEventB->StartTimer(true, 5000);
560
561 _processEventA->StartTimer(true, 10);
562 _processEventB->StartTimer(true, 10);
563
564 _pullEventA->StartTimer(true, 10);
565 _pullEventB->StartTimer(true, 10);
566
567 _pushEventA->StartTimer(true, 10);
568 _pushEventB->StartTimer(true, 10);
569
570 // Keep main thread waiting for sender/receiver
571 // threads to complete
572 EventWrapper* completeEvent = EventWrapper::Create();
573 uint64_t startTime = TickTime::MillisecondTimestamp();
574 uint64_t currentTime;
575 // Run test in 2 minutes (120000 ms).
576 do {
577 {
578 //ReadLockScoped rl(_apiTestRWLock);
579 //fprintf(stderr, "\r%s", _movingDot);
580 }
581 //fflush(stderr);
582 completeEvent->Wait(50);
583 currentTime = TickTime::MillisecondTimestamp();
584 } while ((currentTime - startTime) < 120000);
585
586 //completeEvent->Wait(0xFFFFFFFF);
587 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
588 delete completeEvent;
589
590 myPushAudioThreadA->Stop();
591 myPullAudioThreadA->Stop();
592 myProcessThreadA->Stop();
593 myAPIThreadA->Stop();
594
595 myPushAudioThreadB->Stop();
596 myPullAudioThreadB->Stop();
597 myProcessThreadB->Stop();
598 myAPIThreadB->Stop();
599 }
600
601 void APITest::CheckVADStatus(char side) {
602
603 bool dtxEnabled;
604 bool vadEnabled;
605 ACMVADMode vadMode;
606
607 if (side == 'A') {
608 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
609 _acmA->RegisterVADCallback(NULL);
610 _vadCallbackA->Reset();
611 _acmA->RegisterVADCallback(_vadCallbackA);
612
613 if (!_randomTest) {
614 if (_verbose) {
615 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
616 vadEnabled ? "ON" : "OFF", (int) vadMode);
617 Wait(5000);
618 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
619 } else {
620 Wait(5000);
621 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
622 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
623 (int) vadMode, _channel_A2B->BitRate());
624 }
625 _vadCallbackA->PrintFrameTypes();
626 }
627
628 if (dtxEnabled != _sendDTXA) {
629 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
630 }
631 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
632 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
633 }
634 if ((vadMode != _sendVADModeA) && vadEnabled) {
635 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
636 }
637 } else {
638 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
639
640 _acmB->RegisterVADCallback(NULL);
641 _vadCallbackB->Reset();
642 _acmB->RegisterVADCallback(_vadCallbackB);
643
644 if (!_randomTest) {
645 if (_verbose) {
646 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
647 vadEnabled ? "ON" : "OFF", (int) vadMode);
648 Wait(5000);
649 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
650 } else {
651 Wait(5000);
652 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
653 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
654 (int) vadMode, _channel_B2A->BitRate());
655 }
656 _vadCallbackB->PrintFrameTypes();
657 }
658
659 if (dtxEnabled != _sendDTXB) {
660 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
661 }
662 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
663 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
664 }
665 if ((vadMode != _sendVADModeB) && vadEnabled) {
666 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
667 }
668 }
669 }
670
671 // Set Min delay, get delay, playout timestamp
672 void APITest::TestDelay(char side) {
673 AudioCodingModule* myACM;
674 Channel* myChannel;
675 int32_t* myMinDelay;
676 EventTimerWrapper* myEvent = EventTimerWrapper::Create();
677
678 uint32_t inTimestamp = 0;
679 uint32_t outTimestamp = 0;
680 double estimDelay = 0;
681
682 double averageEstimDelay = 0;
683 double averageDelay = 0;
684
685 CircularBuffer estimDelayCB(100);
686 estimDelayCB.SetArithMean(true);
687
688 if (side == 'A') {
689 myACM = _acmA.get();
690 myChannel = _channel_B2A;
691 myMinDelay = &_minDelayA;
692 } else {
693 myACM = _acmB.get();
694 myChannel = _channel_A2B;
695 myMinDelay = &_minDelayB;
696 }
697
698 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
699
700 inTimestamp = myChannel->LastInTimestamp();
701 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
702
703 if (!_randomTest) {
704 myEvent->StartTimer(true, 30);
705 int n = 0;
706 int settlePoint = 5000;
707 while (n < settlePoint + 400) {
708 myEvent->Wait(1000);
709
710 inTimestamp = myChannel->LastInTimestamp();
711 CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
712
713 //std::cout << outTimestamp << std::endl << std::flush;
714 estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
715 / ((double) myACM->ReceiveFrequency() / 1000.0);
716
717 estimDelayCB.Update(estimDelay);
718
719 estimDelayCB.ArithMean(averageEstimDelay);
720 //printf("\n %6.1f \n", estimDelay);
721 //std::cout << " " << std::flush;
722
723 if (_verbose) {
724 fprintf(stdout,
725 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
726 *myMinDelay, averageDelay, averageEstimDelay);
727 std::cout << " " << std::flush;
728 }
729 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
730 settlePoint = n;
731 }
732 n++;
733 }
734 myEvent->StopTimer();
735 }
736
737 if ((!_verbose) && (!_randomTest)) {
738 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
739 *myMinDelay, averageDelay, averageEstimDelay);
740 }
741
742 *myMinDelay = (rand() % 1000) + 1;
743
744 NetworkStatistics networkStat;
745 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
746
747 if (!_randomTest) {
748 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
749 fprintf(stdout, "--------------------------------------\n");
750 fprintf(stdout, "buffer-size............. %d\n",
751 networkStat.currentBufferSize);
752 fprintf(stdout, "Preferred buffer-size... %d\n",
753 networkStat.preferredBufferSize);
754 fprintf(stdout, "Peaky jitter mode........%d\n",
755 networkStat.jitterPeaksFound);
756 fprintf(stdout, "packet-size rate........ %d\n",
757 networkStat.currentPacketLossRate);
758 fprintf(stdout, "discard rate............ %d\n",
759 networkStat.currentDiscardRate);
760 fprintf(stdout, "expand rate............. %d\n",
761 networkStat.currentExpandRate);
762 fprintf(stdout, "speech expand rate...... %d\n",
763 networkStat.currentSpeechExpandRate);
764 fprintf(stdout, "Preemptive rate......... %d\n",
765 networkStat.currentPreemptiveRate);
766 fprintf(stdout, "Accelerate rate......... %d\n",
767 networkStat.currentAccelerateRate);
768 fprintf(stdout, "Secondary decoded rate.. %d\n",
769 networkStat.currentSecondaryDecodedRate);
770 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
771 fprintf(stdout, "Mean waiting time....... %d\n",
772 networkStat.meanWaitingTimeMs);
773 fprintf(stdout, "Median waiting time..... %d\n",
774 networkStat.medianWaitingTimeMs);
775 fprintf(stdout, "Min waiting time........ %d\n",
776 networkStat.minWaitingTimeMs);
777 fprintf(stdout, "Max waiting time........ %d\n",
778 networkStat.maxWaitingTimeMs);
779 }
780
781 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
782
783 if (!_randomTest) {
784 myEvent->Wait(500);
785 fprintf(stdout, "\n");
786 fprintf(stdout, "\n");
787 }
788 delete myEvent;
789 }
790
791 // Unregister a codec & register again.
792 void APITest::TestRegisteration(char sendSide) {
793 AudioCodingModule* sendACM;
794 AudioCodingModule* receiveACM;
795 bool* thereIsDecoder;
796 EventWrapper* myEvent = EventWrapper::Create();
797
798 if (!_randomTest) {
799 fprintf(stdout, "\n\n");
800 fprintf(stdout,
801 "---------------------------------------------------------\n");
802 fprintf(stdout, " Unregister/register Receive Codec\n");
803 fprintf(stdout,
804 "---------------------------------------------------------\n");
805 }
806
807 switch (sendSide) {
808 case 'A': {
809 sendACM = _acmA.get();
810 receiveACM = _acmB.get();
811 thereIsDecoder = &_thereIsDecoderB;
812 break;
813 }
814 case 'B': {
815 sendACM = _acmB.get();
816 receiveACM = _acmA.get();
817 thereIsDecoder = &_thereIsDecoderA;
818 break;
819 }
820 default:
821 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
822 sendSide);
823 exit(-1);
824 }
825
826 auto myCodec = sendACM->SendCodec();
827 if (!myCodec) {
828 CodecInst ci;
829 AudioCodingModule::Codec(_codecCntrA, &ci);
830 myCodec = rtc::Optional<CodecInst>(ci);
831 }
832
833 if (!_randomTest) {
834 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
835 fflush (stdout);
836 }
837 {
838 WriteLockScoped wl(_apiTestRWLock);
839 *thereIsDecoder = false;
840 }
841 //myEvent->Wait(20);
842 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
843 Wait(1000);
844
845 int currentPayload = myCodec->pltype;
846
847 if (!FixedPayloadTypeCodec(myCodec->plname)) {
848 int32_t i;
849 for (i = 0; i < 32; i++) {
850 if (!_payloadUsed[i]) {
851 if (!_randomTest) {
852 fprintf(stdout,
853 "Register receive codec with new Payload, AUDIO BACK.\n");
854 }
855 //myCodec->pltype = i + 96;
856 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
857 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
858 //myEvent->Wait(20);
859 //{
860 // WriteLockScoped wl(_apiTestRWLock);
861 // *thereIsDecoder = true;
862 //}
863 Wait(1000);
864
865 if (!_randomTest) {
866 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
867 }
868 //{
869 // WriteLockScoped wl(_apiTestRWLock);
870 // *thereIsDecoder = false;
871 //}
872 //myEvent->Wait(20);
873 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
874 Wait(1000);
875
876 myCodec->pltype = currentPayload;
877 if (!_randomTest) {
878 fprintf(stdout,
879 "Register receive codec with default Payload, AUDIO BACK.\n");
880 fflush (stdout);
881 }
882 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
883 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
884 myEvent->Wait(20);
885 {
886 WriteLockScoped wl(_apiTestRWLock);
887 *thereIsDecoder = true;
888 }
889 Wait(1000);
890
891 break;
892 }
893 }
894 if (i == 32) {
895 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
896 {
897 WriteLockScoped wl(_apiTestRWLock);
898 *thereIsDecoder = true;
899 }
900 }
901 } else {
902 if (!_randomTest) {
903 fprintf(stdout,
904 "Register receive codec with fixed Payload, AUDIO BACK.\n");
905 fflush (stdout);
906 }
907 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
908 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
909 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
910 myEvent->Wait(20);
911 {
912 WriteLockScoped wl(_apiTestRWLock);
913 *thereIsDecoder = true;
914 }
915 }
916 delete myEvent;
917 if (!_randomTest) {
918 fprintf(stdout,
919 "---------------------------------------------------------\n");
920 }
921 }
922
923 void APITest::TestSendVAD(char side) {
924 if (_randomTest) {
925 return;
926 }
927
928 bool* vad;
929 bool* dtx;
930 ACMVADMode* mode;
931 Channel* myChannel;
932 AudioCodingModule* myACM;
933
934 CodecInst myCodec;
935 if (!_randomTest) {
936 fprintf(stdout, "\n\n");
937 fprintf(stdout, "-----------------------------------------------\n");
938 fprintf(stdout, " Test VAD API\n");
939 fprintf(stdout, "-----------------------------------------------\n");
940 }
941
942 if (side == 'A') {
943 AudioCodingModule::Codec(_codecCntrA, &myCodec);
944 vad = &_sendVADA;
945 dtx = &_sendDTXA;
946 mode = &_sendVADModeA;
947 myChannel = _channel_A2B;
948 myACM = _acmA.get();
949 } else {
950 AudioCodingModule::Codec(_codecCntrB, &myCodec);
951 vad = &_sendVADB;
952 dtx = &_sendDTXB;
953 mode = &_sendVADModeB;
954 myChannel = _channel_B2A;
955 myACM = _acmB.get();
956 }
957
958 CheckVADStatus(side);
959 if (!_randomTest) {
960 fprintf(stdout, "\n\n");
961 }
962
963 switch (*mode) {
964 case VADNormal:
965 *vad = true;
966 *dtx = true;
967 *mode = VADAggr;
968 break;
969 case VADLowBitrate:
970 *vad = true;
971 *dtx = true;
972 *mode = VADVeryAggr;
973 break;
974 case VADAggr:
975 *vad = true;
976 *dtx = true;
977 *mode = VADLowBitrate;
978 break;
979 case VADVeryAggr:
980 *vad = false;
981 *dtx = false;
982 *mode = VADNormal;
983 break;
984 default:
985 *mode = VADNormal;
986 }
987
988 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
989
990 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
991 myChannel->ResetStats();
992
993 CheckVADStatus(side);
994 if (!_randomTest) {
995 fprintf(stdout, "\n");
996 fprintf(stdout, "-----------------------------------------------\n");
997 }
998
999 // Fault Test
1000 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1001 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
1002
1003 }
1004
1005 void APITest::CurrentCodec(char side) {
1006 auto myCodec = (side == 'A' ? _acmA : _acmB)->SendCodec();
1007
1008 if (!_randomTest) {
1009 fprintf(stdout, "\n\n");
1010 fprintf(stdout, "Send codec in Side A\n");
1011 fprintf(stdout, "----------------------------\n");
1012 fprintf(stdout, "Name................. %s\n", myCodec->plname);
1013 fprintf(stdout, "Sampling Frequency... %d\n", myCodec->plfreq);
1014 fprintf(stdout, "Rate................. %d\n", myCodec->rate);
1015 fprintf(stdout, "Payload-type......... %d\n", myCodec->pltype);
1016 fprintf(stdout, "Packet-size.......... %d\n", myCodec->pacsize);
1017 }
1018
1019 Wait(100);
1020 }
1021
1022 void APITest::ChangeCodec(char side) {
1023 CodecInst myCodec;
1024 AudioCodingModule* myACM;
1025 uint8_t* codecCntr;
1026 bool* thereIsEncoder;
1027 bool* vad;
1028 bool* dtx;
1029 ACMVADMode* mode;
1030 Channel* myChannel;
1031 // Reset and Wait
1032 if (!_randomTest) {
1033 fprintf(stdout, "Reset Encoder Side A \n");
1034 }
1035 if (side == 'A') {
1036 myACM = _acmA.get();
1037 codecCntr = &_codecCntrA;
1038 {
1039 WriteLockScoped wl(_apiTestRWLock);
1040 thereIsEncoder = &_thereIsEncoderA;
1041 }
1042 vad = &_sendVADA;
1043 dtx = &_sendDTXA;
1044 mode = &_sendVADModeA;
1045 myChannel = _channel_A2B;
1046 } else {
1047 myACM = _acmB.get();
1048 codecCntr = &_codecCntrB;
1049 {
1050 WriteLockScoped wl(_apiTestRWLock);
1051 thereIsEncoder = &_thereIsEncoderB;
1052 }
1053 vad = &_sendVADB;
1054 dtx = &_sendDTXB;
1055 mode = &_sendVADModeB;
1056 myChannel = _channel_B2A;
1057 }
1058
1059 Wait(100);
1060
1061 // Register the next codec
1062 do {
1063 *codecCntr =
1064 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1065 (*codecCntr + 1) : 0;
1066
1067 if (*codecCntr == 0) {
1068 //printf("Initialize Sender Side A \n");
1069 {
1070 WriteLockScoped wl(_apiTestRWLock);
1071 *thereIsEncoder = false;
1072 }
1073 // After Initialization CN is lost, re-register them
1074 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1075 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1076 }
1077 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1078 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1079 }
1080 // VAD & DTX are disabled after initialization
1081 *vad = false;
1082 *dtx = false;
1083 _writeToFile = false;
1084 }
1085
1086 AudioCodingModule::Codec(*codecCntr, &myCodec);
1087 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1088 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1089 || !STR_CASE_CMP(myCodec.plname, "RED"));
1090
1091 if (!_randomTest) {
1092 fprintf(stdout,"\n=====================================================\n");
1093 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1094 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1095 }
1096 //std::cout<< std::flush;
1097
1098 // NO DTX for supe-wideband codec at this point
1099 if (myCodec.plfreq == 32000) {
1100 *dtx = false;
1101 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1102
1103 }
1104
1105 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1106 myChannel->ResetStats();
1107 {
1108 WriteLockScoped wl(_apiTestRWLock);
1109 *thereIsEncoder = true;
1110 }
1111 Wait(500);
1112 }
1113
1114 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/test/APITest.h ('k') | webrtc/modules/audio_coding/main/test/Channel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698