blob: 1b9981341b504ff28e076727f3b1cc66f41cf5df [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"
kwibergda2bf4e2016-10-24 13:47:09 -070026#include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h"
kjellander3e6db232015-11-26 04:44:54 -080027#include "webrtc/modules/audio_coding/test/utility.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010028#include "webrtc/system_wrappers/include/event_wrapper.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010029#include "webrtc/system_wrappers/include/trace.h"
kwibergac9f8762016-09-30 22:29:43 -070030#include "webrtc/test/gtest.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000031#include "webrtc/test/testsupport/fileutils.h"
henrik.lundina9a6d4b2016-12-12 05:03:02 -080032#include "webrtc/typedefs.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
solenberg88499ec2016-09-07 07:34:41 -070051APITest::APITest()
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;
kwibergda2bf4e2016-10-24 13:47:09 -0700145 EXPECT_EQ(true, _acmB->RegisterReceiveCodec(dummyCodec.pltype,
146 CodecInstToSdp(dummyCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000147 dummyCodec.pltype = currentPayloadType;
148 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000149
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000150 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
151 // test if re-registration works;
152 CodecInst nextCodec;
153 int currentPayloadType = dummyCodec.pltype;
154 AudioCodingModule::Codec(n + 1, &nextCodec);
155 dummyCodec.pltype = nextCodec.pltype;
156 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
kwibergda2bf4e2016-10-24 13:47:09 -0700157 _acmB->RegisterReceiveCodec(dummyCodec.pltype,
158 CodecInstToSdp(dummyCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000159 }
160 dummyCodec.pltype = currentPayloadType;
161 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000162
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000163 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
164 // test if un-registration works;
165 CodecInst nextCodec;
166 AudioCodingModule::Codec(n + 1, &nextCodec);
167 nextCodec.pltype = dummyCodec.pltype;
168 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
kwibergda2bf4e2016-10-24 13:47:09 -0700169 EXPECT_EQ(true, _acmA->RegisterReceiveCodec(nextCodec.pltype,
170 CodecInstToSdp(nextCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000171 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
172 }
173 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000174
kwibergda2bf4e2016-10-24 13:47:09 -0700175 EXPECT_EQ(true, _acmA->RegisterReceiveCodec(dummyCodec.pltype,
176 CodecInstToSdp(dummyCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000177 printf(" side A done!");
kwibergda2bf4e2016-10-24 13:47:09 -0700178 EXPECT_EQ(true, _acmB->RegisterReceiveCodec(dummyCodec.pltype,
179 CodecInstToSdp(dummyCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000180 printf(" side B done!\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000181
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000182 if (!strcmp(dummyCodec.plname, "CN")) {
183 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
184 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
185 }
186 lastPayloadType = dummyCodec.pltype;
187 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
188 _payloadUsed[lastPayloadType - 96] = true;
189 }
190 }
191 _thereIsDecoderA = true;
192 _thereIsDecoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000193
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000194 // Register Send Codec
195 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
196 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
197 _thereIsEncoderA = true;
198 //
199 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
200 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
201 _thereIsEncoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000202
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000203 uint16_t frequencyHz;
niklase@google.com470e71d2011-07-07 08:21:25 +0000204
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000205 printf("\n\nAPI Test\n");
206 printf("========\n");
207 printf("Hit enter to accept the default values indicated in []\n\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000208
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000209 //--- Input A
210 std::string file_name = webrtc::test::ResourcePath(
211 "audio_coding/testfile32kHz", "pcm");
212 frequencyHz = 32000;
213 printf("Enter input file at side A [%s]: ", file_name.c_str());
214 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
215 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000216
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000217 //--- Output A
218 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
219 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
220 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
221 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000222
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000223 //--- Input B
224 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
225 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
226 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
227 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000228
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000229 //--- Output B
230 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
231 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
232 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
233 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000234
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000235 //--- Set A-to-B channel
236 _channel_A2B = new Channel(2);
237 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000238 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000239
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000240 //--- Set B-to-A channel
241 _channel_B2A = new Channel(1);
242 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000243 _channel_B2A->RegisterReceiverACM(_acmA.get());
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000244
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000245 //--- EVENT TIMERS
246 // A
Peter Boström64c03662015-04-08 11:24:19 +0200247 _pullEventA = EventTimerWrapper::Create();
248 _pushEventA = EventTimerWrapper::Create();
249 _processEventA = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000250 _apiEventA = EventWrapper::Create();
251 // B
Peter Boström64c03662015-04-08 11:24:19 +0200252 _pullEventB = EventTimerWrapper::Create();
253 _pushEventB = EventTimerWrapper::Create();
254 _processEventB = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000255 _apiEventB = EventWrapper::Create();
256
257 //--- I/O params
258 // A
259 _outFreqHzA = _outFileA.SamplingFrequency();
260 // B
261 _outFreqHzB = _outFileB.SamplingFrequency();
262
263 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
264
265 char print[11];
266
267 // Create a trace file.
268 Trace::CreateTrace();
269 Trace::SetTraceFile(
270 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
271
272 printf("\nRandom Test (y/n)?");
273 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
274 print[10] = '\0';
275 if (strstr(print, "y") != NULL) {
276 _randomTest = true;
277 _verbose = false;
278 _writeToFile = false;
279 } else {
280 _randomTest = false;
281 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000282 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000283 print[10] = '\0';
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000284 if (strstr(print, "y") == NULL) {
285 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
286 _verbose = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000287 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000288 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000289
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000290 _vadCallbackA = new VADCallback;
291 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000292
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000293 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000294}
295
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000296bool APITest::PushAudioThreadA(void* obj) {
297 return static_cast<APITest*>(obj)->PushAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000298}
299
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000300bool APITest::PushAudioThreadB(void* obj) {
301 return static_cast<APITest*>(obj)->PushAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000302}
303
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000304bool APITest::PullAudioThreadA(void* obj) {
305 return static_cast<APITest*>(obj)->PullAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000306}
307
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000308bool APITest::PullAudioThreadB(void* obj) {
309 return static_cast<APITest*>(obj)->PullAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000310}
311
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000312bool APITest::ProcessThreadA(void* obj) {
313 return static_cast<APITest*>(obj)->ProcessRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000314}
315
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000316bool APITest::ProcessThreadB(void* obj) {
317 return static_cast<APITest*>(obj)->ProcessRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000318}
319
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000320bool APITest::APIThreadA(void* obj) {
321 return static_cast<APITest*>(obj)->APIRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000322}
323
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000324bool APITest::APIThreadB(void* obj) {
325 return static_cast<APITest*>(obj)->APIRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000326}
327
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000328bool APITest::PullAudioRunA() {
329 _pullEventA->Wait(100);
330 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700331 bool muted;
332 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000333 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000335 ReadLockScoped rl(_apiTestRWLock);
336 thereIsDecoder = _thereIsDecoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000338 if (thereIsDecoder) {
339 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000341 } else {
342 if (_writeToFile) {
343 _outFileA.Write10MsData(audioFrame);
344 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000345 }
346 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000347}
348
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000349bool APITest::PullAudioRunB() {
350 _pullEventB->Wait(100);
351 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700352 bool muted;
353 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000354 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000355 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000356 ReadLockScoped rl(_apiTestRWLock);
357 thereIsDecoder = _thereIsDecoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000358 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000359 if (thereIsDecoder) {
360 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
361 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000362 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000363 } else {
364 if (_writeToFile) {
365 _outFileB.Write10MsData(audioFrame);
366 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000367 }
368 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000369}
370
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000371bool APITest::PushAudioRunA() {
372 _pushEventA->Wait(100);
373 AudioFrame audioFrame;
374 _inFileA.Read10MsData(audioFrame);
375 if (_acmA->Add10MsData(audioFrame) < 0) {
376 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000377 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000378 ReadLockScoped rl(_apiTestRWLock);
379 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000381 if (thereIsEncoder) {
382 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
383 }
384 }
385 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000386}
387
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000388bool APITest::PushAudioRunB() {
389 _pushEventB->Wait(100);
390 AudioFrame audioFrame;
391 _inFileB.Read10MsData(audioFrame);
392 if (_acmB->Add10MsData(audioFrame) < 0) {
393 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000394 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000395 ReadLockScoped rl(_apiTestRWLock);
396 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000397 }
398
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000399 if (thereIsEncoder) {
400 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
401 }
402 }
403
404 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000405}
406
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000407bool APITest::ProcessRunA() {
408 _processEventA->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000409 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000410}
411
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000412bool APITest::ProcessRunB() {
413 _processEventB->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000414 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000415}
416
417/*/
418 *
419 * In side A we test the APIs which are related to sender Side.
420 *
421/*/
422
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000423void APITest::RunTest(char thread) {
424 int testNum;
425 {
426 WriteLockScoped cs(_apiTestRWLock);
427 if (thread == 'A') {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700428 _testNumA = (_testNumB + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000429 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000430
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000431 _movingDot[_dotPositionA] = ' ';
432 if (_dotPositionA == 0) {
433 _dotMoveDirectionA = 1;
434 }
435 if (_dotPositionA == 19) {
436 _dotMoveDirectionA = -1;
437 }
438 _dotPositionA += _dotMoveDirectionA;
439 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
440 } else {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700441 _testNumB = (_testNumA + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000442 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000443
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000444 _movingDot[_dotPositionB] = ' ';
445 if (_dotPositionB == 20) {
446 _dotMoveDirectionB = 1;
447 }
448 if (_dotPositionB == 39) {
449 _dotMoveDirectionB = -1;
450 }
451 _dotPositionB += _dotMoveDirectionB;
452 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000453 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000454 //fprintf(stderr, "%c: %d \n", thread, testNum);
455 //fflush(stderr);
456 }
457 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000458 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000459 CurrentCodec('A');
460 ChangeCodec('A');
461 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000462 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000463 if (!_randomTest) {
464 fprintf(stdout, "\nTesting Delay ...\n");
465 }
466 TestDelay('A');
467 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700468 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000469 TestSendVAD('A');
470 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700471 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000472 TestRegisteration('A');
473 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000474 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000475 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000476 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000477 exit(1);
478 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000479}
480
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000481bool APITest::APIRunA() {
482 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000483
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000484 bool randomTest;
485 {
486 ReadLockScoped rl(_apiTestRWLock);
487 randomTest = _randomTest;
488 }
489 if (randomTest) {
490 RunTest('A');
491 } else {
492 CurrentCodec('A');
493 ChangeCodec('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000494 if (_codecCntrA == 0) {
495 fprintf(stdout, "\nTesting Delay ...\n");
496 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000497 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000498 // VAD TEST
499 TestSendVAD('A');
500 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000501 }
502 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000503}
504
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000505bool APITest::APIRunB() {
506 _apiEventB->Wait(50);
507 bool randomTest;
508 {
509 ReadLockScoped rl(_apiTestRWLock);
510 randomTest = _randomTest;
511 }
512 //_apiEventB->Wait(2000);
513 if (randomTest) {
514 RunTest('B');
515 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000516
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000517 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000518}
519
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000520void APITest::Perform() {
521 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000522
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000523 //--- THREADS
524 // A
525 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100526 rtc::PlatformThread myPushAudioThreadA(PushAudioThreadA, this,
527 "PushAudioThreadA");
528 myPushAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000529 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100530 rtc::PlatformThread myPullAudioThreadA(PullAudioThreadA, this,
531 "PullAudioThreadA");
532 myPullAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000533 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100534 rtc::PlatformThread myProcessThreadA(ProcessThreadA, this, "ProcessThreadA");
535 myProcessThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000536 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100537 rtc::PlatformThread myAPIThreadA(APIThreadA, this, "APIThreadA");
538 myAPIThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000539 // B
540 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100541 rtc::PlatformThread myPushAudioThreadB(PushAudioThreadB, this,
542 "PushAudioThreadB");
543 myPushAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000544 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100545 rtc::PlatformThread myPullAudioThreadB(PullAudioThreadB, this,
546 "PullAudioThreadB");
547 myPullAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000548 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100549 rtc::PlatformThread myProcessThreadB(ProcessThreadB, this, "ProcessThreadB");
550 myProcessThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000551 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100552 rtc::PlatformThread myAPIThreadB(APIThreadB, this, "APIThreadB");
553 myAPIThreadB.Start();
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000554
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000555 //_apiEventA->StartTimer(true, 5000);
556 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000557
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000558 _processEventA->StartTimer(true, 10);
559 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000560
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000561 _pullEventA->StartTimer(true, 10);
562 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000563
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000564 _pushEventA->StartTimer(true, 10);
565 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000566
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000567 // Keep main thread waiting for sender/receiver
568 // threads to complete
569 EventWrapper* completeEvent = EventWrapper::Create();
Niels Möllerd28db7f2016-05-10 16:31:47 +0200570 uint64_t startTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000571 uint64_t currentTime;
572 // Run test in 2 minutes (120000 ms).
573 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000574 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000575 //ReadLockScoped rl(_apiTestRWLock);
576 //fprintf(stderr, "\r%s", _movingDot);
577 }
578 //fflush(stderr);
579 completeEvent->Wait(50);
Niels Möllerd28db7f2016-05-10 16:31:47 +0200580 currentTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000581 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000582
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000583 //completeEvent->Wait(0xFFFFFFFF);
584 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
585 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000586
Peter Boström8c38e8b2015-11-26 17:45:47 +0100587 myPushAudioThreadA.Stop();
588 myPullAudioThreadA.Stop();
589 myProcessThreadA.Stop();
590 myAPIThreadA.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000591
Peter Boström8c38e8b2015-11-26 17:45:47 +0100592 myPushAudioThreadB.Stop();
593 myPullAudioThreadB.Stop();
594 myProcessThreadB.Stop();
595 myAPIThreadB.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000596}
597
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000598void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000599
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000600 bool dtxEnabled;
601 bool vadEnabled;
602 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000603
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000604 if (side == 'A') {
605 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
606 _acmA->RegisterVADCallback(NULL);
607 _vadCallbackA->Reset();
608 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000609
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000610 if (!_randomTest) {
611 if (_verbose) {
612 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
613 vadEnabled ? "ON" : "OFF", (int) vadMode);
614 Wait(5000);
615 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
616 } else {
617 Wait(5000);
618 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
619 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
620 (int) vadMode, _channel_A2B->BitRate());
621 }
622 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000623 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000624
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000625 if (dtxEnabled != _sendDTXA) {
626 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000627 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000628 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
629 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
630 }
631 if ((vadMode != _sendVADModeA) && vadEnabled) {
632 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
633 }
634 } else {
635 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
636
637 _acmB->RegisterVADCallback(NULL);
638 _vadCallbackB->Reset();
639 _acmB->RegisterVADCallback(_vadCallbackB);
640
641 if (!_randomTest) {
642 if (_verbose) {
643 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
644 vadEnabled ? "ON" : "OFF", (int) vadMode);
645 Wait(5000);
646 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
647 } else {
648 Wait(5000);
649 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
650 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
651 (int) vadMode, _channel_B2A->BitRate());
652 }
653 _vadCallbackB->PrintFrameTypes();
654 }
655
656 if (dtxEnabled != _sendDTXB) {
657 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
658 }
659 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
660 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
661 }
662 if ((vadMode != _sendVADModeB) && vadEnabled) {
663 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
664 }
665 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000666}
667
668// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000669void APITest::TestDelay(char side) {
670 AudioCodingModule* myACM;
671 Channel* myChannel;
672 int32_t* myMinDelay;
Peter Boström64c03662015-04-08 11:24:19 +0200673 EventTimerWrapper* myEvent = EventTimerWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000674
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000675 uint32_t inTimestamp = 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000676 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000677
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000678 double averageEstimDelay = 0;
679 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000680
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000681 CircularBuffer estimDelayCB(100);
682 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000683
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000684 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000685 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000686 myChannel = _channel_B2A;
687 myMinDelay = &_minDelayA;
688 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000689 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000690 myChannel = _channel_A2B;
691 myMinDelay = &_minDelayB;
692 }
693
694 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
695
696 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700697 rtc::Optional<uint32_t> outTimestamp = myACM->PlayoutTimestamp();
698 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000699
700 if (!_randomTest) {
701 myEvent->StartTimer(true, 30);
702 int n = 0;
703 int settlePoint = 5000;
704 while (n < settlePoint + 400) {
705 myEvent->Wait(1000);
706
707 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700708 outTimestamp = myACM->PlayoutTimestamp();
709 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000710
711 //std::cout << outTimestamp << std::endl << std::flush;
henrik.lundin9a410dd2016-04-06 01:39:22 -0700712 estimDelay = (double)((uint32_t)(inTimestamp - *outTimestamp)) /
713 ((double)myACM->ReceiveFrequency() / 1000.0);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000714
715 estimDelayCB.Update(estimDelay);
716
717 estimDelayCB.ArithMean(averageEstimDelay);
718 //printf("\n %6.1f \n", estimDelay);
719 //std::cout << " " << std::flush;
720
721 if (_verbose) {
722 fprintf(stdout,
723 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
724 *myMinDelay, averageDelay, averageEstimDelay);
725 std::cout << " " << std::flush;
726 }
727 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
728 settlePoint = n;
729 }
730 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000731 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000732 myEvent->StopTimer();
733 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000734
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000735 if ((!_verbose) && (!_randomTest)) {
736 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000737 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000738 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000739
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000740 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000741
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000742 NetworkStatistics networkStat;
743 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000744
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000745 if (!_randomTest) {
746 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
747 fprintf(stdout, "--------------------------------------\n");
748 fprintf(stdout, "buffer-size............. %d\n",
749 networkStat.currentBufferSize);
750 fprintf(stdout, "Preferred buffer-size... %d\n",
751 networkStat.preferredBufferSize);
752 fprintf(stdout, "Peaky jitter mode........%d\n",
753 networkStat.jitterPeaksFound);
754 fprintf(stdout, "packet-size rate........ %d\n",
755 networkStat.currentPacketLossRate);
756 fprintf(stdout, "discard rate............ %d\n",
757 networkStat.currentDiscardRate);
758 fprintf(stdout, "expand rate............. %d\n",
759 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000760 fprintf(stdout, "speech expand rate...... %d\n",
761 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000762 fprintf(stdout, "Preemptive rate......... %d\n",
763 networkStat.currentPreemptiveRate);
764 fprintf(stdout, "Accelerate rate......... %d\n",
765 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000766 fprintf(stdout, "Secondary decoded rate.. %d\n",
767 networkStat.currentSecondaryDecodedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000768 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
769 fprintf(stdout, "Mean waiting time....... %d\n",
770 networkStat.meanWaitingTimeMs);
771 fprintf(stdout, "Median waiting time..... %d\n",
772 networkStat.medianWaitingTimeMs);
773 fprintf(stdout, "Min waiting time........ %d\n",
774 networkStat.minWaitingTimeMs);
775 fprintf(stdout, "Max waiting time........ %d\n",
776 networkStat.maxWaitingTimeMs);
777 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000778
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000779 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000780
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000781 if (!_randomTest) {
782 myEvent->Wait(500);
783 fprintf(stdout, "\n");
784 fprintf(stdout, "\n");
785 }
786 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000787}
788
789// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000790void APITest::TestRegisteration(char sendSide) {
791 AudioCodingModule* sendACM;
792 AudioCodingModule* receiveACM;
793 bool* thereIsDecoder;
794 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000795
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000796 if (!_randomTest) {
797 fprintf(stdout, "\n\n");
798 fprintf(stdout,
799 "---------------------------------------------------------\n");
800 fprintf(stdout, " Unregister/register Receive Codec\n");
801 fprintf(stdout,
802 "---------------------------------------------------------\n");
803 }
804
805 switch (sendSide) {
806 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000807 sendACM = _acmA.get();
808 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000809 thereIsDecoder = &_thereIsDecoderB;
810 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000811 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000812 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000813 sendACM = _acmB.get();
814 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000815 thereIsDecoder = &_thereIsDecoderA;
816 break;
817 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000818 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000819 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
820 sendSide);
821 exit(-1);
822 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000823
kwiberg1fd4a4a2015-11-03 11:20:50 -0800824 auto myCodec = sendACM->SendCodec();
825 if (!myCodec) {
826 CodecInst ci;
827 AudioCodingModule::Codec(_codecCntrA, &ci);
Karl Wibergbe579832015-11-10 22:34:18 +0100828 myCodec = rtc::Optional<CodecInst>(ci);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000829 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000830
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000831 if (!_randomTest) {
832 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
833 fflush (stdout);
834 }
835 {
836 WriteLockScoped wl(_apiTestRWLock);
837 *thereIsDecoder = false;
838 }
839 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800840 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000841 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000842
kwiberg1fd4a4a2015-11-03 11:20:50 -0800843 int currentPayload = myCodec->pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000844
kwiberg1fd4a4a2015-11-03 11:20:50 -0800845 if (!FixedPayloadTypeCodec(myCodec->plname)) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000846 int32_t i;
847 for (i = 0; i < 32; i++) {
848 if (!_payloadUsed[i]) {
849 if (!_randomTest) {
850 fprintf(stdout,
851 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000852 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800853 //myCodec->pltype = i + 96;
854 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
855 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000856 //myEvent->Wait(20);
857 //{
858 // WriteLockScoped wl(_apiTestRWLock);
859 // *thereIsDecoder = true;
860 //}
861 Wait(1000);
862
863 if (!_randomTest) {
864 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000865 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000866 //{
867 // WriteLockScoped wl(_apiTestRWLock);
868 // *thereIsDecoder = false;
869 //}
870 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800871 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000872 Wait(1000);
873
kwiberg1fd4a4a2015-11-03 11:20:50 -0800874 myCodec->pltype = currentPayload;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000875 if (!_randomTest) {
876 fprintf(stdout,
877 "Register receive codec with default Payload, AUDIO BACK.\n");
878 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000879 }
kwibergda2bf4e2016-10-24 13:47:09 -0700880 EXPECT_EQ(true, receiveACM->RegisterReceiveCodec(
881 myCodec->pltype, CodecInstToSdp(*myCodec)));
kwiberg1fd4a4a2015-11-03 11:20:50 -0800882 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000883 myEvent->Wait(20);
884 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000885 WriteLockScoped wl(_apiTestRWLock);
886 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000887 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000888 Wait(1000);
889
890 break;
891 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000892 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000893 if (i == 32) {
kwibergda2bf4e2016-10-24 13:47:09 -0700894 EXPECT_EQ(true, receiveACM->RegisterReceiveCodec(
895 myCodec->pltype, CodecInstToSdp(*myCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000896 {
897 WriteLockScoped wl(_apiTestRWLock);
898 *thereIsDecoder = true;
899 }
900 }
901 } else {
902 if (!_randomTest) {
903 fprintf(stdout,
904 "Register receive codec with fixed Payload, AUDIO BACK.\n");
905 fflush (stdout);
906 }
kwibergda2bf4e2016-10-24 13:47:09 -0700907 EXPECT_EQ(true, receiveACM->RegisterReceiveCodec(myCodec->pltype,
908 CodecInstToSdp(*myCodec)));
kwiberg1fd4a4a2015-11-03 11:20:50 -0800909 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
910 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000911 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000912 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000913 WriteLockScoped wl(_apiTestRWLock);
914 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000915 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000916 }
917 delete myEvent;
918 if (!_randomTest) {
919 fprintf(stdout,
920 "---------------------------------------------------------\n");
921 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000922}
923
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000924void APITest::TestSendVAD(char side) {
925 if (_randomTest) {
926 return;
927 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000928
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000929 bool* vad;
930 bool* dtx;
931 ACMVADMode* mode;
932 Channel* myChannel;
933 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +0000934
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000935 CodecInst myCodec;
936 if (!_randomTest) {
937 fprintf(stdout, "\n\n");
938 fprintf(stdout, "-----------------------------------------------\n");
939 fprintf(stdout, " Test VAD API\n");
940 fprintf(stdout, "-----------------------------------------------\n");
941 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000942
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000943 if (side == 'A') {
944 AudioCodingModule::Codec(_codecCntrA, &myCodec);
945 vad = &_sendVADA;
946 dtx = &_sendDTXA;
947 mode = &_sendVADModeA;
948 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000949 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000950 } else {
951 AudioCodingModule::Codec(_codecCntrB, &myCodec);
952 vad = &_sendVADB;
953 dtx = &_sendDTXB;
954 mode = &_sendVADModeB;
955 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000956 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000957 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000958
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000959 CheckVADStatus(side);
960 if (!_randomTest) {
961 fprintf(stdout, "\n\n");
962 }
963
964 switch (*mode) {
965 case VADNormal:
966 *vad = true;
967 *dtx = true;
968 *mode = VADAggr;
969 break;
970 case VADLowBitrate:
971 *vad = true;
972 *dtx = true;
973 *mode = VADVeryAggr;
974 break;
975 case VADAggr:
976 *vad = true;
977 *dtx = true;
978 *mode = VADLowBitrate;
979 break;
980 case VADVeryAggr:
981 *vad = false;
982 *dtx = false;
983 *mode = VADNormal;
984 break;
985 default:
986 *mode = VADNormal;
987 }
988
989 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
990
991 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
992 myChannel->ResetStats();
993
994 CheckVADStatus(side);
995 if (!_randomTest) {
996 fprintf(stdout, "\n");
997 fprintf(stdout, "-----------------------------------------------\n");
998 }
999
1000 // Fault Test
1001 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1002 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001003
1004}
1005
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001006void APITest::CurrentCodec(char side) {
kwiberg1fd4a4a2015-11-03 11:20:50 -08001007 auto myCodec = (side == 'A' ? _acmA : _acmB)->SendCodec();
niklase@google.com470e71d2011-07-07 08:21:25 +00001008
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001009 if (!_randomTest) {
1010 fprintf(stdout, "\n\n");
1011 fprintf(stdout, "Send codec in Side A\n");
1012 fprintf(stdout, "----------------------------\n");
kwiberg1fd4a4a2015-11-03 11:20:50 -08001013 fprintf(stdout, "Name................. %s\n", myCodec->plname);
1014 fprintf(stdout, "Sampling Frequency... %d\n", myCodec->plfreq);
1015 fprintf(stdout, "Rate................. %d\n", myCodec->rate);
1016 fprintf(stdout, "Payload-type......... %d\n", myCodec->pltype);
1017 fprintf(stdout, "Packet-size.......... %d\n", myCodec->pacsize);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001018 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001019
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001020 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001021}
1022
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001023void APITest::ChangeCodec(char side) {
1024 CodecInst myCodec;
1025 AudioCodingModule* myACM;
1026 uint8_t* codecCntr;
1027 bool* thereIsEncoder;
1028 bool* vad;
1029 bool* dtx;
1030 ACMVADMode* mode;
1031 Channel* myChannel;
1032 // Reset and Wait
1033 if (!_randomTest) {
1034 fprintf(stdout, "Reset Encoder Side A \n");
1035 }
1036 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001037 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001038 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001039 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001040 WriteLockScoped wl(_apiTestRWLock);
1041 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001042 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001043 vad = &_sendVADA;
1044 dtx = &_sendDTXA;
1045 mode = &_sendVADModeA;
1046 myChannel = _channel_A2B;
1047 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001048 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001049 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001050 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001051 WriteLockScoped wl(_apiTestRWLock);
1052 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001053 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001054 vad = &_sendVADB;
1055 dtx = &_sendDTXB;
1056 mode = &_sendVADModeB;
1057 myChannel = _channel_B2A;
1058 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001059
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001060 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001061
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001062 // Register the next codec
1063 do {
1064 *codecCntr =
1065 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1066 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001067
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001068 if (*codecCntr == 0) {
1069 //printf("Initialize Sender Side A \n");
1070 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001071 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001072 *thereIsEncoder = false;
1073 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001074 // After Initialization CN is lost, re-register them
1075 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1076 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1077 }
1078 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1079 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1080 }
1081 // VAD & DTX are disabled after initialization
1082 *vad = false;
1083 *dtx = false;
1084 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001085 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001086
1087 AudioCodingModule::Codec(*codecCntr, &myCodec);
1088 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1089 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1090 || !STR_CASE_CMP(myCodec.plname, "RED"));
1091
1092 if (!_randomTest) {
1093 fprintf(stdout,"\n=====================================================\n");
1094 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1095 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1096 }
1097 //std::cout<< std::flush;
1098
1099 // NO DTX for supe-wideband codec at this point
1100 if (myCodec.plfreq == 32000) {
1101 *dtx = false;
1102 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1103
1104 }
1105
1106 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1107 myChannel->ResetStats();
1108 {
1109 WriteLockScoped wl(_apiTestRWLock);
1110 *thereIsEncoder = true;
1111 }
1112 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001113}
1114
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001115} // namespace webrtc