blob: 541834271417db7d003ea45118c023f3d30c0445 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "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
Mirko Bonadei71207422017-09-15 13:58:09 +020022#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "modules/audio_coding/codecs/audio_format_conversion.h"
24#include "modules/audio_coding/test/utility.h"
25#include "rtc_base/platform_thread.h"
26#include "rtc_base/timeutils.h"
27#include "system_wrappers/include/event_wrapper.h"
28#include "system_wrappers/include/trace.h"
29#include "test/gtest.h"
30#include "test/testsupport/fileutils.h"
Mirko Bonadei71207422017-09-15 13:58:09 +020031#include "typedefs.h" // NOLINT(build/include)
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;
kwibergda2bf4e2016-10-24 13:47:09 -0700144 EXPECT_EQ(true, _acmB->RegisterReceiveCodec(dummyCodec.pltype,
145 CodecInstToSdp(dummyCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000146 dummyCodec.pltype = currentPayloadType;
147 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000148
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000149 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
150 // test if re-registration works;
151 CodecInst nextCodec;
152 int currentPayloadType = dummyCodec.pltype;
153 AudioCodingModule::Codec(n + 1, &nextCodec);
154 dummyCodec.pltype = nextCodec.pltype;
155 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
kwibergda2bf4e2016-10-24 13:47:09 -0700156 _acmB->RegisterReceiveCodec(dummyCodec.pltype,
157 CodecInstToSdp(dummyCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000158 }
159 dummyCodec.pltype = currentPayloadType;
160 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000161
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000162 if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) {
163 // test if un-registration works;
164 CodecInst nextCodec;
165 AudioCodingModule::Codec(n + 1, &nextCodec);
166 nextCodec.pltype = dummyCodec.pltype;
167 if (!FixedPayloadTypeCodec(nextCodec.plname)) {
kwibergda2bf4e2016-10-24 13:47:09 -0700168 EXPECT_EQ(true, _acmA->RegisterReceiveCodec(nextCodec.pltype,
169 CodecInstToSdp(nextCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000170 CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
171 }
172 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000173
kwibergda2bf4e2016-10-24 13:47:09 -0700174 EXPECT_EQ(true, _acmA->RegisterReceiveCodec(dummyCodec.pltype,
175 CodecInstToSdp(dummyCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000176 printf(" side A done!");
kwibergda2bf4e2016-10-24 13:47:09 -0700177 EXPECT_EQ(true, _acmB->RegisterReceiveCodec(dummyCodec.pltype,
178 CodecInstToSdp(dummyCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000179 printf(" side B done!\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000180
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000181 if (!strcmp(dummyCodec.plname, "CN")) {
182 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
183 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
184 }
185 lastPayloadType = dummyCodec.pltype;
186 if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) {
187 _payloadUsed[lastPayloadType - 96] = true;
188 }
189 }
190 _thereIsDecoderA = true;
191 _thereIsDecoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000192
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000193 // Register Send Codec
194 AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec);
195 CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
196 _thereIsEncoderA = true;
197 //
198 AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec);
199 CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
200 _thereIsEncoderB = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000201
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000202 uint16_t frequencyHz;
niklase@google.com470e71d2011-07-07 08:21:25 +0000203
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000204 printf("\n\nAPI Test\n");
205 printf("========\n");
206 printf("Hit enter to accept the default values indicated in []\n\n");
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000207
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000208 //--- Input A
209 std::string file_name = webrtc::test::ResourcePath(
210 "audio_coding/testfile32kHz", "pcm");
211 frequencyHz = 32000;
212 printf("Enter input file at side A [%s]: ", file_name.c_str());
213 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
214 _inFileA.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000215
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000216 //--- Output A
217 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
218 printf("Enter output file at side A [%s]: ", out_file_a.c_str());
219 PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz);
220 _outFileA.Open(out_file_a, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000221
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000222 //--- Input B
223 file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
224 printf("\n\nEnter input file at side B [%s]: ", file_name.c_str());
225 PCMFile::ChooseFile(&file_name, 499, &frequencyHz);
226 _inFileB.Open(file_name, frequencyHz, "rb", true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000227
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000228 //--- Output B
229 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
230 printf("Enter output file at side B [%s]: ", out_file_b.c_str());
231 PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz);
232 _outFileB.Open(out_file_b, frequencyHz, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000233
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000234 //--- Set A-to-B channel
235 _channel_A2B = new Channel(2);
236 CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000237 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000238
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000239 //--- Set B-to-A channel
240 _channel_B2A = new Channel(1);
241 CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000242 _channel_B2A->RegisterReceiverACM(_acmA.get());
tina.legrand@webrtc.org5e7ca602012-06-12 07:16:24 +0000243
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000244 //--- EVENT TIMERS
245 // A
Peter Boström64c03662015-04-08 11:24:19 +0200246 _pullEventA = EventTimerWrapper::Create();
247 _pushEventA = EventTimerWrapper::Create();
248 _processEventA = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000249 _apiEventA = EventWrapper::Create();
250 // B
Peter Boström64c03662015-04-08 11:24:19 +0200251 _pullEventB = EventTimerWrapper::Create();
252 _pushEventB = EventTimerWrapper::Create();
253 _processEventB = EventTimerWrapper::Create();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000254 _apiEventB = EventWrapper::Create();
255
256 //--- I/O params
257 // A
258 _outFreqHzA = _outFileA.SamplingFrequency();
259 // B
260 _outFreqHzB = _outFileB.SamplingFrequency();
261
262 //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");
263
264 char print[11];
265
266 // Create a trace file.
267 Trace::CreateTrace();
268 Trace::SetTraceFile(
269 (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str());
270
271 printf("\nRandom Test (y/n)?");
272 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
273 print[10] = '\0';
274 if (strstr(print, "y") != NULL) {
275 _randomTest = true;
276 _verbose = false;
277 _writeToFile = false;
278 } else {
279 _randomTest = false;
280 printf("\nPrint Tests (y/n)? ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000281 EXPECT_TRUE(fgets(print, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000282 print[10] = '\0';
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000283 if (strstr(print, "y") == NULL) {
284 EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0);
285 _verbose = false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000286 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000287 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000288
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000289 _vadCallbackA = new VADCallback;
290 _vadCallbackB = new VADCallback;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000291
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000292 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000293}
294
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000295bool APITest::PushAudioThreadA(void* obj) {
296 return static_cast<APITest*>(obj)->PushAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000297}
298
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000299bool APITest::PushAudioThreadB(void* obj) {
300 return static_cast<APITest*>(obj)->PushAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000301}
302
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000303bool APITest::PullAudioThreadA(void* obj) {
304 return static_cast<APITest*>(obj)->PullAudioRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000305}
306
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000307bool APITest::PullAudioThreadB(void* obj) {
308 return static_cast<APITest*>(obj)->PullAudioRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000309}
310
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000311bool APITest::ProcessThreadA(void* obj) {
312 return static_cast<APITest*>(obj)->ProcessRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000313}
314
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000315bool APITest::ProcessThreadB(void* obj) {
316 return static_cast<APITest*>(obj)->ProcessRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000317}
318
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000319bool APITest::APIThreadA(void* obj) {
320 return static_cast<APITest*>(obj)->APIRunA();
niklase@google.com470e71d2011-07-07 08:21:25 +0000321}
322
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000323bool APITest::APIThreadB(void* obj) {
324 return static_cast<APITest*>(obj)->APIRunB();
niklase@google.com470e71d2011-07-07 08:21:25 +0000325}
326
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000327bool APITest::PullAudioRunA() {
328 _pullEventA->Wait(100);
329 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700330 bool muted;
331 if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000332 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000334 ReadLockScoped rl(_apiTestRWLock);
335 thereIsDecoder = _thereIsDecoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000336 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000337 if (thereIsDecoder) {
338 fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000340 } else {
341 if (_writeToFile) {
342 _outFileA.Write10MsData(audioFrame);
343 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000344 }
345 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000346}
347
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000348bool APITest::PullAudioRunB() {
349 _pullEventB->Wait(100);
350 AudioFrame audioFrame;
henrik.lundind4ccb002016-05-17 12:21:55 -0700351 bool muted;
352 if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame, &muted) < 0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000353 bool thereIsDecoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000355 ReadLockScoped rl(_apiTestRWLock);
356 thereIsDecoder = _thereIsDecoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000358 if (thereIsDecoder) {
359 fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n");
360 fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000361 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000362 } else {
363 if (_writeToFile) {
364 _outFileB.Write10MsData(audioFrame);
365 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000366 }
367 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000368}
369
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000370bool APITest::PushAudioRunA() {
371 _pushEventA->Wait(100);
372 AudioFrame audioFrame;
373 _inFileA.Read10MsData(audioFrame);
374 if (_acmA->Add10MsData(audioFrame) < 0) {
375 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000376 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000377 ReadLockScoped rl(_apiTestRWLock);
378 thereIsEncoder = _thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000379 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000380 if (thereIsEncoder) {
381 fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n");
382 }
383 }
384 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000385}
386
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000387bool APITest::PushAudioRunB() {
388 _pushEventB->Wait(100);
389 AudioFrame audioFrame;
390 _inFileB.Read10MsData(audioFrame);
391 if (_acmB->Add10MsData(audioFrame) < 0) {
392 bool thereIsEncoder;
niklase@google.com470e71d2011-07-07 08:21:25 +0000393 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000394 ReadLockScoped rl(_apiTestRWLock);
395 thereIsEncoder = _thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +0000396 }
397
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000398 if (thereIsEncoder) {
399 fprintf(stderr, "\n>>>> cannot add audio to B <<<<");
400 }
401 }
402
403 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000404}
405
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000406bool APITest::ProcessRunA() {
407 _processEventA->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000408 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000409}
410
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000411bool APITest::ProcessRunB() {
412 _processEventB->Wait(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000413 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000414}
415
416/*/
417 *
418 * In side A we test the APIs which are related to sender Side.
419 *
420/*/
421
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000422void APITest::RunTest(char thread) {
423 int testNum;
424 {
425 WriteLockScoped cs(_apiTestRWLock);
426 if (thread == 'A') {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700427 _testNumA = (_testNumB + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000428 testNum = _testNumA;
niklase@google.com470e71d2011-07-07 08:21:25 +0000429
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000430 _movingDot[_dotPositionA] = ' ';
431 if (_dotPositionA == 0) {
432 _dotMoveDirectionA = 1;
433 }
434 if (_dotPositionA == 19) {
435 _dotMoveDirectionA = -1;
436 }
437 _dotPositionA += _dotMoveDirectionA;
438 _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<';
439 } else {
henrik.lundin1bd0e032015-09-28 06:12:17 -0700440 _testNumB = (_testNumA + 1 + (rand() % 3)) % 4;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000441 testNum = _testNumB;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000442
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000443 _movingDot[_dotPositionB] = ' ';
444 if (_dotPositionB == 20) {
445 _dotMoveDirectionB = 1;
446 }
447 if (_dotPositionB == 39) {
448 _dotMoveDirectionB = -1;
449 }
450 _dotPositionB += _dotMoveDirectionB;
451 _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<';
niklase@google.com470e71d2011-07-07 08:21:25 +0000452 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000453 //fprintf(stderr, "%c: %d \n", thread, testNum);
454 //fflush(stderr);
455 }
456 switch (testNum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000457 case 0:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000458 CurrentCodec('A');
459 ChangeCodec('A');
460 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000461 case 1:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000462 if (!_randomTest) {
463 fprintf(stdout, "\nTesting Delay ...\n");
464 }
465 TestDelay('A');
466 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700467 case 2:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000468 TestSendVAD('A');
469 break;
henrik.lundin1bd0e032015-09-28 06:12:17 -0700470 case 3:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000471 TestRegisteration('A');
472 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000473 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000474 fprintf(stderr, "Wrong Test Number\n");
marpan@webrtc.org4765ca52014-11-03 20:10:26 +0000475 getc(stdin);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000476 exit(1);
477 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000478}
479
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000480bool APITest::APIRunA() {
481 _apiEventA->Wait(50);
niklase@google.com470e71d2011-07-07 08:21:25 +0000482
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000483 bool randomTest;
484 {
485 ReadLockScoped rl(_apiTestRWLock);
486 randomTest = _randomTest;
487 }
488 if (randomTest) {
489 RunTest('A');
490 } else {
491 CurrentCodec('A');
492 ChangeCodec('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000493 if (_codecCntrA == 0) {
494 fprintf(stdout, "\nTesting Delay ...\n");
495 TestDelay('A');
niklase@google.com470e71d2011-07-07 08:21:25 +0000496 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000497 // VAD TEST
498 TestSendVAD('A');
499 TestRegisteration('A');
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000500 }
501 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000502}
503
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000504bool APITest::APIRunB() {
505 _apiEventB->Wait(50);
506 bool randomTest;
507 {
508 ReadLockScoped rl(_apiTestRWLock);
509 randomTest = _randomTest;
510 }
511 //_apiEventB->Wait(2000);
512 if (randomTest) {
513 RunTest('B');
514 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000515
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000516 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000517}
518
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000519void APITest::Perform() {
520 SetUp();
niklase@google.com470e71d2011-07-07 08:21:25 +0000521
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000522 //--- THREADS
523 // A
524 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100525 rtc::PlatformThread myPushAudioThreadA(PushAudioThreadA, this,
526 "PushAudioThreadA");
527 myPushAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000528 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100529 rtc::PlatformThread myPullAudioThreadA(PullAudioThreadA, this,
530 "PullAudioThreadA");
531 myPullAudioThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000532 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100533 rtc::PlatformThread myProcessThreadA(ProcessThreadA, this, "ProcessThreadA");
534 myProcessThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000535 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100536 rtc::PlatformThread myAPIThreadA(APIThreadA, this, "APIThreadA");
537 myAPIThreadA.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000538 // B
539 // PUSH
Peter Boström8c38e8b2015-11-26 17:45:47 +0100540 rtc::PlatformThread myPushAudioThreadB(PushAudioThreadB, this,
541 "PushAudioThreadB");
542 myPushAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000543 // PULL
Peter Boström8c38e8b2015-11-26 17:45:47 +0100544 rtc::PlatformThread myPullAudioThreadB(PullAudioThreadB, this,
545 "PullAudioThreadB");
546 myPullAudioThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000547 // Process
Peter Boström8c38e8b2015-11-26 17:45:47 +0100548 rtc::PlatformThread myProcessThreadB(ProcessThreadB, this, "ProcessThreadB");
549 myProcessThreadB.Start();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000550 // API
Peter Boström8c38e8b2015-11-26 17:45:47 +0100551 rtc::PlatformThread myAPIThreadB(APIThreadB, this, "APIThreadB");
552 myAPIThreadB.Start();
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000553
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000554 //_apiEventA->StartTimer(true, 5000);
555 //_apiEventB->StartTimer(true, 5000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000556
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000557 _processEventA->StartTimer(true, 10);
558 _processEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000559
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000560 _pullEventA->StartTimer(true, 10);
561 _pullEventB->StartTimer(true, 10);
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000562
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000563 _pushEventA->StartTimer(true, 10);
564 _pushEventB->StartTimer(true, 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000565
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000566 // Keep main thread waiting for sender/receiver
567 // threads to complete
568 EventWrapper* completeEvent = EventWrapper::Create();
Niels Möllerd28db7f2016-05-10 16:31:47 +0200569 uint64_t startTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000570 uint64_t currentTime;
571 // Run test in 2 minutes (120000 ms).
572 do {
niklase@google.com470e71d2011-07-07 08:21:25 +0000573 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000574 //ReadLockScoped rl(_apiTestRWLock);
575 //fprintf(stderr, "\r%s", _movingDot);
576 }
577 //fflush(stderr);
578 completeEvent->Wait(50);
Niels Möllerd28db7f2016-05-10 16:31:47 +0200579 currentTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000580 } while ((currentTime - startTime) < 120000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000581
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000582 //completeEvent->Wait(0xFFFFFFFF);
583 //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
584 delete completeEvent;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000585
Peter Boström8c38e8b2015-11-26 17:45:47 +0100586 myPushAudioThreadA.Stop();
587 myPullAudioThreadA.Stop();
588 myProcessThreadA.Stop();
589 myAPIThreadA.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000590
Peter Boström8c38e8b2015-11-26 17:45:47 +0100591 myPushAudioThreadB.Stop();
592 myPullAudioThreadB.Stop();
593 myProcessThreadB.Stop();
594 myAPIThreadB.Stop();
niklase@google.com470e71d2011-07-07 08:21:25 +0000595}
596
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000597void APITest::CheckVADStatus(char side) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000598
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000599 bool dtxEnabled;
600 bool vadEnabled;
601 ACMVADMode vadMode;
niklase@google.com470e71d2011-07-07 08:21:25 +0000602
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000603 if (side == 'A') {
604 _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode);
605 _acmA->RegisterVADCallback(NULL);
606 _vadCallbackA->Reset();
607 _acmA->RegisterVADCallback(_vadCallbackA);
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000608
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000609 if (!_randomTest) {
610 if (_verbose) {
611 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
612 vadEnabled ? "ON" : "OFF", (int) vadMode);
613 Wait(5000);
614 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate());
615 } else {
616 Wait(5000);
617 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
618 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
619 (int) vadMode, _channel_A2B->BitRate());
620 }
621 _vadCallbackA->PrintFrameTypes();
niklase@google.com470e71d2011-07-07 08:21:25 +0000622 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000623
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000624 if (dtxEnabled != _sendDTXA) {
625 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000626 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000627 if ((vadEnabled != _sendVADA) && (!dtxEnabled)) {
628 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
629 }
630 if ((vadMode != _sendVADModeA) && vadEnabled) {
631 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
632 }
633 } else {
634 _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode);
635
636 _acmB->RegisterVADCallback(NULL);
637 _vadCallbackB->Reset();
638 _acmB->RegisterVADCallback(_vadCallbackB);
639
640 if (!_randomTest) {
641 if (_verbose) {
642 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF",
643 vadEnabled ? "ON" : "OFF", (int) vadMode);
644 Wait(5000);
645 fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate());
646 } else {
647 Wait(5000);
648 fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n",
649 dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF",
650 (int) vadMode, _channel_B2A->BitRate());
651 }
652 _vadCallbackB->PrintFrameTypes();
653 }
654
655 if (dtxEnabled != _sendDTXB) {
656 fprintf(stderr, ">>> Error Enabling DTX <<<\n");
657 }
658 if ((vadEnabled != _sendVADB) && (!dtxEnabled)) {
659 fprintf(stderr, ">>> Error Enabling VAD <<<\n");
660 }
661 if ((vadMode != _sendVADModeB) && vadEnabled) {
662 fprintf(stderr, ">>> Error setting VAD-mode <<<\n");
663 }
664 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000665}
666
667// Set Min delay, get delay, playout timestamp
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000668void APITest::TestDelay(char side) {
669 AudioCodingModule* myACM;
670 Channel* myChannel;
671 int32_t* myMinDelay;
Peter Boström64c03662015-04-08 11:24:19 +0200672 EventTimerWrapper* myEvent = EventTimerWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000673
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000674 uint32_t inTimestamp = 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000675 double estimDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000676
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000677 double averageEstimDelay = 0;
678 double averageDelay = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000679
brandtr6607d842017-02-11 00:24:10 -0800680 test::CircularBuffer estimDelayCB(100);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000681 estimDelayCB.SetArithMean(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000682
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000683 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000684 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000685 myChannel = _channel_B2A;
686 myMinDelay = &_minDelayA;
687 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000688 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000689 myChannel = _channel_A2B;
690 myMinDelay = &_minDelayB;
691 }
692
693 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
694
695 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700696 rtc::Optional<uint32_t> outTimestamp = myACM->PlayoutTimestamp();
697 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000698
699 if (!_randomTest) {
700 myEvent->StartTimer(true, 30);
701 int n = 0;
702 int settlePoint = 5000;
703 while (n < settlePoint + 400) {
704 myEvent->Wait(1000);
705
706 inTimestamp = myChannel->LastInTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700707 outTimestamp = myACM->PlayoutTimestamp();
708 CHECK_ERROR_MT(outTimestamp ? 0 : -1);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000709
710 //std::cout << outTimestamp << std::endl << std::flush;
henrik.lundin9a410dd2016-04-06 01:39:22 -0700711 estimDelay = (double)((uint32_t)(inTimestamp - *outTimestamp)) /
712 ((double)myACM->ReceiveFrequency() / 1000.0);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000713
714 estimDelayCB.Update(estimDelay);
715
716 estimDelayCB.ArithMean(averageEstimDelay);
717 //printf("\n %6.1f \n", estimDelay);
718 //std::cout << " " << std::flush;
719
720 if (_verbose) {
721 fprintf(stdout,
722 "\rExpected: %4d, retreived: %6.1f, measured: %6.1f",
723 *myMinDelay, averageDelay, averageEstimDelay);
724 std::cout << " " << std::flush;
725 }
726 if ((averageDelay > *myMinDelay) && (n < settlePoint)) {
727 settlePoint = n;
728 }
729 n++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000730 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000731 myEvent->StopTimer();
732 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000733
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000734 if ((!_verbose) && (!_randomTest)) {
735 fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f",
niklase@google.com470e71d2011-07-07 08:21:25 +0000736 *myMinDelay, averageDelay, averageEstimDelay);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000737 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000738
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000739 *myMinDelay = (rand() % 1000) + 1;
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000740
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000741 NetworkStatistics networkStat;
742 CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat));
niklase@google.com470e71d2011-07-07 08:21:25 +0000743
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000744 if (!_randomTest) {
745 fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
746 fprintf(stdout, "--------------------------------------\n");
747 fprintf(stdout, "buffer-size............. %d\n",
748 networkStat.currentBufferSize);
749 fprintf(stdout, "Preferred buffer-size... %d\n",
750 networkStat.preferredBufferSize);
751 fprintf(stdout, "Peaky jitter mode........%d\n",
752 networkStat.jitterPeaksFound);
753 fprintf(stdout, "packet-size rate........ %d\n",
754 networkStat.currentPacketLossRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000755 fprintf(stdout, "expand rate............. %d\n",
756 networkStat.currentExpandRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000757 fprintf(stdout, "speech expand rate...... %d\n",
758 networkStat.currentSpeechExpandRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000759 fprintf(stdout, "Preemptive rate......... %d\n",
760 networkStat.currentPreemptiveRate);
761 fprintf(stdout, "Accelerate rate......... %d\n",
762 networkStat.currentAccelerateRate);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000763 fprintf(stdout, "Secondary decoded rate.. %d\n",
764 networkStat.currentSecondaryDecodedRate);
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200765 fprintf(stdout, "Secondary discarded rate.%d\n",
766 networkStat.currentSecondaryDiscardedRate);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000767 fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
768 fprintf(stdout, "Mean waiting time....... %d\n",
769 networkStat.meanWaitingTimeMs);
770 fprintf(stdout, "Median waiting time..... %d\n",
771 networkStat.medianWaitingTimeMs);
772 fprintf(stdout, "Min waiting time........ %d\n",
773 networkStat.minWaitingTimeMs);
774 fprintf(stdout, "Max waiting time........ %d\n",
775 networkStat.maxWaitingTimeMs);
776 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000777
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000778 CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
niklase@google.com470e71d2011-07-07 08:21:25 +0000779
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000780 if (!_randomTest) {
781 myEvent->Wait(500);
782 fprintf(stdout, "\n");
783 fprintf(stdout, "\n");
784 }
785 delete myEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +0000786}
787
788// Unregister a codec & register again.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000789void APITest::TestRegisteration(char sendSide) {
790 AudioCodingModule* sendACM;
791 AudioCodingModule* receiveACM;
792 bool* thereIsDecoder;
793 EventWrapper* myEvent = EventWrapper::Create();
niklase@google.com470e71d2011-07-07 08:21:25 +0000794
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000795 if (!_randomTest) {
796 fprintf(stdout, "\n\n");
797 fprintf(stdout,
798 "---------------------------------------------------------\n");
799 fprintf(stdout, " Unregister/register Receive Codec\n");
800 fprintf(stdout,
801 "---------------------------------------------------------\n");
802 }
803
804 switch (sendSide) {
805 case 'A': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000806 sendACM = _acmA.get();
807 receiveACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000808 thereIsDecoder = &_thereIsDecoderB;
809 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000810 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000811 case 'B': {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000812 sendACM = _acmB.get();
813 receiveACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000814 thereIsDecoder = &_thereIsDecoderA;
815 break;
816 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000817 default:
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000818 fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n",
819 sendSide);
820 exit(-1);
821 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000822
kwiberg1fd4a4a2015-11-03 11:20:50 -0800823 auto myCodec = sendACM->SendCodec();
824 if (!myCodec) {
825 CodecInst ci;
826 AudioCodingModule::Codec(_codecCntrA, &ci);
Karl Wibergbe579832015-11-10 22:34:18 +0100827 myCodec = rtc::Optional<CodecInst>(ci);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000828 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000829
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000830 if (!_randomTest) {
831 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
832 fflush (stdout);
833 }
834 {
835 WriteLockScoped wl(_apiTestRWLock);
836 *thereIsDecoder = false;
837 }
838 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800839 CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000840 Wait(1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000841
kwiberg1fd4a4a2015-11-03 11:20:50 -0800842 int currentPayload = myCodec->pltype;
niklase@google.com470e71d2011-07-07 08:21:25 +0000843
kwiberg1fd4a4a2015-11-03 11:20:50 -0800844 if (!FixedPayloadTypeCodec(myCodec->plname)) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000845 int32_t i;
846 for (i = 0; i < 32; i++) {
847 if (!_payloadUsed[i]) {
848 if (!_randomTest) {
849 fprintf(stdout,
850 "Register receive codec with new Payload, AUDIO BACK.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000851 }
kwiberg1fd4a4a2015-11-03 11:20:50 -0800852 //myCodec->pltype = i + 96;
853 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
854 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000855 //myEvent->Wait(20);
856 //{
857 // WriteLockScoped wl(_apiTestRWLock);
858 // *thereIsDecoder = true;
859 //}
860 Wait(1000);
861
862 if (!_randomTest) {
863 fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
niklase@google.com470e71d2011-07-07 08:21:25 +0000864 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000865 //{
866 // WriteLockScoped wl(_apiTestRWLock);
867 // *thereIsDecoder = false;
868 //}
869 //myEvent->Wait(20);
kwiberg1fd4a4a2015-11-03 11:20:50 -0800870 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000871 Wait(1000);
872
kwiberg1fd4a4a2015-11-03 11:20:50 -0800873 myCodec->pltype = currentPayload;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000874 if (!_randomTest) {
875 fprintf(stdout,
876 "Register receive codec with default Payload, AUDIO BACK.\n");
877 fflush (stdout);
niklase@google.com470e71d2011-07-07 08:21:25 +0000878 }
kwibergda2bf4e2016-10-24 13:47:09 -0700879 EXPECT_EQ(true, receiveACM->RegisterReceiveCodec(
880 myCodec->pltype, CodecInstToSdp(*myCodec)));
kwiberg1fd4a4a2015-11-03 11:20:50 -0800881 //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000882 myEvent->Wait(20);
883 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000884 WriteLockScoped wl(_apiTestRWLock);
885 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000886 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000887 Wait(1000);
888
889 break;
890 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000891 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000892 if (i == 32) {
kwibergda2bf4e2016-10-24 13:47:09 -0700893 EXPECT_EQ(true, receiveACM->RegisterReceiveCodec(
894 myCodec->pltype, CodecInstToSdp(*myCodec)));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000895 {
896 WriteLockScoped wl(_apiTestRWLock);
897 *thereIsDecoder = true;
898 }
899 }
900 } else {
901 if (!_randomTest) {
902 fprintf(stdout,
903 "Register receive codec with fixed Payload, AUDIO BACK.\n");
904 fflush (stdout);
905 }
kwibergda2bf4e2016-10-24 13:47:09 -0700906 EXPECT_EQ(true, receiveACM->RegisterReceiveCodec(myCodec->pltype,
907 CodecInstToSdp(*myCodec)));
kwiberg1fd4a4a2015-11-03 11:20:50 -0800908 //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype));
909 //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000910 myEvent->Wait(20);
niklase@google.com470e71d2011-07-07 08:21:25 +0000911 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000912 WriteLockScoped wl(_apiTestRWLock);
913 *thereIsDecoder = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000914 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000915 }
916 delete myEvent;
917 if (!_randomTest) {
918 fprintf(stdout,
919 "---------------------------------------------------------\n");
920 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000921}
922
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000923void APITest::TestSendVAD(char side) {
924 if (_randomTest) {
925 return;
926 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000927
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000928 bool* vad;
929 bool* dtx;
930 ACMVADMode* mode;
931 Channel* myChannel;
932 AudioCodingModule* myACM;
niklase@google.com470e71d2011-07-07 08:21:25 +0000933
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000934 CodecInst myCodec;
935 if (!_randomTest) {
936 fprintf(stdout, "\n\n");
937 fprintf(stdout, "-----------------------------------------------\n");
938 fprintf(stdout, " Test VAD API\n");
939 fprintf(stdout, "-----------------------------------------------\n");
940 }
andrew@webrtc.orgd7a71d02012-08-01 01:40:02 +0000941
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000942 if (side == 'A') {
943 AudioCodingModule::Codec(_codecCntrA, &myCodec);
944 vad = &_sendVADA;
945 dtx = &_sendDTXA;
946 mode = &_sendVADModeA;
947 myChannel = _channel_A2B;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000948 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000949 } else {
950 AudioCodingModule::Codec(_codecCntrB, &myCodec);
951 vad = &_sendVADB;
952 dtx = &_sendDTXB;
953 mode = &_sendVADModeB;
954 myChannel = _channel_B2A;
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +0000955 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000956 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000957
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000958 CheckVADStatus(side);
959 if (!_randomTest) {
960 fprintf(stdout, "\n\n");
961 }
962
963 switch (*mode) {
964 case VADNormal:
965 *vad = true;
966 *dtx = true;
967 *mode = VADAggr;
968 break;
969 case VADLowBitrate:
970 *vad = true;
971 *dtx = true;
972 *mode = VADVeryAggr;
973 break;
974 case VADAggr:
975 *vad = true;
976 *dtx = true;
977 *mode = VADLowBitrate;
978 break;
979 case VADVeryAggr:
980 *vad = false;
981 *dtx = false;
982 *mode = VADNormal;
983 break;
984 default:
985 *mode = VADNormal;
986 }
987
988 *dtx = (myCodec.plfreq == 32000) ? false : *dtx;
989
990 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
991 myChannel->ResetStats();
992
993 CheckVADStatus(side);
994 if (!_randomTest) {
995 fprintf(stdout, "\n");
996 fprintf(stdout, "-----------------------------------------------\n");
997 }
998
999 // Fault Test
1000 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1));
1001 CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4));
niklase@google.com470e71d2011-07-07 08:21:25 +00001002
1003}
1004
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001005void APITest::CurrentCodec(char side) {
kwiberg1fd4a4a2015-11-03 11:20:50 -08001006 auto myCodec = (side == 'A' ? _acmA : _acmB)->SendCodec();
niklase@google.com470e71d2011-07-07 08:21:25 +00001007
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001008 if (!_randomTest) {
1009 fprintf(stdout, "\n\n");
1010 fprintf(stdout, "Send codec in Side A\n");
1011 fprintf(stdout, "----------------------------\n");
kwiberg1fd4a4a2015-11-03 11:20:50 -08001012 fprintf(stdout, "Name................. %s\n", myCodec->plname);
1013 fprintf(stdout, "Sampling Frequency... %d\n", myCodec->plfreq);
1014 fprintf(stdout, "Rate................. %d\n", myCodec->rate);
1015 fprintf(stdout, "Payload-type......... %d\n", myCodec->pltype);
1016 fprintf(stdout, "Packet-size.......... %d\n", myCodec->pacsize);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001017 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001018
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001019 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001020}
1021
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001022void APITest::ChangeCodec(char side) {
1023 CodecInst myCodec;
1024 AudioCodingModule* myACM;
1025 uint8_t* codecCntr;
1026 bool* thereIsEncoder;
1027 bool* vad;
1028 bool* dtx;
1029 ACMVADMode* mode;
1030 Channel* myChannel;
1031 // Reset and Wait
1032 if (!_randomTest) {
1033 fprintf(stdout, "Reset Encoder Side A \n");
1034 }
1035 if (side == 'A') {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001036 myACM = _acmA.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001037 codecCntr = &_codecCntrA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001038 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001039 WriteLockScoped wl(_apiTestRWLock);
1040 thereIsEncoder = &_thereIsEncoderA;
niklase@google.com470e71d2011-07-07 08:21:25 +00001041 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001042 vad = &_sendVADA;
1043 dtx = &_sendDTXA;
1044 mode = &_sendVADModeA;
1045 myChannel = _channel_A2B;
1046 } else {
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +00001047 myACM = _acmB.get();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001048 codecCntr = &_codecCntrB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001049 {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001050 WriteLockScoped wl(_apiTestRWLock);
1051 thereIsEncoder = &_thereIsEncoderB;
niklase@google.com470e71d2011-07-07 08:21:25 +00001052 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001053 vad = &_sendVADB;
1054 dtx = &_sendDTXB;
1055 mode = &_sendVADModeB;
1056 myChannel = _channel_B2A;
1057 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001058
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001059 Wait(100);
niklase@google.com470e71d2011-07-07 08:21:25 +00001060
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001061 // Register the next codec
1062 do {
1063 *codecCntr =
1064 (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ?
1065 (*codecCntr + 1) : 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001066
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001067 if (*codecCntr == 0) {
1068 //printf("Initialize Sender Side A \n");
1069 {
niklase@google.com470e71d2011-07-07 08:21:25 +00001070 WriteLockScoped wl(_apiTestRWLock);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001071 *thereIsEncoder = false;
1072 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001073 // After Initialization CN is lost, re-register them
1074 if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) {
1075 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1076 }
1077 if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) {
1078 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1079 }
1080 // VAD & DTX are disabled after initialization
1081 *vad = false;
1082 *dtx = false;
1083 _writeToFile = false;
niklase@google.com470e71d2011-07-07 08:21:25 +00001084 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001085
1086 AudioCodingModule::Codec(*codecCntr, &myCodec);
1087 } while (!STR_CASE_CMP(myCodec.plname, "CN")
1088 || !STR_CASE_CMP(myCodec.plname, "telephone-event")
1089 || !STR_CASE_CMP(myCodec.plname, "RED"));
1090
1091 if (!_randomTest) {
1092 fprintf(stdout,"\n=====================================================\n");
1093 fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n",
1094 myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
1095 }
1096 //std::cout<< std::flush;
1097
1098 // NO DTX for supe-wideband codec at this point
1099 if (myCodec.plfreq == 32000) {
1100 *dtx = false;
1101 CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
1102
1103 }
1104
1105 CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
1106 myChannel->ResetStats();
1107 {
1108 WriteLockScoped wl(_apiTestRWLock);
1109 *thereIsEncoder = true;
1110 }
1111 Wait(500);
niklase@google.com470e71d2011-07-07 08:21:25 +00001112}
1113
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +00001114} // namespace webrtc