blob: ffa675c0fa7f9c368a0edc014e2729ee821a3811 [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
pbos12411ef2015-11-23 14:47:56 -080022#include "webrtc/base/platform_thread.h"
Niels Möllerd28db7f2016-05-10 16:31:47 +020023#include "webrtc/base/timeutils.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000024#include "webrtc/common_types.h"
kjellander3e6db232015-11-26 04:44:54 -080025#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h"
26#include "webrtc/modules/audio_coding/test/utility.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010027#include "webrtc/system_wrappers/include/event_wrapper.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010028#include "webrtc/system_wrappers/include/trace.h"
kwibergac9f8762016-09-30 22:29:43 -070029#include "webrtc/test/gtest.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000030#include "webrtc/test/testsupport/fileutils.h"
mflodman7056be92016-10-07 07:07:28 +020031#include "webrtc/voice_engine_configurations.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000032
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000033namespace webrtc {
34
niklase@google.com470e71d2011-07-07 08:21:25 +000035#define TEST_DURATION_SEC 600
niklase@google.com470e71d2011-07-07 08:21:25 +000036#define NUMBER_OF_SENDER_TESTS 6
niklase@google.com470e71d2011-07-07 08:21:25 +000037#define MAX_FILE_NAME_LENGTH_BYTE 500
niklase@google.com470e71d2011-07-07 08:21:25 +000038
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000039void APITest::Wait(uint32_t waitLengthMs) {
40 if (_randomTest) {
41 return;
42 } else {
43 EventWrapper* myEvent = EventWrapper::Create();
44 myEvent->Wait(waitLengthMs);
45 delete myEvent;
46 return;
47 }
niklase@google.com470e71d2011-07-07 08:21:25 +000048}
49
solenberg88499ec2016-09-07 07:34:41 -070050APITest::APITest()
henrik.lundin@webrtc.orgadaf8092014-04-17 08:29:10 +000051 : _acmA(AudioCodingModule::Create(1)),
52 _acmB(AudioCodingModule::Create(2)),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000053 _channel_A2B(NULL),
54 _channel_B2A(NULL),
55 _writeToFile(true),
56 _pullEventA(NULL),
57 _pushEventA(NULL),
58 _processEventA(NULL),
59 _apiEventA(NULL),
60 _pullEventB(NULL),
61 _pushEventB(NULL),
62 _processEventB(NULL),
63 _apiEventB(NULL),
64 _codecCntrA(0),
65 _codecCntrB(0),
66 _thereIsEncoderA(false),
67 _thereIsEncoderB(false),
68 _thereIsDecoderA(false),
69 _thereIsDecoderB(false),
70 _sendVADA(false),
71 _sendDTXA(false),
72 _sendVADModeA(VADNormal),
73 _sendVADB(false),
74 _sendDTXB(false),
75 _sendVADModeB(VADNormal),
76 _minDelayA(0),
77 _minDelayB(0),
78 _dotPositionA(0),
79 _dotMoveDirectionA(1),
80 _dotPositionB(39),
81 _dotMoveDirectionB(-1),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000082 _vadCallbackA(NULL),
83 _vadCallbackB(NULL),
84 _apiTestRWLock(*RWLockWrapper::CreateRWLock()),
85 _randomTest(false),
86 _testNumA(0),
87 _testNumB(1) {
88 int n;
89 for (n = 0; n < 32; n++) {
90 _payloadUsed[n] = false;
91 }
niklase@google.com470e71d2011-07-07 08:21:25 +000092
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000093 _movingDot[40] = '\0';
niklase@google.com470e71d2011-07-07 08:21:25 +000094
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000095 for (int n = 0; n < 40; n++) {
96 _movingDot[n] = ' ';
97 }
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000100APITest::~APITest() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000101 DELETE_POINTER(_channel_A2B);
102 DELETE_POINTER(_channel_B2A);
niklase@google.com470e71d2011-07-07 08:21:25 +0000103
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000104 DELETE_POINTER(_pushEventA);
105 DELETE_POINTER(_pullEventA);
106 DELETE_POINTER(_processEventA);
107 DELETE_POINTER(_apiEventA);
niklase@google.com470e71d2011-07-07 08:21:25 +0000108
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000109 DELETE_POINTER(_pushEventB);
110 DELETE_POINTER(_pullEventB);
111 DELETE_POINTER(_processEventB);
112 DELETE_POINTER(_apiEventB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000113
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000114 _inFileA.Close();
115 _outFileA.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000116
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000117 _inFileB.Close();
118 _outFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000120 DELETE_POINTER(_vadCallbackA);
121 DELETE_POINTER(_vadCallbackB);
niklase@google.com470e71d2011-07-07 08:21:25 +0000122
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000123 delete &_apiTestRWLock;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124}
125
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000126int16_t APITest::SetUp() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000127 CodecInst dummyCodec;
128 int lastPayloadType = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000129
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000130 int16_t numCodecs = _acmA->NumberOfCodecs();
131 for (uint8_t n = 0; n < numCodecs; n++) {
132 AudioCodingModule::Codec(n, &dummyCodec);
133 if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0)
134 && (dummyCodec.plfreq == 32000)) {
135 continue;
niklase@google.com470e71d2011-07-07 08:21:25 +0000136 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000137
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000138 printf("Register Receive Codec %s ", dummyCodec.plname);
niklase@google.com470e71d2011-07-07 08:21:25 +0000139
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000140 if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
141 // Check registration with an already occupied payload type
142 int currentPayloadType = dummyCodec.pltype;
143 dummyCodec.pltype = 97; //lastPayloadType;
144 CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
145 dummyCodec.pltype = currentPayloadType;
146 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000147
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000148 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
149 // test if re-registration works;
150 CodecInst nextCodec;
151 int currentPayloadType = dummyCodec.pltype;
152 AudioCodingModule::Codec(n + 1, &nextCodec);
153 dummyCodec.pltype = nextCodec.pltype;
154 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
155 _acmB->RegisterReceiveCodec(dummyCodec);
156 }
157 dummyCodec.pltype = currentPayloadType;
158 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000159
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000160 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
161 // test if un-registration works;
162 CodecInst nextCodec;
163 AudioCodingModule::Codec(n + 1, &nextCodec);
164 nextCodec.pltype = dummyCodec.pltype;
165 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
166 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
167 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
168 }
169 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000170
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000171 CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
172 printf(" side A done!");
173 CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
174 printf(" side B done!\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000175
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000176 if (!strcmp(dummyCodec.plname, "CN")) {
177 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
178 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
179 }
180 lastPayloadType = dummyCodec.pltype;
181 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
182 _payloadUsed[lastPayloadType - 96] = true;
183 }
184 }
185 _thereIsDecoderA = true;
186 _thereIsDecoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000187
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000188 // Register Send Codec
189 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
190 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
191 _thereIsEncoderA = true;
192 //
193 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
194 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
195 _thereIsEncoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000196
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000197 uint16_t frequencyHz;
niklase@google.com470e71d2011-07-07 08:21:25 +0000198
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000199 printf("\n\nAPI Test\n");
200 printf("========\n");
201 printf("Hit enter to accept the default values indicated in []\n\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000202
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000203 //--- Input A
204 std::string file_name = webrtc::test::ResourcePath(
205 "audio_coding/testfile32kHz", "pcm");
206 frequencyHz = 32000;
207 printf("Enter input file at side A [%s]: ", file_name.c_str());
208 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
209 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000210
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000211 //--- Output A
212 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
213 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
214 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
215 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000216
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000217 //--- Input B
218 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
219 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
220 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
221 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000222
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000223 //--- Output B
224 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
225 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
226 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
227 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000228
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000229 //--- Set A-to-B channel
230 _channel_A2B = new Channel(2);
231 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000232 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000233
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000234 //--- Set B-to-A channel
235 _channel_B2A = new Channel(1);
236 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000237 _channel_B2A->RegisterReceiverACM(_acmA.get());
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000238
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000239 //--- EVENT TIMERS
240 // A
Peter Boström64c03662015-04-08 11:24:19 +0200241 _pullEventA = EventTimerWrapper::Create();
242 _pushEventA = EventTimerWrapper::Create();
243 _processEventA = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000244 _apiEventA = EventWrapper::Create();
245 // B
Peter Boström64c03662015-04-08 11:24:19 +0200246 _pullEventB = EventTimerWrapper::Create();
247 _pushEventB = EventTimerWrapper::Create();
248 _processEventB = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000249 _apiEventB = EventWrapper::Create();
250
251 //--- I/O params
252 // A
253 _outFreqHzA = _outFileA.SamplingFrequency();
254 // B
255 _outFreqHzB = _outFileB.SamplingFrequency();
256
257 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
258
259 char print[11];
260
261 // Create a trace file.
262 Trace::CreateTrace();
263 Trace::SetTraceFile(
264 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
265
266 printf("\nRandom Test (y/n)?");
267 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
268 print[10] = '\0';
269 if (strstr(print, "y") != NULL) {
270 _randomTest = true;
271 _verbose = false;
272 _writeToFile = false;
273 } else {
274 _randomTest = false;
275 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000276 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000277 print[10] = '\0';
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000278 if (strstr(print, "y") == NULL) {
279 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
280 _verbose = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000281 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000282 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000283
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000284 _vadCallbackA = new VADCallback;
285 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000286
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000287 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000288}
289
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000290bool APITest::PushAudioThreadA(void* obj) {
291 return static_cast<APITest*>(obj)->PushAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000292}
293
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000294bool APITest::PushAudioThreadB(void* obj) {
295 return static_cast<APITest*>(obj)->PushAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000296}
297
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000298bool APITest::PullAudioThreadA(void* obj) {
299 return static_cast<APITest*>(obj)->PullAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000300}
301
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000302bool APITest::PullAudioThreadB(void* obj) {
303 return static_cast<APITest*>(obj)->PullAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000304}
305
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000306bool APITest::ProcessThreadA(void* obj) {
307 return static_cast<APITest*>(obj)->ProcessRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000308}
309
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000310bool APITest::ProcessThreadB(void* obj) {
311 return static_cast<APITest*>(obj)->ProcessRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000312}
313
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000314bool APITest::APIThreadA(void* obj) {
315 return static_cast<APITest*>(obj)->APIRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000316}
317
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000318bool APITest::APIThreadB(void* obj) {
319 return static_cast<APITest*>(obj)->APIRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000320}
321
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000322bool APITest::PullAudioRunA() {
323 _pullEventA->Wait(100);
324 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700325 bool muted;
326 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000327 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000329 ReadLockScoped rl(_apiTestRWLock);
330 thereIsDecoder = _thereIsDecoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000332 if (thereIsDecoder) {
333 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000335 } else {
336 if (_writeToFile) {
337 _outFileA.Write10MsData(audioFrame);
338 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000339 }
340 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000341}
342
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000343bool APITest::PullAudioRunB() {
344 _pullEventB->Wait(100);
345 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700346 bool muted;
347 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000348 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000350 ReadLockScoped rl(_apiTestRWLock);
351 thereIsDecoder = _thereIsDecoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000352 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000353 if (thereIsDecoder) {
354 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
355 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000356 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000357 } else {
358 if (_writeToFile) {
359 _outFileB.Write10MsData(audioFrame);
360 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000361 }
362 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000363}
364
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000365bool APITest::PushAudioRunA() {
366 _pushEventA->Wait(100);
367 AudioFrame audioFrame;
368 _inFileA.Read10MsData(audioFrame);
369 if (_acmA->Add10MsData(audioFrame) < 0) {
370 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000371 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000372 ReadLockScoped rl(_apiTestRWLock);
373 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000374 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000375 if (thereIsEncoder) {
376 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
377 }
378 }
379 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000380}
381
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000382bool APITest::PushAudioRunB() {
383 _pushEventB->Wait(100);
384 AudioFrame audioFrame;
385 _inFileB.Read10MsData(audioFrame);
386 if (_acmB->Add10MsData(audioFrame) < 0) {
387 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000388 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000389 ReadLockScoped rl(_apiTestRWLock);
390 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000391 }
392
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000393 if (thereIsEncoder) {
394 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
395 }
396 }
397
398 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000399}
400
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000401bool APITest::ProcessRunA() {
402 _processEventA->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000403 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000404}
405
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000406bool APITest::ProcessRunB() {
407 _processEventB->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000408 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000409}
410
411/*/
412 *
413 * In side A we test the APIs which are related to sender Side.
414 *
415/*/
416
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000417void APITest::RunTest(char thread) {
418 int testNum;
419 {
420 WriteLockScoped cs(_apiTestRWLock);
421 if (thread == 'A') {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700422 _testNumA = (_testNumB + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000423 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000424
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000425 _movingDot[_dotPositionA] = ' ';
426 if (_dotPositionA == 0) {
427 _dotMoveDirectionA = 1;
428 }
429 if (_dotPositionA == 19) {
430 _dotMoveDirectionA = -1;
431 }
432 _dotPositionA += _dotMoveDirectionA;
433 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
434 } else {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700435 _testNumB = (_testNumA + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000436 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000437
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000438 _movingDot[_dotPositionB] = ' ';
439 if (_dotPositionB == 20) {
440 _dotMoveDirectionB = 1;
441 }
442 if (_dotPositionB == 39) {
443 _dotMoveDirectionB = -1;
444 }
445 _dotPositionB += _dotMoveDirectionB;
446 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000447 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000448 //fprintf(stderr, "%c: %d \n", thread, testNum);
449 //fflush(stderr);
450 }
451 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000452 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000453 CurrentCodec('A');
454 ChangeCodec('A');
455 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000456 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000457 if (!_randomTest) {
458 fprintf(stdout, "\nTesting Delay ...\n");
459 }
460 TestDelay('A');
461 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700462 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000463 TestSendVAD('A');
464 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700465 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000466 TestRegisteration('A');
467 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000468 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000469 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000470 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000471 exit(1);
472 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000473}
474
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000475bool APITest::APIRunA() {
476 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000477
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000478 bool randomTest;
479 {
480 ReadLockScoped rl(_apiTestRWLock);
481 randomTest = _randomTest;
482 }
483 if (randomTest) {
484 RunTest('A');
485 } else {
486 CurrentCodec('A');
487 ChangeCodec('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000488 if (_codecCntrA == 0) {
489 fprintf(stdout, "\nTesting Delay ...\n");
490 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000491 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000492 // VAD TEST
493 TestSendVAD('A');
494 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000495 }
496 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000497}
498
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000499bool APITest::APIRunB() {
500 _apiEventB->Wait(50);
501 bool randomTest;
502 {
503 ReadLockScoped rl(_apiTestRWLock);
504 randomTest = _randomTest;
505 }
506 //_apiEventB->Wait(2000);
507 if (randomTest) {
508 RunTest('B');
509 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000510
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000511 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000512}
513
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000514void APITest::Perform() {
515 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000516
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000517 //--- THREADS
518 // A
519 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100520 rtc::PlatformThread myPushAudioThreadA(PushAudioThreadA, this,
521 "PushAudioThreadA");
522 myPushAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000523 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100524 rtc::PlatformThread myPullAudioThreadA(PullAudioThreadA, this,
525 "PullAudioThreadA");
526 myPullAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000527 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100528 rtc::PlatformThread myProcessThreadA(ProcessThreadA, this, "ProcessThreadA");
529 myProcessThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000530 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100531 rtc::PlatformThread myAPIThreadA(APIThreadA, this, "APIThreadA");
532 myAPIThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000533 // B
534 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100535 rtc::PlatformThread myPushAudioThreadB(PushAudioThreadB, this,
536 "PushAudioThreadB");
537 myPushAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000538 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100539 rtc::PlatformThread myPullAudioThreadB(PullAudioThreadB, this,
540 "PullAudioThreadB");
541 myPullAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000542 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100543 rtc::PlatformThread myProcessThreadB(ProcessThreadB, this, "ProcessThreadB");
544 myProcessThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000545 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100546 rtc::PlatformThread myAPIThreadB(APIThreadB, this, "APIThreadB");
547 myAPIThreadB.Start();
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000548
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000549 //_apiEventA->StartTimer(true, 5000);
550 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000551
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000552 _processEventA->StartTimer(true, 10);
553 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000554
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000555 _pullEventA->StartTimer(true, 10);
556 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000557
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000558 _pushEventA->StartTimer(true, 10);
559 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000560
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000561 // Keep main thread waiting for sender/receiver
562 // threads to complete
563 EventWrapper* completeEvent = EventWrapper::Create();
Niels Möllerd28db7f2016-05-10 16:31:47 +0200564 uint64_t startTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000565 uint64_t currentTime;
566 // Run test in 2 minutes (120000 ms).
567 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000568 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000569 //ReadLockScoped rl(_apiTestRWLock);
570 //fprintf(stderr, "\r%s", _movingDot);
571 }
572 //fflush(stderr);
573 completeEvent->Wait(50);
Niels Möllerd28db7f2016-05-10 16:31:47 +0200574 currentTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000575 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000576
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000577 //completeEvent->Wait(0xFFFFFFFF);
578 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
579 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000580
Peter Boström8c38e8b2015-11-26 17:45:47 +0100581 myPushAudioThreadA.Stop();
582 myPullAudioThreadA.Stop();
583 myProcessThreadA.Stop();
584 myAPIThreadA.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000585
Peter Boström8c38e8b2015-11-26 17:45:47 +0100586 myPushAudioThreadB.Stop();
587 myPullAudioThreadB.Stop();
588 myProcessThreadB.Stop();
589 myAPIThreadB.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000590}
591
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000592void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000593
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000594 bool dtxEnabled;
595 bool vadEnabled;
596 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000597
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000598 if (side == 'A') {
599 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
600 _acmA->RegisterVADCallback(NULL);
601 _vadCallbackA->Reset();
602 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000603
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000604 if (!_randomTest) {
605 if (_verbose) {
606 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
607 vadEnabled ? "ON" : "OFF", (int) vadMode);
608 Wait(5000);
609 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
610 } else {
611 Wait(5000);
612 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
613 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
614 (int) vadMode, _channel_A2B->BitRate());
615 }
616 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000617 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000618
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000619 if (dtxEnabled != _sendDTXA) {
620 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000621 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000622 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
623 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
624 }
625 if ((vadMode != _sendVADModeA) && vadEnabled) {
626 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
627 }
628 } else {
629 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
630
631 _acmB->RegisterVADCallback(NULL);
632 _vadCallbackB->Reset();
633 _acmB->RegisterVADCallback(_vadCallbackB);
634
635 if (!_randomTest) {
636 if (_verbose) {
637 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
638 vadEnabled ? "ON" : "OFF", (int) vadMode);
639 Wait(5000);
640 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
641 } else {
642 Wait(5000);
643 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
644 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
645 (int) vadMode, _channel_B2A->BitRate());
646 }
647 _vadCallbackB->PrintFrameTypes();
648 }
649
650 if (dtxEnabled != _sendDTXB) {
651 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
652 }
653 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
654 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
655 }
656 if ((vadMode != _sendVADModeB) && vadEnabled) {
657 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
658 }
659 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000660}
661
662// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000663void APITest::TestDelay(char side) {
664 AudioCodingModule* myACM;
665 Channel* myChannel;
666 int32_t* myMinDelay;
Peter Boström64c03662015-04-08 11:24:19 +0200667 EventTimerWrapper* myEvent = EventTimerWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000668
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000669 uint32_t inTimestamp = 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000670 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000671
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000672 double averageEstimDelay = 0;
673 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000674
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000675 CircularBuffer estimDelayCB(100);
676 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000677
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000678 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000679 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000680 myChannel = _channel_B2A;
681 myMinDelay = &_minDelayA;
682 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000683 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000684 myChannel = _channel_A2B;
685 myMinDelay = &_minDelayB;
686 }
687
688 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
689
690 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700691 rtc::Optional<uint32_t> outTimestamp = myACM->PlayoutTimestamp();
692 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000693
694 if (!_randomTest) {
695 myEvent->StartTimer(true, 30);
696 int n = 0;
697 int settlePoint = 5000;
698 while (n < settlePoint + 400) {
699 myEvent->Wait(1000);
700
701 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700702 outTimestamp = myACM->PlayoutTimestamp();
703 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000704
705 //std::cout << outTimestamp << std::endl << std::flush;
henrik.lundin9a410dd2016-04-06 01:39:22 -0700706 estimDelay = (double)((uint32_t)(inTimestamp - *outTimestamp)) /
707 ((double)myACM->ReceiveFrequency() / 1000.0);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000708
709 estimDelayCB.Update(estimDelay);
710
711 estimDelayCB.ArithMean(averageEstimDelay);
712 //printf("\n %6.1f \n", estimDelay);
713 //std::cout << " " << std::flush;
714
715 if (_verbose) {
716 fprintf(stdout,
717 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
718 *myMinDelay, averageDelay, averageEstimDelay);
719 std::cout << " " << std::flush;
720 }
721 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
722 settlePoint = n;
723 }
724 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000725 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000726 myEvent->StopTimer();
727 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000728
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000729 if ((!_verbose) && (!_randomTest)) {
730 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000731 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000732 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000733
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000734 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000735
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000736 NetworkStatistics networkStat;
737 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000738
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000739 if (!_randomTest) {
740 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
741 fprintf(stdout, "--------------------------------------\n");
742 fprintf(stdout, "buffer-size............. %d\n",
743 networkStat.currentBufferSize);
744 fprintf(stdout, "Preferred buffer-size... %d\n",
745 networkStat.preferredBufferSize);
746 fprintf(stdout, "Peaky jitter mode........%d\n",
747 networkStat.jitterPeaksFound);
748 fprintf(stdout, "packet-size rate........ %d\n",
749 networkStat.currentPacketLossRate);
750 fprintf(stdout, "discard rate............ %d\n",
751 networkStat.currentDiscardRate);
752 fprintf(stdout, "expand rate............. %d\n",
753 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000754 fprintf(stdout, "speech expand rate...... %d\n",
755 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000756 fprintf(stdout, "Preemptive rate......... %d\n",
757 networkStat.currentPreemptiveRate);
758 fprintf(stdout, "Accelerate rate......... %d\n",
759 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000760 fprintf(stdout, "Secondary decoded rate.. %d\n",
761 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000762 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
763 fprintf(stdout, "Mean waiting time....... %d\n",
764 networkStat.meanWaitingTimeMs);
765 fprintf(stdout, "Median waiting time..... %d\n",
766 networkStat.medianWaitingTimeMs);
767 fprintf(stdout, "Min waiting time........ %d\n",
768 networkStat.minWaitingTimeMs);
769 fprintf(stdout, "Max waiting time........ %d\n",
770 networkStat.maxWaitingTimeMs);
771 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000772
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000773 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000774
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000775 if (!_randomTest) {
776 myEvent->Wait(500);
777 fprintf(stdout, "\n");
778 fprintf(stdout, "\n");
779 }
780 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000781}
782
783// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000784void APITest::TestRegisteration(char sendSide) {
785 AudioCodingModule* sendACM;
786 AudioCodingModule* receiveACM;
787 bool* thereIsDecoder;
788 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000789
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000790 if (!_randomTest) {
791 fprintf(stdout, "\n\n");
792 fprintf(stdout,
793 "---------------------------------------------------------\n");
794 fprintf(stdout, " Unregister/register Receive Codec\n");
795 fprintf(stdout,
796 "---------------------------------------------------------\n");
797 }
798
799 switch (sendSide) {
800 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000801 sendACM = _acmA.get();
802 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000803 thereIsDecoder = &_thereIsDecoderB;
804 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000805 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000806 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000807 sendACM = _acmB.get();
808 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000809 thereIsDecoder = &_thereIsDecoderA;
810 break;
811 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000812 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000813 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
814 sendSide);
815 exit(-1);
816 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000817
kwiberg1fd4a4a2015-11-03 11:20:50 -0800818 auto myCodec = sendACM->SendCodec();
819 if (!myCodec) {
820 CodecInst ci;
821 AudioCodingModule::Codec(_codecCntrA, &ci);
Karl Wibergbe579832015-11-10 22:34:18 +0100822 myCodec = rtc::Optional<CodecInst>(ci);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000823 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000824
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000825 if (!_randomTest) {
826 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
827 fflush (stdout);
828 }
829 {
830 WriteLockScoped wl(_apiTestRWLock);
831 *thereIsDecoder = false;
832 }
833 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800834 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000835 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000836
kwiberg1fd4a4a2015-11-03 11:20:50 -0800837 int currentPayload = myCodec->pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000838
kwiberg1fd4a4a2015-11-03 11:20:50 -0800839 if (!FixedPayloadTypeCodec(myCodec->plname)) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000840 int32_t i;
841 for (i = 0; i < 32; i++) {
842 if (!_payloadUsed[i]) {
843 if (!_randomTest) {
844 fprintf(stdout,
845 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000846 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800847 //myCodec->pltype = i + 96;
848 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
849 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000850 //myEvent->Wait(20);
851 //{
852 // WriteLockScoped wl(_apiTestRWLock);
853 // *thereIsDecoder = true;
854 //}
855 Wait(1000);
856
857 if (!_randomTest) {
858 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000859 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000860 //{
861 // WriteLockScoped wl(_apiTestRWLock);
862 // *thereIsDecoder = false;
863 //}
864 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800865 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000866 Wait(1000);
867
kwiberg1fd4a4a2015-11-03 11:20:50 -0800868 myCodec->pltype = currentPayload;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000869 if (!_randomTest) {
870 fprintf(stdout,
871 "Register receive codec with default Payload, AUDIO BACK.\n");
872 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000873 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800874 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
875 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000876 myEvent->Wait(20);
877 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000878 WriteLockScoped wl(_apiTestRWLock);
879 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000880 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000881 Wait(1000);
882
883 break;
884 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000885 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000886 if (i == 32) {
kwiberg1fd4a4a2015-11-03 11:20:50 -0800887 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000888 {
889 WriteLockScoped wl(_apiTestRWLock);
890 *thereIsDecoder = true;
891 }
892 }
893 } else {
894 if (!_randomTest) {
895 fprintf(stdout,
896 "Register receive codec with fixed Payload, AUDIO BACK.\n");
897 fflush (stdout);
898 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800899 CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
900 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
901 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000902 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000903 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000904 WriteLockScoped wl(_apiTestRWLock);
905 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000906 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000907 }
908 delete myEvent;
909 if (!_randomTest) {
910 fprintf(stdout,
911 "---------------------------------------------------------\n");
912 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000913}
914
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000915void APITest::TestSendVAD(char side) {
916 if (_randomTest) {
917 return;
918 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000919
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000920 bool* vad;
921 bool* dtx;
922 ACMVADMode* mode;
923 Channel* myChannel;
924 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +0000925
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000926 CodecInst myCodec;
927 if (!_randomTest) {
928 fprintf(stdout, "\n\n");
929 fprintf(stdout, "-----------------------------------------------\n");
930 fprintf(stdout, " Test VAD API\n");
931 fprintf(stdout, "-----------------------------------------------\n");
932 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000933
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000934 if (side == 'A') {
935 AudioCodingModule::Codec(_codecCntrA, &myCodec);
936 vad = &_sendVADA;
937 dtx = &_sendDTXA;
938 mode = &_sendVADModeA;
939 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000940 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000941 } else {
942 AudioCodingModule::Codec(_codecCntrB, &myCodec);
943 vad = &_sendVADB;
944 dtx = &_sendDTXB;
945 mode = &_sendVADModeB;
946 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000947 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000948 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000949
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000950 CheckVADStatus(side);
951 if (!_randomTest) {
952 fprintf(stdout, "\n\n");
953 }
954
955 switch (*mode) {
956 case VADNormal:
957 *vad = true;
958 *dtx = true;
959 *mode = VADAggr;
960 break;
961 case VADLowBitrate:
962 *vad = true;
963 *dtx = true;
964 *mode = VADVeryAggr;
965 break;
966 case VADAggr:
967 *vad = true;
968 *dtx = true;
969 *mode = VADLowBitrate;
970 break;
971 case VADVeryAggr:
972 *vad = false;
973 *dtx = false;
974 *mode = VADNormal;
975 break;
976 default:
977 *mode = VADNormal;
978 }
979
980 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
981
982 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
983 myChannel->ResetStats();
984
985 CheckVADStatus(side);
986 if (!_randomTest) {
987 fprintf(stdout, "\n");
988 fprintf(stdout, "-----------------------------------------------\n");
989 }
990
991 // Fault Test
992 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
993 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +0000994
995}
996
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000997void APITest::CurrentCodec(char side) {
kwiberg1fd4a4a2015-11-03 11:20:50 -0800998 auto myCodec = (side == 'A' ? _acmA : _acmB)->SendCodec();
niklase@google.com470e71d2011-07-07 08:21:25 +0000999
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001000 if (!_randomTest) {
1001 fprintf(stdout, "\n\n");
1002 fprintf(stdout, "Send codec in Side A\n");
1003 fprintf(stdout, "----------------------------\n");
kwiberg1fd4a4a2015-11-03 11:20:50 -08001004 fprintf(stdout, "Name................. %s\n", myCodec->plname);
1005 fprintf(stdout, "Sampling Frequency... %d\n", myCodec->plfreq);
1006 fprintf(stdout, "Rate................. %d\n", myCodec->rate);
1007 fprintf(stdout, "Payload-type......... %d\n", myCodec->pltype);
1008 fprintf(stdout, "Packet-size.......... %d\n", myCodec->pacsize);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001009 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001010
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001011 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001012}
1013
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001014void APITest::ChangeCodec(char side) {
1015 CodecInst myCodec;
1016 AudioCodingModule* myACM;
1017 uint8_t* codecCntr;
1018 bool* thereIsEncoder;
1019 bool* vad;
1020 bool* dtx;
1021 ACMVADMode* mode;
1022 Channel* myChannel;
1023 // Reset and Wait
1024 if (!_randomTest) {
1025 fprintf(stdout, "Reset Encoder Side A \n");
1026 }
1027 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001028 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001029 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001030 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001031 WriteLockScoped wl(_apiTestRWLock);
1032 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001033 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001034 vad = &_sendVADA;
1035 dtx = &_sendDTXA;
1036 mode = &_sendVADModeA;
1037 myChannel = _channel_A2B;
1038 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001039 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001040 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001041 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001042 WriteLockScoped wl(_apiTestRWLock);
1043 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001044 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001045 vad = &_sendVADB;
1046 dtx = &_sendDTXB;
1047 mode = &_sendVADModeB;
1048 myChannel = _channel_B2A;
1049 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001050
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001051 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001052
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001053 // Register the next codec
1054 do {
1055 *codecCntr =
1056 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1057 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001058
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001059 if (*codecCntr == 0) {
1060 //printf("Initialize Sender Side A \n");
1061 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001062 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001063 *thereIsEncoder = false;
1064 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001065 // After Initialization CN is lost, re-register them
1066 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1067 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1068 }
1069 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1070 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1071 }
1072 // VAD & DTX are disabled after initialization
1073 *vad = false;
1074 *dtx = false;
1075 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001076 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001077
1078 AudioCodingModule::Codec(*codecCntr, &myCodec);
1079 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1080 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1081 || !STR_CASE_CMP(myCodec.plname, "RED"));
1082
1083 if (!_randomTest) {
1084 fprintf(stdout,"\n=====================================================\n");
1085 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1086 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1087 }
1088 //std::cout<< std::flush;
1089
1090 // NO DTX for supe-wideband codec at this point
1091 if (myCodec.plfreq == 32000) {
1092 *dtx = false;
1093 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1094
1095 }
1096
1097 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1098 myChannel->ResetStats();
1099 {
1100 WriteLockScoped wl(_apiTestRWLock);
1101 *thereIsEncoder = true;
1102 }
1103 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001104}
1105
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001106} // namespace webrtc