blob: 833398acddfd71fc9784b41650542a6c0a2a8cad [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
andrew@webrtc.org63a50982012-05-02 23:56:37 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
kjellander3e6db232015-11-26 04:44:54 -080011#include "webrtc/modules/audio_coding/test/APITest.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <ctype.h>
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000014#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000017
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +000018#include <iostream>
19#include <ostream>
20#include <string>
21
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000022#include "testing/gtest/include/gtest/gtest.h"
pbos12411ef2015-11-23 14:47:56 -080023#include "webrtc/base/platform_thread.h"
Niels Möllerd28db7f2016-05-10 16:31:47 +020024#include "webrtc/base/timeutils.h"
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000025#include "webrtc/common.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000026#include "webrtc/common_types.h"
27#include "webrtc/engine_configurations.h"
kjellander3e6db232015-11-26 04:44:54 -080028#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h"
29#include "webrtc/modules/audio_coding/test/utility.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010030#include "webrtc/system_wrappers/include/event_wrapper.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010031#include "webrtc/system_wrappers/include/trace.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000032#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000033
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000034namespace webrtc {
35
niklase@google.com470e71d2011-07-07 08:21:25 +000036#define TEST_DURATION_SEC 600
niklase@google.com470e71d2011-07-07 08:21:25 +000037#define NUMBER_OF_SENDER_TESTS 6
niklase@google.com470e71d2011-07-07 08:21:25 +000038#define MAX_FILE_NAME_LENGTH_BYTE 500
niklase@google.com470e71d2011-07-07 08:21:25 +000039
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000040void APITest::Wait(uint32_t waitLengthMs) {
41 if (_randomTest) {
42 return;
43 } else {
44 EventWrapper* myEvent = EventWrapper::Create();
45 myEvent->Wait(waitLengthMs);
46 delete myEvent;
47 return;
48 }
niklase@google.com470e71d2011-07-07 08:21:25 +000049}
50
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000051APITest::APITest(const Config& config)
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +000052 : _acmA(AudioCodingModule::Create(1)),
53 _acmB(AudioCodingModule::Create(2)),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000054 _channel_A2B(NULL),
55 _channel_B2A(NULL),
56 _writeToFile(true),
57 _pullEventA(NULL),
58 _pushEventA(NULL),
59 _processEventA(NULL),
60 _apiEventA(NULL),
61 _pullEventB(NULL),
62 _pushEventB(NULL),
63 _processEventB(NULL),
64 _apiEventB(NULL),
65 _codecCntrA(0),
66 _codecCntrB(0),
67 _thereIsEncoderA(false),
68 _thereIsEncoderB(false),
69 _thereIsDecoderA(false),
70 _thereIsDecoderB(false),
71 _sendVADA(false),
72 _sendDTXA(false),
73 _sendVADModeA(VADNormal),
74 _sendVADB(false),
75 _sendDTXB(false),
76 _sendVADModeB(VADNormal),
77 _minDelayA(0),
78 _minDelayB(0),
79 _dotPositionA(0),
80 _dotMoveDirectionA(1),
81 _dotPositionB(39),
82 _dotMoveDirectionB(-1),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000083 _vadCallbackA(NULL),
84 _vadCallbackB(NULL),
85 _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
86 _randomTest(false),
87 _testNumA(0),
88 _testNumB(1) {
89 int n;
90 for (n = 0; n < 32; n++) {
91 _payloadUsed[n] = false;
92 }
niklase@google.com470e71d2011-07-07 08:21:25 +000093
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000094 _movingDot[40] = '\0';
niklase@google.com470e71d2011-07-07 08:21:25 +000095
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000096 for (int n = 0; n < 40; n++) {
97 _movingDot[n] = ' ';
98 }
niklase@google.com470e71d2011-07-07 08:21:25 +000099}
100
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000101APITest::~APITest() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000102 DELETE_POINTER(_channel_A2B);
103 DELETE_POINTER(_channel_B2A);
niklase@google.com470e71d2011-07-07 08:21:25 +0000104
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000105 DELETE_POINTER(_pushEventA);
106 DELETE_POINTER(_pullEventA);
107 DELETE_POINTER(_processEventA);
108 DELETE_POINTER(_apiEventA);
niklase@google.com470e71d2011-07-07 08:21:25 +0000109
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000110 DELETE_POINTER(_pushEventB);
111 DELETE_POINTER(_pullEventB);
112 DELETE_POINTER(_processEventB);
113 DELETE_POINTER(_apiEventB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000114
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000115 _inFileA.Close();
116 _outFileA.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000117
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000118 _inFileB.Close();
119 _outFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000120
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000121 DELETE_POINTER(_vadCallbackA);
122 DELETE_POINTER(_vadCallbackB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000123
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000124 delete &_apiTestRWLock;
niklase@google.com470e71d2011-07-07 08:21:25 +0000125}
126
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000127int16_t APITest::SetUp() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000128 CodecInst dummyCodec;
129 int lastPayloadType = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000130
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000131 int16_t numCodecs = _acmA->NumberOfCodecs();
132 for (uint8_t n = 0; n < numCodecs; n++) {
133 AudioCodingModule::Codec(n, &dummyCodec);
134 if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
135 && (dummyCodec.plfreq == 32000)) {
136 continue;
niklase@google.com470e71d2011-07-07 08:21:25 +0000137 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000138
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000139 printf("Register Receive Codec %s ", dummyCodec.plname);
niklase@google.com470e71d2011-07-07 08:21:25 +0000140
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000141 if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
142 // Check registration with an already occupied payload type
143 int currentPayloadType = dummyCodec.pltype;
144 dummyCodec.pltype = 97; //lastPayloadType;
145 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
146 dummyCodec.pltype = currentPayloadType;
147 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000148
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000149 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
150 // test if re-registration works;
151 CodecInst nextCodec;
152 int currentPayloadType = dummyCodec.pltype;
153 AudioCodingModule::Codec(n + 1, &nextCodec);
154 dummyCodec.pltype = nextCodec.pltype;
155 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
156 _acmB->RegisterReceiveCodec(dummyCodec);
157 }
158 dummyCodec.pltype = currentPayloadType;
159 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000160
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000161 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
162 // test if un-registration works;
163 CodecInst nextCodec;
164 AudioCodingModule::Codec(n + 1, &nextCodec);
165 nextCodec.pltype = dummyCodec.pltype;
166 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
167 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
168 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
169 }
170 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000171
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000172 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
173 printf(" side A done!");
174 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
175 printf(" side B done!\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000176
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000177 if (!strcmp(dummyCodec.plname, "CN")) {
178 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
179 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
180 }
181 lastPayloadType = dummyCodec.pltype;
182 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
183 _payloadUsed[lastPayloadType - 96] = true;
184 }
185 }
186 _thereIsDecoderA = true;
187 _thereIsDecoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000188
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000189 // Register Send Codec
190 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
191 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
192 _thereIsEncoderA = true;
193 //
194 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
195 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
196 _thereIsEncoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000197
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000198 uint16_t frequencyHz;
niklase@google.com470e71d2011-07-07 08:21:25 +0000199
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000200 printf("\n\nAPI Test\n");
201 printf("========\n");
202 printf("Hit enter to accept the default values indicated in []\n\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000203
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000204 //--- Input A
205 std::string file_name = webrtc::test::ResourcePath(
206 "audio_coding/testfile32kHz", "pcm");
207 frequencyHz = 32000;
208 printf("Enter input file at side A [%s]: ", file_name.c_str());
209 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
210 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000211
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000212 //--- Output A
213 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
214 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
215 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
216 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000217
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000218 //--- Input B
219 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
220 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
221 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
222 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000223
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000224 //--- Output B
225 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
226 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
227 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
228 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000229
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000230 //--- Set A-to-B channel
231 _channel_A2B = new Channel(2);
232 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000233 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000234
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000235 //--- Set B-to-A channel
236 _channel_B2A = new Channel(1);
237 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000238 _channel_B2A->RegisterReceiverACM(_acmA.get());
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000239
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000240 //--- EVENT TIMERS
241 // A
Peter Boström64c03662015-04-08 11:24:19 +0200242 _pullEventA = EventTimerWrapper::Create();
243 _pushEventA = EventTimerWrapper::Create();
244 _processEventA = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000245 _apiEventA = EventWrapper::Create();
246 // B
Peter Boström64c03662015-04-08 11:24:19 +0200247 _pullEventB = EventTimerWrapper::Create();
248 _pushEventB = EventTimerWrapper::Create();
249 _processEventB = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000250 _apiEventB = EventWrapper::Create();
251
252 //--- I/O params
253 // A
254 _outFreqHzA = _outFileA.SamplingFrequency();
255 // B
256 _outFreqHzB = _outFileB.SamplingFrequency();
257
258 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
259
260 char print[11];
261
262 // Create a trace file.
263 Trace::CreateTrace();
264 Trace::SetTraceFile(
265 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
266
267 printf("\nRandom Test (y/n)?");
268 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
269 print[10] = '\0';
270 if (strstr(print, "y") != NULL) {
271 _randomTest = true;
272 _verbose = false;
273 _writeToFile = false;
274 } else {
275 _randomTest = false;
276 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000277 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000278 print[10] = '\0';
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000279 if (strstr(print, "y") == NULL) {
280 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
281 _verbose = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000282 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000283 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000284
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000285 _vadCallbackA = new VADCallback;
286 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000287
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000288 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000289}
290
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000291bool APITest::PushAudioThreadA(void* obj) {
292 return static_cast<APITest*>(obj)->PushAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000293}
294
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000295bool APITest::PushAudioThreadB(void* obj) {
296 return static_cast<APITest*>(obj)->PushAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000297}
298
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000299bool APITest::PullAudioThreadA(void* obj) {
300 return static_cast<APITest*>(obj)->PullAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000301}
302
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000303bool APITest::PullAudioThreadB(void* obj) {
304 return static_cast<APITest*>(obj)->PullAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000305}
306
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000307bool APITest::ProcessThreadA(void* obj) {
308 return static_cast<APITest*>(obj)->ProcessRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000309}
310
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000311bool APITest::ProcessThreadB(void* obj) {
312 return static_cast<APITest*>(obj)->ProcessRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000313}
314
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000315bool APITest::APIThreadA(void* obj) {
316 return static_cast<APITest*>(obj)->APIRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000317}
318
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000319bool APITest::APIThreadB(void* obj) {
320 return static_cast<APITest*>(obj)->APIRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000321}
322
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000323bool APITest::PullAudioRunA() {
324 _pullEventA->Wait(100);
325 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700326 bool muted;
327 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000328 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000330 ReadLockScoped rl(_apiTestRWLock);
331 thereIsDecoder = _thereIsDecoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000332 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000333 if (thereIsDecoder) {
334 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000335 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000336 } else {
337 if (_writeToFile) {
338 _outFileA.Write10MsData(audioFrame);
339 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000340 }
341 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000342}
343
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000344bool APITest::PullAudioRunB() {
345 _pullEventB->Wait(100);
346 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700347 bool muted;
348 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000349 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000350 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000351 ReadLockScoped rl(_apiTestRWLock);
352 thereIsDecoder = _thereIsDecoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000354 if (thereIsDecoder) {
355 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
356 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000357 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000358 } else {
359 if (_writeToFile) {
360 _outFileB.Write10MsData(audioFrame);
361 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000362 }
363 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000364}
365
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000366bool APITest::PushAudioRunA() {
367 _pushEventA->Wait(100);
368 AudioFrame audioFrame;
369 _inFileA.Read10MsData(audioFrame);
370 if (_acmA->Add10MsData(audioFrame) < 0) {
371 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000372 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000373 ReadLockScoped rl(_apiTestRWLock);
374 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000375 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000376 if (thereIsEncoder) {
377 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
378 }
379 }
380 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000381}
382
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000383bool APITest::PushAudioRunB() {
384 _pushEventB->Wait(100);
385 AudioFrame audioFrame;
386 _inFileB.Read10MsData(audioFrame);
387 if (_acmB->Add10MsData(audioFrame) < 0) {
388 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000389 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000390 ReadLockScoped rl(_apiTestRWLock);
391 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000392 }
393
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000394 if (thereIsEncoder) {
395 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
396 }
397 }
398
399 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000400}
401
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000402bool APITest::ProcessRunA() {
403 _processEventA->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000404 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000405}
406
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000407bool APITest::ProcessRunB() {
408 _processEventB->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000409 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000410}
411
412/*/
413 *
414 * In side A we test the APIs which are related to sender Side.
415 *
416/*/
417
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000418void APITest::RunTest(char thread) {
419 int testNum;
420 {
421 WriteLockScoped cs(_apiTestRWLock);
422 if (thread == 'A') {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700423 _testNumA = (_testNumB + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000424 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000425
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000426 _movingDot[_dotPositionA] = ' ';
427 if (_dotPositionA == 0) {
428 _dotMoveDirectionA = 1;
429 }
430 if (_dotPositionA == 19) {
431 _dotMoveDirectionA = -1;
432 }
433 _dotPositionA += _dotMoveDirectionA;
434 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
435 } else {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700436 _testNumB = (_testNumA + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000437 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000438
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000439 _movingDot[_dotPositionB] = ' ';
440 if (_dotPositionB == 20) {
441 _dotMoveDirectionB = 1;
442 }
443 if (_dotPositionB == 39) {
444 _dotMoveDirectionB = -1;
445 }
446 _dotPositionB += _dotMoveDirectionB;
447 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000448 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000449 //fprintf(stderr, "%c: %d \n", thread, testNum);
450 //fflush(stderr);
451 }
452 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000453 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000454 CurrentCodec('A');
455 ChangeCodec('A');
456 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000457 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000458 if (!_randomTest) {
459 fprintf(stdout, "\nTesting Delay ...\n");
460 }
461 TestDelay('A');
462 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700463 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000464 TestSendVAD('A');
465 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700466 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000467 TestRegisteration('A');
468 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000469 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000470 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000471 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000472 exit(1);
473 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000474}
475
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000476bool APITest::APIRunA() {
477 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000478
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000479 bool randomTest;
480 {
481 ReadLockScoped rl(_apiTestRWLock);
482 randomTest = _randomTest;
483 }
484 if (randomTest) {
485 RunTest('A');
486 } else {
487 CurrentCodec('A');
488 ChangeCodec('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000489 if (_codecCntrA == 0) {
490 fprintf(stdout, "\nTesting Delay ...\n");
491 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000492 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000493 // VAD TEST
494 TestSendVAD('A');
495 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000496 }
497 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000498}
499
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000500bool APITest::APIRunB() {
501 _apiEventB->Wait(50);
502 bool randomTest;
503 {
504 ReadLockScoped rl(_apiTestRWLock);
505 randomTest = _randomTest;
506 }
507 //_apiEventB->Wait(2000);
508 if (randomTest) {
509 RunTest('B');
510 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000511
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000512 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000513}
514
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000515void APITest::Perform() {
516 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000517
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000518 //--- THREADS
519 // A
520 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100521 rtc::PlatformThread myPushAudioThreadA(PushAudioThreadA, this,
522 "PushAudioThreadA");
523 myPushAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000524 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100525 rtc::PlatformThread myPullAudioThreadA(PullAudioThreadA, this,
526 "PullAudioThreadA");
527 myPullAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000528 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100529 rtc::PlatformThread myProcessThreadA(ProcessThreadA, this, "ProcessThreadA");
530 myProcessThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000531 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100532 rtc::PlatformThread myAPIThreadA(APIThreadA, this, "APIThreadA");
533 myAPIThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000534 // B
535 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100536 rtc::PlatformThread myPushAudioThreadB(PushAudioThreadB, this,
537 "PushAudioThreadB");
538 myPushAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000539 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100540 rtc::PlatformThread myPullAudioThreadB(PullAudioThreadB, this,
541 "PullAudioThreadB");
542 myPullAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000543 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100544 rtc::PlatformThread myProcessThreadB(ProcessThreadB, this, "ProcessThreadB");
545 myProcessThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000546 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100547 rtc::PlatformThread myAPIThreadB(APIThreadB, this, "APIThreadB");
548 myAPIThreadB.Start();
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000549
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000550 //_apiEventA->StartTimer(true, 5000);
551 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000552
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000553 _processEventA->StartTimer(true, 10);
554 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000555
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000556 _pullEventA->StartTimer(true, 10);
557 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000558
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000559 _pushEventA->StartTimer(true, 10);
560 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000561
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000562 // Keep main thread waiting for sender/receiver
563 // threads to complete
564 EventWrapper* completeEvent = EventWrapper::Create();
Niels Möllerd28db7f2016-05-10 16:31:47 +0200565 uint64_t startTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000566 uint64_t currentTime;
567 // Run test in 2 minutes (120000 ms).
568 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000569 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000570 //ReadLockScoped rl(_apiTestRWLock);
571 //fprintf(stderr, "\r%s", _movingDot);
572 }
573 //fflush(stderr);
574 completeEvent->Wait(50);
Niels Möllerd28db7f2016-05-10 16:31:47 +0200575 currentTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000576 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000577
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000578 //completeEvent->Wait(0xFFFFFFFF);
579 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
580 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000581
Peter Boström8c38e8b2015-11-26 17:45:47 +0100582 myPushAudioThreadA.Stop();
583 myPullAudioThreadA.Stop();
584 myProcessThreadA.Stop();
585 myAPIThreadA.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000586
Peter Boström8c38e8b2015-11-26 17:45:47 +0100587 myPushAudioThreadB.Stop();
588 myPullAudioThreadB.Stop();
589 myProcessThreadB.Stop();
590 myAPIThreadB.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000591}
592
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000593void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000594
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000595 bool dtxEnabled;
596 bool vadEnabled;
597 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000598
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000599 if (side == 'A') {
600 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
601 _acmA->RegisterVADCallback(NULL);
602 _vadCallbackA->Reset();
603 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000604
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000605 if (!_randomTest) {
606 if (_verbose) {
607 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
608 vadEnabled ? "ON" : "OFF", (int) vadMode);
609 Wait(5000);
610 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
611 } else {
612 Wait(5000);
613 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
614 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
615 (int) vadMode, _channel_A2B->BitRate());
616 }
617 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000618 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000619
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000620 if (dtxEnabled != _sendDTXA) {
621 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000622 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000623 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
624 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
625 }
626 if ((vadMode != _sendVADModeA) && vadEnabled) {
627 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
628 }
629 } else {
630 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
631
632 _acmB->RegisterVADCallback(NULL);
633 _vadCallbackB->Reset();
634 _acmB->RegisterVADCallback(_vadCallbackB);
635
636 if (!_randomTest) {
637 if (_verbose) {
638 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
639 vadEnabled ? "ON" : "OFF", (int) vadMode);
640 Wait(5000);
641 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
642 } else {
643 Wait(5000);
644 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
645 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
646 (int) vadMode, _channel_B2A->BitRate());
647 }
648 _vadCallbackB->PrintFrameTypes();
649 }
650
651 if (dtxEnabled != _sendDTXB) {
652 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
653 }
654 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
655 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
656 }
657 if ((vadMode != _sendVADModeB) && vadEnabled) {
658 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
659 }
660 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000661}
662
663// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000664void APITest::TestDelay(char side) {
665 AudioCodingModule* myACM;
666 Channel* myChannel;
667 int32_t* myMinDelay;
Peter Boström64c03662015-04-08 11:24:19 +0200668 EventTimerWrapper* myEvent = EventTimerWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000669
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000670 uint32_t inTimestamp = 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000671 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000672
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000673 double averageEstimDelay = 0;
674 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000675
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000676 CircularBuffer estimDelayCB(100);
677 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000678
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000679 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000680 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000681 myChannel = _channel_B2A;
682 myMinDelay = &_minDelayA;
683 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000684 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000685 myChannel = _channel_A2B;
686 myMinDelay = &_minDelayB;
687 }
688
689 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
690
691 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700692 rtc::Optional<uint32_t> outTimestamp = myACM->PlayoutTimestamp();
693 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000694
695 if (!_randomTest) {
696 myEvent->StartTimer(true, 30);
697 int n = 0;
698 int settlePoint = 5000;
699 while (n < settlePoint + 400) {
700 myEvent->Wait(1000);
701
702 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700703 outTimestamp = myACM->PlayoutTimestamp();
704 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000705
706 //std::cout << outTimestamp << std::endl << std::flush;
henrik.lundin9a410dd2016-04-06 01:39:22 -0700707 estimDelay = (double)((uint32_t)(inTimestamp - *outTimestamp)) /
708 ((double)myACM->ReceiveFrequency() / 1000.0);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000709
710 estimDelayCB.Update(estimDelay);
711
712 estimDelayCB.ArithMean(averageEstimDelay);
713 //printf("\n %6.1f \n", estimDelay);
714 //std::cout << " " << std::flush;
715
716 if (_verbose) {
717 fprintf(stdout,
718 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
719 *myMinDelay, averageDelay, averageEstimDelay);
720 std::cout << " " << std::flush;
721 }
722 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
723 settlePoint = n;
724 }
725 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000726 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000727 myEvent->StopTimer();
728 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000729
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000730 if ((!_verbose) && (!_randomTest)) {
731 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000732 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000733 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000734
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000735 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000736
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000737 NetworkStatistics networkStat;
738 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000739
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000740 if (!_randomTest) {
741 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
742 fprintf(stdout, "--------------------------------------\n");
743 fprintf(stdout, "buffer-size............. %d\n",
744 networkStat.currentBufferSize);
745 fprintf(stdout, "Preferred buffer-size... %d\n",
746 networkStat.preferredBufferSize);
747 fprintf(stdout, "Peaky jitter mode........%d\n",
748 networkStat.jitterPeaksFound);
749 fprintf(stdout, "packet-size rate........ %d\n",
750 networkStat.currentPacketLossRate);
751 fprintf(stdout, "discard rate............ %d\n",
752 networkStat.currentDiscardRate);
753 fprintf(stdout, "expand rate............. %d\n",
754 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000755 fprintf(stdout, "speech expand rate...... %d\n",
756 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000757 fprintf(stdout, "Preemptive rate......... %d\n",
758 networkStat.currentPreemptiveRate);
759 fprintf(stdout, "Accelerate rate......... %d\n",
760 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000761 fprintf(stdout, "Secondary decoded rate.. %d\n",
762 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000763 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
764 fprintf(stdout, "Mean waiting time....... %d\n",
765 networkStat.meanWaitingTimeMs);
766 fprintf(stdout, "Median waiting time..... %d\n",
767 networkStat.medianWaitingTimeMs);
768 fprintf(stdout, "Min waiting time........ %d\n",
769 networkStat.minWaitingTimeMs);
770 fprintf(stdout, "Max waiting time........ %d\n",
771 networkStat.maxWaitingTimeMs);
772 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000773
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000774 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000775
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000776 if (!_randomTest) {
777 myEvent->Wait(500);
778 fprintf(stdout, "\n");
779 fprintf(stdout, "\n");
780 }
781 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000782}
783
784// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000785void APITest::TestRegisteration(char sendSide) {
786 AudioCodingModule* sendACM;
787 AudioCodingModule* receiveACM;
788 bool* thereIsDecoder;
789 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000790
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000791 if (!_randomTest) {
792 fprintf(stdout, "\n\n");
793 fprintf(stdout,
794 "---------------------------------------------------------\n");
795 fprintf(stdout, " Unregister/register Receive Codec\n");
796 fprintf(stdout,
797 "---------------------------------------------------------\n");
798 }
799
800 switch (sendSide) {
801 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000802 sendACM = _acmA.get();
803 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000804 thereIsDecoder = &_thereIsDecoderB;
805 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000806 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000807 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000808 sendACM = _acmB.get();
809 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000810 thereIsDecoder = &_thereIsDecoderA;
811 break;
812 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000813 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000814 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
815 sendSide);
816 exit(-1);
817 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000818
kwiberg1fd4a4a2015-11-03 11:20:50 -0800819 auto myCodec = sendACM->SendCodec();
820 if (!myCodec) {
821 CodecInst ci;
822 AudioCodingModule::Codec(_codecCntrA, &ci);
Karl Wibergbe579832015-11-10 22:34:18 +0100823 myCodec = rtc::Optional<CodecInst>(ci);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000824 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000825
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000826 if (!_randomTest) {
827 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
828 fflush (stdout);
829 }
830 {
831 WriteLockScoped wl(_apiTestRWLock);
832 *thereIsDecoder = false;
833 }
834 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800835 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000836 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000837
kwiberg1fd4a4a2015-11-03 11:20:50 -0800838 int currentPayload = myCodec->pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000839
kwiberg1fd4a4a2015-11-03 11:20:50 -0800840 if (!FixedPayloadTypeCodec(myCodec->plname)) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000841 int32_t i;
842 for (i = 0; i < 32; i++) {
843 if (!_payloadUsed[i]) {
844 if (!_randomTest) {
845 fprintf(stdout,
846 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000847 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800848 //myCodec->pltype = i + 96;
849 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
850 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000851 //myEvent->Wait(20);
852 //{
853 // WriteLockScoped wl(_apiTestRWLock);
854 // *thereIsDecoder = true;
855 //}
856 Wait(1000);
857
858 if (!_randomTest) {
859 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000860 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000861 //{
862 // WriteLockScoped wl(_apiTestRWLock);
863 // *thereIsDecoder = false;
864 //}
865 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800866 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000867 Wait(1000);
868
kwiberg1fd4a4a2015-11-03 11:20:50 -0800869 myCodec->pltype = currentPayload;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000870 if (!_randomTest) {
871 fprintf(stdout,
872 "Register receive codec with default Payload, AUDIO BACK.\n");
873 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000874 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800875 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
876 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000877 myEvent->Wait(20);
878 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000879 WriteLockScoped wl(_apiTestRWLock);
880 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000881 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000882 Wait(1000);
883
884 break;
885 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000886 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000887 if (i == 32) {
kwiberg1fd4a4a2015-11-03 11:20:50 -0800888 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000889 {
890 WriteLockScoped wl(_apiTestRWLock);
891 *thereIsDecoder = true;
892 }
893 }
894 } else {
895 if (!_randomTest) {
896 fprintf(stdout,
897 "Register receive codec with fixed Payload, AUDIO BACK.\n");
898 fflush (stdout);
899 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800900 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
901 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
902 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000903 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000904 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000905 WriteLockScoped wl(_apiTestRWLock);
906 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000907 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000908 }
909 delete myEvent;
910 if (!_randomTest) {
911 fprintf(stdout,
912 "---------------------------------------------------------\n");
913 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000914}
915
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000916void APITest::TestSendVAD(char side) {
917 if (_randomTest) {
918 return;
919 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000920
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000921 bool* vad;
922 bool* dtx;
923 ACMVADMode* mode;
924 Channel* myChannel;
925 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +0000926
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000927 CodecInst myCodec;
928 if (!_randomTest) {
929 fprintf(stdout, "\n\n");
930 fprintf(stdout, "-----------------------------------------------\n");
931 fprintf(stdout, " Test VAD API\n");
932 fprintf(stdout, "-----------------------------------------------\n");
933 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000934
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000935 if (side == 'A') {
936 AudioCodingModule::Codec(_codecCntrA, &myCodec);
937 vad = &_sendVADA;
938 dtx = &_sendDTXA;
939 mode = &_sendVADModeA;
940 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000941 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000942 } else {
943 AudioCodingModule::Codec(_codecCntrB, &myCodec);
944 vad = &_sendVADB;
945 dtx = &_sendDTXB;
946 mode = &_sendVADModeB;
947 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000948 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000949 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000950
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000951 CheckVADStatus(side);
952 if (!_randomTest) {
953 fprintf(stdout, "\n\n");
954 }
955
956 switch (*mode) {
957 case VADNormal:
958 *vad = true;
959 *dtx = true;
960 *mode = VADAggr;
961 break;
962 case VADLowBitrate:
963 *vad = true;
964 *dtx = true;
965 *mode = VADVeryAggr;
966 break;
967 case VADAggr:
968 *vad = true;
969 *dtx = true;
970 *mode = VADLowBitrate;
971 break;
972 case VADVeryAggr:
973 *vad = false;
974 *dtx = false;
975 *mode = VADNormal;
976 break;
977 default:
978 *mode = VADNormal;
979 }
980
981 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
982
983 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
984 myChannel->ResetStats();
985
986 CheckVADStatus(side);
987 if (!_randomTest) {
988 fprintf(stdout, "\n");
989 fprintf(stdout, "-----------------------------------------------\n");
990 }
991
992 // Fault Test
993 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
994 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +0000995
996}
997
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000998void APITest::CurrentCodec(char side) {
kwiberg1fd4a4a2015-11-03 11:20:50 -0800999 auto myCodec = (side == 'A' ? _acmA : _acmB)->SendCodec();
niklase@google.com470e71d2011-07-07 08:21:25 +00001000
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001001 if (!_randomTest) {
1002 fprintf(stdout, "\n\n");
1003 fprintf(stdout, "Send codec in Side A\n");
1004 fprintf(stdout, "----------------------------\n");
kwiberg1fd4a4a2015-11-03 11:20:50 -08001005 fprintf(stdout, "Name................. %s\n", myCodec->plname);
1006 fprintf(stdout, "Sampling Frequency... %d\n", myCodec->plfreq);
1007 fprintf(stdout, "Rate................. %d\n", myCodec->rate);
1008 fprintf(stdout, "Payload-type......... %d\n", myCodec->pltype);
1009 fprintf(stdout, "Packet-size.......... %d\n", myCodec->pacsize);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001010 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001011
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001012 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001013}
1014
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001015void APITest::ChangeCodec(char side) {
1016 CodecInst myCodec;
1017 AudioCodingModule* myACM;
1018 uint8_t* codecCntr;
1019 bool* thereIsEncoder;
1020 bool* vad;
1021 bool* dtx;
1022 ACMVADMode* mode;
1023 Channel* myChannel;
1024 // Reset and Wait
1025 if (!_randomTest) {
1026 fprintf(stdout, "Reset Encoder Side A \n");
1027 }
1028 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001029 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001030 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001031 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001032 WriteLockScoped wl(_apiTestRWLock);
1033 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001034 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001035 vad = &_sendVADA;
1036 dtx = &_sendDTXA;
1037 mode = &_sendVADModeA;
1038 myChannel = _channel_A2B;
1039 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001040 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001041 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001042 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001043 WriteLockScoped wl(_apiTestRWLock);
1044 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001045 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001046 vad = &_sendVADB;
1047 dtx = &_sendDTXB;
1048 mode = &_sendVADModeB;
1049 myChannel = _channel_B2A;
1050 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001051
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001052 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001053
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001054 // Register the next codec
1055 do {
1056 *codecCntr =
1057 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1058 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001059
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001060 if (*codecCntr == 0) {
1061 //printf("Initialize Sender Side A \n");
1062 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001063 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001064 *thereIsEncoder = false;
1065 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001066 // After Initialization CN is lost, re-register them
1067 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1068 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1069 }
1070 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1071 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1072 }
1073 // VAD & DTX are disabled after initialization
1074 *vad = false;
1075 *dtx = false;
1076 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001077 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001078
1079 AudioCodingModule::Codec(*codecCntr, &myCodec);
1080 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1081 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1082 || !STR_CASE_CMP(myCodec.plname, "RED"));
1083
1084 if (!_randomTest) {
1085 fprintf(stdout,"\n=====================================================\n");
1086 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1087 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1088 }
1089 //std::cout<< std::flush;
1090
1091 // NO DTX for supe-wideband codec at this point
1092 if (myCodec.plfreq == 32000) {
1093 *dtx = false;
1094 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1095
1096 }
1097
1098 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1099 myChannel->ResetStats();
1100 {
1101 WriteLockScoped wl(_apiTestRWLock);
1102 *thereIsEncoder = true;
1103 }
1104 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001105}
1106
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001107} // namespace webrtc