| Index: webrtc/modules/audio_coding/main/test/APITest.cc
|
| diff --git a/webrtc/modules/audio_coding/main/test/APITest.cc b/webrtc/modules/audio_coding/main/test/APITest.cc
|
| deleted file mode 100644
|
| index 88ad7e2a76af2c79c9e4bc5f3ec393f2560d4752..0000000000000000000000000000000000000000
|
| --- a/webrtc/modules/audio_coding/main/test/APITest.cc
|
| +++ /dev/null
|
| @@ -1,1114 +0,0 @@
|
| -/*
|
| - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license
|
| - * that can be found in the LICENSE file in the root of the source
|
| - * tree. An additional intellectual property rights grant can be found
|
| - * in the file PATENTS. All contributing project authors may
|
| - * be found in the AUTHORS file in the root of the source tree.
|
| - */
|
| -
|
| -#include "webrtc/modules/audio_coding/main/test/APITest.h"
|
| -
|
| -#include <ctype.h>
|
| -#include <stdio.h>
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| -
|
| -#include <iostream>
|
| -#include <ostream>
|
| -#include <string>
|
| -
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "webrtc/base/platform_thread.h"
|
| -#include "webrtc/common.h"
|
| -#include "webrtc/common_types.h"
|
| -#include "webrtc/engine_configurations.h"
|
| -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
|
| -#include "webrtc/modules/audio_coding/main/test/utility.h"
|
| -#include "webrtc/system_wrappers/include/event_wrapper.h"
|
| -#include "webrtc/system_wrappers/include/tick_util.h"
|
| -#include "webrtc/system_wrappers/include/trace.h"
|
| -#include "webrtc/test/testsupport/fileutils.h"
|
| -
|
| -namespace webrtc {
|
| -
|
| -#define TEST_DURATION_SEC 600
|
| -#define NUMBER_OF_SENDER_TESTS 6
|
| -#define MAX_FILE_NAME_LENGTH_BYTE 500
|
| -#define CHECK_THREAD_NULLITY(myThread, S) \
|
| - if(myThread != NULL) { \
|
| - (myThread)->Start(); \
|
| - } else { \
|
| - ADD_FAILURE() << S; \
|
| - }
|
| -
|
| -void APITest::Wait(uint32_t waitLengthMs) {
|
| - if (_randomTest) {
|
| - return;
|
| - } else {
|
| - EventWrapper* myEvent = EventWrapper::Create();
|
| - myEvent->Wait(waitLengthMs);
|
| - delete myEvent;
|
| - return;
|
| - }
|
| -}
|
| -
|
| -APITest::APITest(const Config& config)
|
| - : _acmA(AudioCodingModule::Create(1)),
|
| - _acmB(AudioCodingModule::Create(2)),
|
| - _channel_A2B(NULL),
|
| - _channel_B2A(NULL),
|
| - _writeToFile(true),
|
| - _pullEventA(NULL),
|
| - _pushEventA(NULL),
|
| - _processEventA(NULL),
|
| - _apiEventA(NULL),
|
| - _pullEventB(NULL),
|
| - _pushEventB(NULL),
|
| - _processEventB(NULL),
|
| - _apiEventB(NULL),
|
| - _codecCntrA(0),
|
| - _codecCntrB(0),
|
| - _thereIsEncoderA(false),
|
| - _thereIsEncoderB(false),
|
| - _thereIsDecoderA(false),
|
| - _thereIsDecoderB(false),
|
| - _sendVADA(false),
|
| - _sendDTXA(false),
|
| - _sendVADModeA(VADNormal),
|
| - _sendVADB(false),
|
| - _sendDTXB(false),
|
| - _sendVADModeB(VADNormal),
|
| - _minDelayA(0),
|
| - _minDelayB(0),
|
| - _dotPositionA(0),
|
| - _dotMoveDirectionA(1),
|
| - _dotPositionB(39),
|
| - _dotMoveDirectionB(-1),
|
| - _vadCallbackA(NULL),
|
| - _vadCallbackB(NULL),
|
| - _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
|
| - _randomTest(false),
|
| - _testNumA(0),
|
| - _testNumB(1) {
|
| - int n;
|
| - for (n = 0; n < 32; n++) {
|
| - _payloadUsed[n] = false;
|
| - }
|
| -
|
| - _movingDot[40] = '\0';
|
| -
|
| - for (int n = 0; n < 40; n++) {
|
| - _movingDot[n] = ' ';
|
| - }
|
| -}
|
| -
|
| -APITest::~APITest() {
|
| - DELETE_POINTER(_channel_A2B);
|
| - DELETE_POINTER(_channel_B2A);
|
| -
|
| - DELETE_POINTER(_pushEventA);
|
| - DELETE_POINTER(_pullEventA);
|
| - DELETE_POINTER(_processEventA);
|
| - DELETE_POINTER(_apiEventA);
|
| -
|
| - DELETE_POINTER(_pushEventB);
|
| - DELETE_POINTER(_pullEventB);
|
| - DELETE_POINTER(_processEventB);
|
| - DELETE_POINTER(_apiEventB);
|
| -
|
| - _inFileA.Close();
|
| - _outFileA.Close();
|
| -
|
| - _inFileB.Close();
|
| - _outFileB.Close();
|
| -
|
| - DELETE_POINTER(_vadCallbackA);
|
| - DELETE_POINTER(_vadCallbackB);
|
| -
|
| - delete &_apiTestRWLock;
|
| -}
|
| -
|
| -int16_t APITest::SetUp() {
|
| - CodecInst dummyCodec;
|
| - int lastPayloadType = 0;
|
| -
|
| - int16_t numCodecs = _acmA->NumberOfCodecs();
|
| - for (uint8_t n = 0; n < numCodecs; n++) {
|
| - AudioCodingModule::Codec(n, &dummyCodec);
|
| - if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
|
| - && (dummyCodec.plfreq == 32000)) {
|
| - continue;
|
| - }
|
| -
|
| - printf("Register Receive Codec %s ", dummyCodec.plname);
|
| -
|
| - if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
|
| - // Check registration with an already occupied payload type
|
| - int currentPayloadType = dummyCodec.pltype;
|
| - dummyCodec.pltype = 97; //lastPayloadType;
|
| - CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
|
| - dummyCodec.pltype = currentPayloadType;
|
| - }
|
| -
|
| - if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
|
| - // test if re-registration works;
|
| - CodecInst nextCodec;
|
| - int currentPayloadType = dummyCodec.pltype;
|
| - AudioCodingModule::Codec(n + 1, &nextCodec);
|
| - dummyCodec.pltype = nextCodec.pltype;
|
| - if (!FixedPayloadTypeCodec(nextCodec.plname)) {
|
| - _acmB->RegisterReceiveCodec(dummyCodec);
|
| - }
|
| - dummyCodec.pltype = currentPayloadType;
|
| - }
|
| -
|
| - if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
|
| - // test if un-registration works;
|
| - CodecInst nextCodec;
|
| - AudioCodingModule::Codec(n + 1, &nextCodec);
|
| - nextCodec.pltype = dummyCodec.pltype;
|
| - if (!FixedPayloadTypeCodec(nextCodec.plname)) {
|
| - CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
|
| - CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
|
| - }
|
| - }
|
| -
|
| - CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
|
| - printf(" side A done!");
|
| - CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
|
| - printf(" side B done!\n");
|
| -
|
| - if (!strcmp(dummyCodec.plname, "CN")) {
|
| - CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
|
| - CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
|
| - }
|
| - lastPayloadType = dummyCodec.pltype;
|
| - if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
|
| - _payloadUsed[lastPayloadType - 96] = true;
|
| - }
|
| - }
|
| - _thereIsDecoderA = true;
|
| - _thereIsDecoderB = true;
|
| -
|
| - // Register Send Codec
|
| - AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
|
| - CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
|
| - _thereIsEncoderA = true;
|
| - //
|
| - AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
|
| - CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
|
| - _thereIsEncoderB = true;
|
| -
|
| - uint16_t frequencyHz;
|
| -
|
| - printf("\n\nAPI Test\n");
|
| - printf("========\n");
|
| - printf("Hit enter to accept the default values indicated in []\n\n");
|
| -
|
| - //--- Input A
|
| - std::string file_name = webrtc::test::ResourcePath(
|
| - "audio_coding/testfile32kHz", "pcm");
|
| - frequencyHz = 32000;
|
| - printf("Enter input file at side A [%s]: ", file_name.c_str());
|
| - PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
|
| - _inFileA.Open(file_name, frequencyHz, "rb", true);
|
| -
|
| - //--- Output A
|
| - std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
|
| - printf("Enter output file at side A [%s]: ", out_file_a.c_str());
|
| - PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
|
| - _outFileA.Open(out_file_a, frequencyHz, "wb");
|
| -
|
| - //--- Input B
|
| - file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
|
| - printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
|
| - PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
|
| - _inFileB.Open(file_name, frequencyHz, "rb", true);
|
| -
|
| - //--- Output B
|
| - std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
|
| - printf("Enter output file at side B [%s]: ", out_file_b.c_str());
|
| - PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
|
| - _outFileB.Open(out_file_b, frequencyHz, "wb");
|
| -
|
| - //--- Set A-to-B channel
|
| - _channel_A2B = new Channel(2);
|
| - CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
|
| - _channel_A2B->RegisterReceiverACM(_acmB.get());
|
| -
|
| - //--- Set B-to-A channel
|
| - _channel_B2A = new Channel(1);
|
| - CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
|
| - _channel_B2A->RegisterReceiverACM(_acmA.get());
|
| -
|
| - //--- EVENT TIMERS
|
| - // A
|
| - _pullEventA = EventTimerWrapper::Create();
|
| - _pushEventA = EventTimerWrapper::Create();
|
| - _processEventA = EventTimerWrapper::Create();
|
| - _apiEventA = EventWrapper::Create();
|
| - // B
|
| - _pullEventB = EventTimerWrapper::Create();
|
| - _pushEventB = EventTimerWrapper::Create();
|
| - _processEventB = EventTimerWrapper::Create();
|
| - _apiEventB = EventWrapper::Create();
|
| -
|
| - //--- I/O params
|
| - // A
|
| - _outFreqHzA = _outFileA.SamplingFrequency();
|
| - // B
|
| - _outFreqHzB = _outFileB.SamplingFrequency();
|
| -
|
| - //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
|
| -
|
| - char print[11];
|
| -
|
| - // Create a trace file.
|
| - Trace::CreateTrace();
|
| - Trace::SetTraceFile(
|
| - (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
|
| -
|
| - printf("\nRandom Test (y/n)?");
|
| - EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
|
| - print[10] = '\0';
|
| - if (strstr(print, "y") != NULL) {
|
| - _randomTest = true;
|
| - _verbose = false;
|
| - _writeToFile = false;
|
| - } else {
|
| - _randomTest = false;
|
| - printf("\nPrint Tests (y/n)? ");
|
| - EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
|
| - print[10] = '\0';
|
| - if (strstr(print, "y") == NULL) {
|
| - EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
|
| - _verbose = false;
|
| - }
|
| - }
|
| -
|
| - _vadCallbackA = new VADCallback;
|
| - _vadCallbackB = new VADCallback;
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -bool APITest::PushAudioThreadA(void* obj) {
|
| - return static_cast<APITest*>(obj)->PushAudioRunA();
|
| -}
|
| -
|
| -bool APITest::PushAudioThreadB(void* obj) {
|
| - return static_cast<APITest*>(obj)->PushAudioRunB();
|
| -}
|
| -
|
| -bool APITest::PullAudioThreadA(void* obj) {
|
| - return static_cast<APITest*>(obj)->PullAudioRunA();
|
| -}
|
| -
|
| -bool APITest::PullAudioThreadB(void* obj) {
|
| - return static_cast<APITest*>(obj)->PullAudioRunB();
|
| -}
|
| -
|
| -bool APITest::ProcessThreadA(void* obj) {
|
| - return static_cast<APITest*>(obj)->ProcessRunA();
|
| -}
|
| -
|
| -bool APITest::ProcessThreadB(void* obj) {
|
| - return static_cast<APITest*>(obj)->ProcessRunB();
|
| -}
|
| -
|
| -bool APITest::APIThreadA(void* obj) {
|
| - return static_cast<APITest*>(obj)->APIRunA();
|
| -}
|
| -
|
| -bool APITest::APIThreadB(void* obj) {
|
| - return static_cast<APITest*>(obj)->APIRunB();
|
| -}
|
| -
|
| -bool APITest::PullAudioRunA() {
|
| - _pullEventA->Wait(100);
|
| - AudioFrame audioFrame;
|
| - if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0) {
|
| - bool thereIsDecoder;
|
| - {
|
| - ReadLockScoped rl(_apiTestRWLock);
|
| - thereIsDecoder = _thereIsDecoderA;
|
| - }
|
| - if (thereIsDecoder) {
|
| - fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
|
| - }
|
| - } else {
|
| - if (_writeToFile) {
|
| - _outFileA.Write10MsData(audioFrame);
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool APITest::PullAudioRunB() {
|
| - _pullEventB->Wait(100);
|
| - AudioFrame audioFrame;
|
| - if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0) {
|
| - bool thereIsDecoder;
|
| - {
|
| - ReadLockScoped rl(_apiTestRWLock);
|
| - thereIsDecoder = _thereIsDecoderB;
|
| - }
|
| - if (thereIsDecoder) {
|
| - fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
|
| - fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
|
| - }
|
| - } else {
|
| - if (_writeToFile) {
|
| - _outFileB.Write10MsData(audioFrame);
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool APITest::PushAudioRunA() {
|
| - _pushEventA->Wait(100);
|
| - AudioFrame audioFrame;
|
| - _inFileA.Read10MsData(audioFrame);
|
| - if (_acmA->Add10MsData(audioFrame) < 0) {
|
| - bool thereIsEncoder;
|
| - {
|
| - ReadLockScoped rl(_apiTestRWLock);
|
| - thereIsEncoder = _thereIsEncoderA;
|
| - }
|
| - if (thereIsEncoder) {
|
| - fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool APITest::PushAudioRunB() {
|
| - _pushEventB->Wait(100);
|
| - AudioFrame audioFrame;
|
| - _inFileB.Read10MsData(audioFrame);
|
| - if (_acmB->Add10MsData(audioFrame) < 0) {
|
| - bool thereIsEncoder;
|
| - {
|
| - ReadLockScoped rl(_apiTestRWLock);
|
| - thereIsEncoder = _thereIsEncoderB;
|
| - }
|
| -
|
| - if (thereIsEncoder) {
|
| - fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
|
| - }
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool APITest::ProcessRunA() {
|
| - _processEventA->Wait(100);
|
| - return true;
|
| -}
|
| -
|
| -bool APITest::ProcessRunB() {
|
| - _processEventB->Wait(100);
|
| - return true;
|
| -}
|
| -
|
| -/*/
|
| - *
|
| - * In side A we test the APIs which are related to sender Side.
|
| - *
|
| -/*/
|
| -
|
| -void APITest::RunTest(char thread) {
|
| - int testNum;
|
| - {
|
| - WriteLockScoped cs(_apiTestRWLock);
|
| - if (thread == 'A') {
|
| - _testNumA = (_testNumB + 1 + (rand() % 3)) % 4;
|
| - testNum = _testNumA;
|
| -
|
| - _movingDot[_dotPositionA] = ' ';
|
| - if (_dotPositionA == 0) {
|
| - _dotMoveDirectionA = 1;
|
| - }
|
| - if (_dotPositionA == 19) {
|
| - _dotMoveDirectionA = -1;
|
| - }
|
| - _dotPositionA += _dotMoveDirectionA;
|
| - _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
|
| - } else {
|
| - _testNumB = (_testNumA + 1 + (rand() % 3)) % 4;
|
| - testNum = _testNumB;
|
| -
|
| - _movingDot[_dotPositionB] = ' ';
|
| - if (_dotPositionB == 20) {
|
| - _dotMoveDirectionB = 1;
|
| - }
|
| - if (_dotPositionB == 39) {
|
| - _dotMoveDirectionB = -1;
|
| - }
|
| - _dotPositionB += _dotMoveDirectionB;
|
| - _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
|
| - }
|
| - //fprintf(stderr, "%c: %d \n", thread, testNum);
|
| - //fflush(stderr);
|
| - }
|
| - switch (testNum) {
|
| - case 0:
|
| - CurrentCodec('A');
|
| - ChangeCodec('A');
|
| - break;
|
| - case 1:
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "\nTesting Delay ...\n");
|
| - }
|
| - TestDelay('A');
|
| - break;
|
| - case 2:
|
| - TestSendVAD('A');
|
| - break;
|
| - case 3:
|
| - TestRegisteration('A');
|
| - break;
|
| - default:
|
| - fprintf(stderr, "Wrong Test Number\n");
|
| - getc(stdin);
|
| - exit(1);
|
| - }
|
| -}
|
| -
|
| -bool APITest::APIRunA() {
|
| - _apiEventA->Wait(50);
|
| -
|
| - bool randomTest;
|
| - {
|
| - ReadLockScoped rl(_apiTestRWLock);
|
| - randomTest = _randomTest;
|
| - }
|
| - if (randomTest) {
|
| - RunTest('A');
|
| - } else {
|
| - CurrentCodec('A');
|
| - ChangeCodec('A');
|
| - if (_codecCntrA == 0) {
|
| - fprintf(stdout, "\nTesting Delay ...\n");
|
| - TestDelay('A');
|
| - }
|
| - // VAD TEST
|
| - TestSendVAD('A');
|
| - TestRegisteration('A');
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool APITest::APIRunB() {
|
| - _apiEventB->Wait(50);
|
| - bool randomTest;
|
| - {
|
| - ReadLockScoped rl(_apiTestRWLock);
|
| - randomTest = _randomTest;
|
| - }
|
| - //_apiEventB->Wait(2000);
|
| - if (randomTest) {
|
| - RunTest('B');
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void APITest::Perform() {
|
| - SetUp();
|
| -
|
| - //--- THREADS
|
| - // A
|
| - // PUSH
|
| - rtc::scoped_ptr<PlatformThread> myPushAudioThreadA =
|
| - PlatformThread::CreateThread(PushAudioThreadA, this, "PushAudioThreadA");
|
| - CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
|
| - // PULL
|
| - rtc::scoped_ptr<PlatformThread> myPullAudioThreadA =
|
| - PlatformThread::CreateThread(PullAudioThreadA, this, "PullAudioThreadA");
|
| - CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
|
| - // Process
|
| - rtc::scoped_ptr<PlatformThread> myProcessThreadA =
|
| - PlatformThread::CreateThread(ProcessThreadA, this, "ProcessThreadA");
|
| - CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
|
| - // API
|
| - rtc::scoped_ptr<PlatformThread> myAPIThreadA =
|
| - PlatformThread::CreateThread(APIThreadA, this, "APIThreadA");
|
| - CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
|
| - // B
|
| - // PUSH
|
| - rtc::scoped_ptr<PlatformThread> myPushAudioThreadB =
|
| - PlatformThread::CreateThread(PushAudioThreadB, this, "PushAudioThreadB");
|
| - CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
|
| - // PULL
|
| - rtc::scoped_ptr<PlatformThread> myPullAudioThreadB =
|
| - PlatformThread::CreateThread(PullAudioThreadB, this, "PullAudioThreadB");
|
| - CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
|
| - // Process
|
| - rtc::scoped_ptr<PlatformThread> myProcessThreadB =
|
| - PlatformThread::CreateThread(ProcessThreadB, this, "ProcessThreadB");
|
| - CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
|
| - // API
|
| - rtc::scoped_ptr<PlatformThread> myAPIThreadB =
|
| - PlatformThread::CreateThread(APIThreadB, this, "APIThreadB");
|
| - CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
|
| -
|
| - //_apiEventA->StartTimer(true, 5000);
|
| - //_apiEventB->StartTimer(true, 5000);
|
| -
|
| - _processEventA->StartTimer(true, 10);
|
| - _processEventB->StartTimer(true, 10);
|
| -
|
| - _pullEventA->StartTimer(true, 10);
|
| - _pullEventB->StartTimer(true, 10);
|
| -
|
| - _pushEventA->StartTimer(true, 10);
|
| - _pushEventB->StartTimer(true, 10);
|
| -
|
| - // Keep main thread waiting for sender/receiver
|
| - // threads to complete
|
| - EventWrapper* completeEvent = EventWrapper::Create();
|
| - uint64_t startTime = TickTime::MillisecondTimestamp();
|
| - uint64_t currentTime;
|
| - // Run test in 2 minutes (120000 ms).
|
| - do {
|
| - {
|
| - //ReadLockScoped rl(_apiTestRWLock);
|
| - //fprintf(stderr, "\r%s", _movingDot);
|
| - }
|
| - //fflush(stderr);
|
| - completeEvent->Wait(50);
|
| - currentTime = TickTime::MillisecondTimestamp();
|
| - } while ((currentTime - startTime) < 120000);
|
| -
|
| - //completeEvent->Wait(0xFFFFFFFF);
|
| - //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
|
| - delete completeEvent;
|
| -
|
| - myPushAudioThreadA->Stop();
|
| - myPullAudioThreadA->Stop();
|
| - myProcessThreadA->Stop();
|
| - myAPIThreadA->Stop();
|
| -
|
| - myPushAudioThreadB->Stop();
|
| - myPullAudioThreadB->Stop();
|
| - myProcessThreadB->Stop();
|
| - myAPIThreadB->Stop();
|
| -}
|
| -
|
| -void APITest::CheckVADStatus(char side) {
|
| -
|
| - bool dtxEnabled;
|
| - bool vadEnabled;
|
| - ACMVADMode vadMode;
|
| -
|
| - if (side == 'A') {
|
| - _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
|
| - _acmA->RegisterVADCallback(NULL);
|
| - _vadCallbackA->Reset();
|
| - _acmA->RegisterVADCallback(_vadCallbackA);
|
| -
|
| - if (!_randomTest) {
|
| - if (_verbose) {
|
| - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
|
| - vadEnabled ? "ON" : "OFF", (int) vadMode);
|
| - Wait(5000);
|
| - fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
|
| - } else {
|
| - Wait(5000);
|
| - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
|
| - dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
|
| - (int) vadMode, _channel_A2B->BitRate());
|
| - }
|
| - _vadCallbackA->PrintFrameTypes();
|
| - }
|
| -
|
| - if (dtxEnabled != _sendDTXA) {
|
| - fprintf(stderr, ">>> Error Enabling DTX <<<\n");
|
| - }
|
| - if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
|
| - fprintf(stderr, ">>> Error Enabling VAD <<<\n");
|
| - }
|
| - if ((vadMode != _sendVADModeA) && vadEnabled) {
|
| - fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
|
| - }
|
| - } else {
|
| - _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
|
| -
|
| - _acmB->RegisterVADCallback(NULL);
|
| - _vadCallbackB->Reset();
|
| - _acmB->RegisterVADCallback(_vadCallbackB);
|
| -
|
| - if (!_randomTest) {
|
| - if (_verbose) {
|
| - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
|
| - vadEnabled ? "ON" : "OFF", (int) vadMode);
|
| - Wait(5000);
|
| - fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
|
| - } else {
|
| - Wait(5000);
|
| - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
|
| - dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
|
| - (int) vadMode, _channel_B2A->BitRate());
|
| - }
|
| - _vadCallbackB->PrintFrameTypes();
|
| - }
|
| -
|
| - if (dtxEnabled != _sendDTXB) {
|
| - fprintf(stderr, ">>> Error Enabling DTX <<<\n");
|
| - }
|
| - if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
|
| - fprintf(stderr, ">>> Error Enabling VAD <<<\n");
|
| - }
|
| - if ((vadMode != _sendVADModeB) && vadEnabled) {
|
| - fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Set Min delay, get delay, playout timestamp
|
| -void APITest::TestDelay(char side) {
|
| - AudioCodingModule* myACM;
|
| - Channel* myChannel;
|
| - int32_t* myMinDelay;
|
| - EventTimerWrapper* myEvent = EventTimerWrapper::Create();
|
| -
|
| - uint32_t inTimestamp = 0;
|
| - uint32_t outTimestamp = 0;
|
| - double estimDelay = 0;
|
| -
|
| - double averageEstimDelay = 0;
|
| - double averageDelay = 0;
|
| -
|
| - CircularBuffer estimDelayCB(100);
|
| - estimDelayCB.SetArithMean(true);
|
| -
|
| - if (side == 'A') {
|
| - myACM = _acmA.get();
|
| - myChannel = _channel_B2A;
|
| - myMinDelay = &_minDelayA;
|
| - } else {
|
| - myACM = _acmB.get();
|
| - myChannel = _channel_A2B;
|
| - myMinDelay = &_minDelayB;
|
| - }
|
| -
|
| - CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
|
| -
|
| - inTimestamp = myChannel->LastInTimestamp();
|
| - CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
|
| -
|
| - if (!_randomTest) {
|
| - myEvent->StartTimer(true, 30);
|
| - int n = 0;
|
| - int settlePoint = 5000;
|
| - while (n < settlePoint + 400) {
|
| - myEvent->Wait(1000);
|
| -
|
| - inTimestamp = myChannel->LastInTimestamp();
|
| - CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp));
|
| -
|
| - //std::cout << outTimestamp << std::endl << std::flush;
|
| - estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp))
|
| - / ((double) myACM->ReceiveFrequency() / 1000.0);
|
| -
|
| - estimDelayCB.Update(estimDelay);
|
| -
|
| - estimDelayCB.ArithMean(averageEstimDelay);
|
| - //printf("\n %6.1f \n", estimDelay);
|
| - //std::cout << " " << std::flush;
|
| -
|
| - if (_verbose) {
|
| - fprintf(stdout,
|
| - "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
|
| - *myMinDelay, averageDelay, averageEstimDelay);
|
| - std::cout << " " << std::flush;
|
| - }
|
| - if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
|
| - settlePoint = n;
|
| - }
|
| - n++;
|
| - }
|
| - myEvent->StopTimer();
|
| - }
|
| -
|
| - if ((!_verbose) && (!_randomTest)) {
|
| - fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
|
| - *myMinDelay, averageDelay, averageEstimDelay);
|
| - }
|
| -
|
| - *myMinDelay = (rand() % 1000) + 1;
|
| -
|
| - NetworkStatistics networkStat;
|
| - CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
|
| -
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
|
| - fprintf(stdout, "--------------------------------------\n");
|
| - fprintf(stdout, "buffer-size............. %d\n",
|
| - networkStat.currentBufferSize);
|
| - fprintf(stdout, "Preferred buffer-size... %d\n",
|
| - networkStat.preferredBufferSize);
|
| - fprintf(stdout, "Peaky jitter mode........%d\n",
|
| - networkStat.jitterPeaksFound);
|
| - fprintf(stdout, "packet-size rate........ %d\n",
|
| - networkStat.currentPacketLossRate);
|
| - fprintf(stdout, "discard rate............ %d\n",
|
| - networkStat.currentDiscardRate);
|
| - fprintf(stdout, "expand rate............. %d\n",
|
| - networkStat.currentExpandRate);
|
| - fprintf(stdout, "speech expand rate...... %d\n",
|
| - networkStat.currentSpeechExpandRate);
|
| - fprintf(stdout, "Preemptive rate......... %d\n",
|
| - networkStat.currentPreemptiveRate);
|
| - fprintf(stdout, "Accelerate rate......... %d\n",
|
| - networkStat.currentAccelerateRate);
|
| - fprintf(stdout, "Secondary decoded rate.. %d\n",
|
| - networkStat.currentSecondaryDecodedRate);
|
| - fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
|
| - fprintf(stdout, "Mean waiting time....... %d\n",
|
| - networkStat.meanWaitingTimeMs);
|
| - fprintf(stdout, "Median waiting time..... %d\n",
|
| - networkStat.medianWaitingTimeMs);
|
| - fprintf(stdout, "Min waiting time........ %d\n",
|
| - networkStat.minWaitingTimeMs);
|
| - fprintf(stdout, "Max waiting time........ %d\n",
|
| - networkStat.maxWaitingTimeMs);
|
| - }
|
| -
|
| - CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
|
| -
|
| - if (!_randomTest) {
|
| - myEvent->Wait(500);
|
| - fprintf(stdout, "\n");
|
| - fprintf(stdout, "\n");
|
| - }
|
| - delete myEvent;
|
| -}
|
| -
|
| -// Unregister a codec & register again.
|
| -void APITest::TestRegisteration(char sendSide) {
|
| - AudioCodingModule* sendACM;
|
| - AudioCodingModule* receiveACM;
|
| - bool* thereIsDecoder;
|
| - EventWrapper* myEvent = EventWrapper::Create();
|
| -
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "\n\n");
|
| - fprintf(stdout,
|
| - "---------------------------------------------------------\n");
|
| - fprintf(stdout, " Unregister/register Receive Codec\n");
|
| - fprintf(stdout,
|
| - "---------------------------------------------------------\n");
|
| - }
|
| -
|
| - switch (sendSide) {
|
| - case 'A': {
|
| - sendACM = _acmA.get();
|
| - receiveACM = _acmB.get();
|
| - thereIsDecoder = &_thereIsDecoderB;
|
| - break;
|
| - }
|
| - case 'B': {
|
| - sendACM = _acmB.get();
|
| - receiveACM = _acmA.get();
|
| - thereIsDecoder = &_thereIsDecoderA;
|
| - break;
|
| - }
|
| - default:
|
| - fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
|
| - sendSide);
|
| - exit(-1);
|
| - }
|
| -
|
| - auto myCodec = sendACM->SendCodec();
|
| - if (!myCodec) {
|
| - CodecInst ci;
|
| - AudioCodingModule::Codec(_codecCntrA, &ci);
|
| - myCodec = rtc::Optional<CodecInst>(ci);
|
| - }
|
| -
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
|
| - fflush (stdout);
|
| - }
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - *thereIsDecoder = false;
|
| - }
|
| - //myEvent->Wait(20);
|
| - CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
|
| - Wait(1000);
|
| -
|
| - int currentPayload = myCodec->pltype;
|
| -
|
| - if (!FixedPayloadTypeCodec(myCodec->plname)) {
|
| - int32_t i;
|
| - for (i = 0; i < 32; i++) {
|
| - if (!_payloadUsed[i]) {
|
| - if (!_randomTest) {
|
| - fprintf(stdout,
|
| - "Register receive codec with new Payload, AUDIO BACK.\n");
|
| - }
|
| - //myCodec->pltype = i + 96;
|
| - //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
|
| - //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
|
| - //myEvent->Wait(20);
|
| - //{
|
| - // WriteLockScoped wl(_apiTestRWLock);
|
| - // *thereIsDecoder = true;
|
| - //}
|
| - Wait(1000);
|
| -
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
|
| - }
|
| - //{
|
| - // WriteLockScoped wl(_apiTestRWLock);
|
| - // *thereIsDecoder = false;
|
| - //}
|
| - //myEvent->Wait(20);
|
| - //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
|
| - Wait(1000);
|
| -
|
| - myCodec->pltype = currentPayload;
|
| - if (!_randomTest) {
|
| - fprintf(stdout,
|
| - "Register receive codec with default Payload, AUDIO BACK.\n");
|
| - fflush (stdout);
|
| - }
|
| - CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
|
| - //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
|
| - myEvent->Wait(20);
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - *thereIsDecoder = true;
|
| - }
|
| - Wait(1000);
|
| -
|
| - break;
|
| - }
|
| - }
|
| - if (i == 32) {
|
| - CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - *thereIsDecoder = true;
|
| - }
|
| - }
|
| - } else {
|
| - if (!_randomTest) {
|
| - fprintf(stdout,
|
| - "Register receive codec with fixed Payload, AUDIO BACK.\n");
|
| - fflush (stdout);
|
| - }
|
| - CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
|
| - //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
|
| - //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
|
| - myEvent->Wait(20);
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - *thereIsDecoder = true;
|
| - }
|
| - }
|
| - delete myEvent;
|
| - if (!_randomTest) {
|
| - fprintf(stdout,
|
| - "---------------------------------------------------------\n");
|
| - }
|
| -}
|
| -
|
| -void APITest::TestSendVAD(char side) {
|
| - if (_randomTest) {
|
| - return;
|
| - }
|
| -
|
| - bool* vad;
|
| - bool* dtx;
|
| - ACMVADMode* mode;
|
| - Channel* myChannel;
|
| - AudioCodingModule* myACM;
|
| -
|
| - CodecInst myCodec;
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "\n\n");
|
| - fprintf(stdout, "-----------------------------------------------\n");
|
| - fprintf(stdout, " Test VAD API\n");
|
| - fprintf(stdout, "-----------------------------------------------\n");
|
| - }
|
| -
|
| - if (side == 'A') {
|
| - AudioCodingModule::Codec(_codecCntrA, &myCodec);
|
| - vad = &_sendVADA;
|
| - dtx = &_sendDTXA;
|
| - mode = &_sendVADModeA;
|
| - myChannel = _channel_A2B;
|
| - myACM = _acmA.get();
|
| - } else {
|
| - AudioCodingModule::Codec(_codecCntrB, &myCodec);
|
| - vad = &_sendVADB;
|
| - dtx = &_sendDTXB;
|
| - mode = &_sendVADModeB;
|
| - myChannel = _channel_B2A;
|
| - myACM = _acmB.get();
|
| - }
|
| -
|
| - CheckVADStatus(side);
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "\n\n");
|
| - }
|
| -
|
| - switch (*mode) {
|
| - case VADNormal:
|
| - *vad = true;
|
| - *dtx = true;
|
| - *mode = VADAggr;
|
| - break;
|
| - case VADLowBitrate:
|
| - *vad = true;
|
| - *dtx = true;
|
| - *mode = VADVeryAggr;
|
| - break;
|
| - case VADAggr:
|
| - *vad = true;
|
| - *dtx = true;
|
| - *mode = VADLowBitrate;
|
| - break;
|
| - case VADVeryAggr:
|
| - *vad = false;
|
| - *dtx = false;
|
| - *mode = VADNormal;
|
| - break;
|
| - default:
|
| - *mode = VADNormal;
|
| - }
|
| -
|
| - *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
|
| -
|
| - CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
|
| - myChannel->ResetStats();
|
| -
|
| - CheckVADStatus(side);
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "\n");
|
| - fprintf(stdout, "-----------------------------------------------\n");
|
| - }
|
| -
|
| - // Fault Test
|
| - CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
|
| - CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
|
| -
|
| -}
|
| -
|
| -void APITest::CurrentCodec(char side) {
|
| - auto myCodec = (side == 'A' ? _acmA : _acmB)->SendCodec();
|
| -
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "\n\n");
|
| - fprintf(stdout, "Send codec in Side A\n");
|
| - fprintf(stdout, "----------------------------\n");
|
| - fprintf(stdout, "Name................. %s\n", myCodec->plname);
|
| - fprintf(stdout, "Sampling Frequency... %d\n", myCodec->plfreq);
|
| - fprintf(stdout, "Rate................. %d\n", myCodec->rate);
|
| - fprintf(stdout, "Payload-type......... %d\n", myCodec->pltype);
|
| - fprintf(stdout, "Packet-size.......... %d\n", myCodec->pacsize);
|
| - }
|
| -
|
| - Wait(100);
|
| -}
|
| -
|
| -void APITest::ChangeCodec(char side) {
|
| - CodecInst myCodec;
|
| - AudioCodingModule* myACM;
|
| - uint8_t* codecCntr;
|
| - bool* thereIsEncoder;
|
| - bool* vad;
|
| - bool* dtx;
|
| - ACMVADMode* mode;
|
| - Channel* myChannel;
|
| - // Reset and Wait
|
| - if (!_randomTest) {
|
| - fprintf(stdout, "Reset Encoder Side A \n");
|
| - }
|
| - if (side == 'A') {
|
| - myACM = _acmA.get();
|
| - codecCntr = &_codecCntrA;
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - thereIsEncoder = &_thereIsEncoderA;
|
| - }
|
| - vad = &_sendVADA;
|
| - dtx = &_sendDTXA;
|
| - mode = &_sendVADModeA;
|
| - myChannel = _channel_A2B;
|
| - } else {
|
| - myACM = _acmB.get();
|
| - codecCntr = &_codecCntrB;
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - thereIsEncoder = &_thereIsEncoderB;
|
| - }
|
| - vad = &_sendVADB;
|
| - dtx = &_sendDTXB;
|
| - mode = &_sendVADModeB;
|
| - myChannel = _channel_B2A;
|
| - }
|
| -
|
| - Wait(100);
|
| -
|
| - // Register the next codec
|
| - do {
|
| - *codecCntr =
|
| - (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
|
| - (*codecCntr + 1) : 0;
|
| -
|
| - if (*codecCntr == 0) {
|
| - //printf("Initialize Sender Side A \n");
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - *thereIsEncoder = false;
|
| - }
|
| - // After Initialization CN is lost, re-register them
|
| - if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
|
| - CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
|
| - }
|
| - if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
|
| - CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
|
| - }
|
| - // VAD & DTX are disabled after initialization
|
| - *vad = false;
|
| - *dtx = false;
|
| - _writeToFile = false;
|
| - }
|
| -
|
| - AudioCodingModule::Codec(*codecCntr, &myCodec);
|
| - } while (!STR_CASE_CMP(myCodec.plname, "CN")
|
| - || !STR_CASE_CMP(myCodec.plname, "telephone-event")
|
| - || !STR_CASE_CMP(myCodec.plname, "RED"));
|
| -
|
| - if (!_randomTest) {
|
| - fprintf(stdout,"\n=====================================================\n");
|
| - fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
|
| - myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
|
| - }
|
| - //std::cout<< std::flush;
|
| -
|
| - // NO DTX for supe-wideband codec at this point
|
| - if (myCodec.plfreq == 32000) {
|
| - *dtx = false;
|
| - CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
|
| -
|
| - }
|
| -
|
| - CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
|
| - myChannel->ResetStats();
|
| - {
|
| - WriteLockScoped wl(_apiTestRWLock);
|
| - *thereIsEncoder = true;
|
| - }
|
| - Wait(500);
|
| -}
|
| -
|
| -} // namespace webrtc
|
|
|