OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
11 #include <android/log.h> | |
12 #include <stdio.h> | |
13 #include <string.h> | |
14 #include <unistd.h> | |
15 | |
16 #include "webrtc/voice_engine/test/android/android_test/jni/org_webrtc_voiceengi
ne_test_AndroidTest.h" | |
17 | |
18 #include "webrtc/base/platform_thread.h" | |
19 | |
20 #include "webrtc/voice_engine/include/voe_audio_processing.h" | |
21 #include "webrtc/voice_engine/include/voe_base.h" | |
22 #include "webrtc/voice_engine/include/voe_codec.h" | |
23 #include "webrtc/voice_engine/include/voe_file.h" | |
24 #include "webrtc/voice_engine/include/voe_hardware.h" | |
25 #include "webrtc/voice_engine/include/voe_network.h" | |
26 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" | |
27 #include "webrtc/voice_engine/include/voe_volume_control.h" | |
28 | |
29 #include "webrtc/voice_engine/test/auto_test/voe_test_interface.h" | |
30 | |
31 //#define INIT_FROM_THREAD | |
32 //#define START_CALL_FROM_THREAD | |
33 | |
34 #define WEBRTC_LOG_TAG "*WEBRTCN*" // As in WEBRTC Native... | |
35 #define VALIDATE_BASE_POINTER \ | |
36 if (!veData1.base) \ | |
37 { \ | |
38 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
39 "Base pointer doesn't exist"); \ | |
40 return -1; \ | |
41 } | |
42 #define VALIDATE_CODEC_POINTER \ | |
43 if (!veData1.codec) \ | |
44 { \ | |
45 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
46 "Codec pointer doesn't exist"); \ | |
47 return -1; \ | |
48 } | |
49 #define VALIDATE_FILE_POINTER \ | |
50 if (!veData1.file) \ | |
51 { \ | |
52 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
53 "File pointer doesn't exist"); \ | |
54 return -1; \ | |
55 } | |
56 #define VALIDATE_NETWORK_POINTER \ | |
57 if (!veData1.netw) \ | |
58 { \ | |
59 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
60 "Network pointer doesn't exist"); \ | |
61 return -1; \ | |
62 } | |
63 #define VALIDATE_APM_POINTER \ | |
64 if (!veData1.codec) \ | |
65 { \ | |
66 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
67 "Apm pointer doesn't exist"); \ | |
68 return -1; \ | |
69 } | |
70 #define VALIDATE_VOLUME_POINTER \ | |
71 if (!veData1.volume) \ | |
72 { \ | |
73 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
74 "Volume pointer doesn't exist"); \ | |
75 return -1; \ | |
76 } | |
77 #define VALIDATE_HARDWARE_POINTER \ | |
78 if (!veData1.hardware) \ | |
79 { \ | |
80 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
81 "Hardware pointer doesn't exist"); \ | |
82 return -1; \ | |
83 } | |
84 #define VALIDATE_RTP_RTCP_POINTER \ | |
85 if (!veData1.rtp_rtcp) \ | |
86 { \ | |
87 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \ | |
88 "RTP / RTCP pointer doesn't exist"); \ | |
89 return -1; \ | |
90 } | |
91 | |
92 // Register functions in JNI_OnLoad() | |
93 // How do we ensure that VoE is deleted? JNI_OnUnload? | |
94 // What happens if class is unloaded? When loaded again, NativeInit will be | |
95 // called again. Keep what we have? | |
96 // Should we do something in JNI_OnUnload? | |
97 // General design: create a class or keep global struct with "C" functions? | |
98 // Otherwise make sure symbols are as unique as possible. | |
99 | |
100 // TestType enumerator | |
101 enum TestType | |
102 { | |
103 Invalid = -1, | |
104 Standard = 0, | |
105 Extended = 1, | |
106 Stress = 2, | |
107 Unit = 3, | |
108 CPU = 4 | |
109 }; | |
110 | |
111 using namespace webrtc; | |
112 | |
113 class my_transportation; | |
114 | |
115 // VoiceEngine data struct | |
116 typedef struct | |
117 { | |
118 // VoiceEngine | |
119 VoiceEngine* ve; | |
120 // Sub-APIs | |
121 VoEBase* base; | |
122 VoECodec* codec; | |
123 VoEFile* file; | |
124 VoENetwork* netw; | |
125 VoEAudioProcessing* apm; | |
126 VoEVolumeControl* volume; | |
127 VoEHardware* hardware; | |
128 VoERTP_RTCP* rtp_rtcp; | |
129 // Other | |
130 my_transportation* extTrans; | |
131 JavaVM* jvm; | |
132 } VoiceEngineData; | |
133 | |
134 // my_transportation is used when useExtTrans is enabled | |
135 class my_transportation : public Transport | |
136 { | |
137 public: | |
138 my_transportation(VoENetwork * network) : | |
139 netw(network) { | |
140 } | |
141 | |
142 int SendPacket(int channel, const void* data, size_t len) override; | |
143 int SendRTCPPacket(int channel, const void* data, size_t len) override; | |
144 | |
145 private: | |
146 VoENetwork * netw; | |
147 }; | |
148 | |
149 int my_transportation::SendPacket(int channel, const void *data, size_t len) | |
150 { | |
151 netw->ReceivedRTPPacket(channel, data, len); | |
152 return len; | |
153 } | |
154 | |
155 int my_transportation::SendRTCPPacket(int channel, const void *data, size_t len) | |
156 { | |
157 netw->ReceivedRTCPPacket(channel, data, len); | |
158 return len; | |
159 } | |
160 | |
161 //Global variables visible in this file | |
162 static VoiceEngineData veData1; | |
163 static VoiceEngineData veData2; | |
164 | |
165 // "Local" functions (i.e. not Java accessible) | |
166 static bool GetSubApis(VoiceEngineData &veData); | |
167 static bool ReleaseSubApis(VoiceEngineData &veData); | |
168 | |
169 class ThreadTest | |
170 { | |
171 public: | |
172 ThreadTest(); | |
173 ~ThreadTest(); | |
174 int RunTest(); | |
175 int CloseTest(); | |
176 private: | |
177 static bool Run(void* ptr); | |
178 bool Process(); | |
179 private: | |
180 rtc::PlatformThread _thread; | |
181 }; | |
182 | |
183 ThreadTest::~ThreadTest() | |
184 { | |
185 if (_thread) | |
186 _thread->Stop(); | |
187 } | |
188 | |
189 ThreadTest::ThreadTest() | |
190 { | |
191 _thread(Run, this, "ThreadTest thread"); | |
192 } | |
193 | |
194 bool ThreadTest::Run(void* ptr) | |
195 { | |
196 return static_cast<ThreadTest*> (ptr)->Process(); | |
197 } | |
198 | |
199 bool ThreadTest::Process() | |
200 { | |
201 // Attach this thread to JVM | |
202 /*JNIEnv* env = NULL; | |
203 jint res = veData1.jvm->AttachCurrentThread(&env, NULL); | |
204 char msg[32]; | |
205 sprintf(msg, "res=%d, env=%d", res, env); | |
206 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, msg);*/ | |
207 | |
208 #ifdef INIT_FROM_THREAD | |
209 VALIDATE_BASE_POINTER; | |
210 veData1.base->Init(); | |
211 #endif | |
212 | |
213 #ifdef START_CALL_FROM_THREAD | |
214 // receiving instance | |
215 veData2.ve = VoiceEngine::Create(); | |
216 GetSubApis(veData2); | |
217 veData2.base->Init(); | |
218 veData2.base->CreateChannel(); | |
219 if(veData2.base->SetLocalReceiver(0, 1234) < 0) | |
220 { | |
221 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
222 "set local receiver 2 failed"); | |
223 } | |
224 veData2.volume->SetSpeakerVolume(204); | |
225 veData2.base->StartReceive(0); | |
226 if(veData2.base->StartPlayout(0) < 0) | |
227 { | |
228 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
229 "start playout failed"); | |
230 } | |
231 | |
232 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
233 "receiving instance started from thread"); | |
234 | |
235 // sending instance | |
236 veData1.ve = VoiceEngine::Create(); | |
237 GetSubApis(veData1); | |
238 veData1.base->Init(); | |
239 if(veData1.base->CreateChannel() < 0) | |
240 { | |
241 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
242 "create channel failed"); | |
243 } | |
244 if(veData1.base->SetLocalReceiver(0, 1256) < 0) | |
245 { | |
246 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
247 "set local receiver failed"); | |
248 } | |
249 if(veData1.base->SetSendDestination(0, 1234, "127.0.0.1") < 0) | |
250 { | |
251 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
252 "set send destination failed"); | |
253 } | |
254 if(veData1.base->StartSend(0) < 0) | |
255 { | |
256 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
257 "start send failed"); | |
258 } | |
259 | |
260 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
261 "sending instance started from thread"); | |
262 #endif | |
263 | |
264 _thread->Stop(); | |
265 | |
266 //res = veData1.jvm->DetachCurrentThread(); | |
267 | |
268 return true; | |
269 } | |
270 | |
271 int ThreadTest::RunTest() | |
272 { | |
273 if (_thread) | |
274 { | |
275 _thread->Start(); | |
276 } | |
277 return 0; | |
278 } | |
279 | |
280 int ThreadTest::CloseTest() | |
281 { | |
282 VALIDATE_BASE_POINTER | |
283 | |
284 veData1.base->DeleteChannel(0); | |
285 veData2.base->DeleteChannel(0); | |
286 veData1.base->Terminate(); | |
287 veData2.base->Terminate(); | |
288 | |
289 // Release sub-APIs | |
290 ReleaseSubApis(veData1); | |
291 ReleaseSubApis(veData2); | |
292 | |
293 // Delete | |
294 VoiceEngine::Delete(veData1.ve); | |
295 VoiceEngine::Delete(veData2.ve); | |
296 veData2.ve = NULL; | |
297 veData2.ve = NULL; | |
298 | |
299 return 0; | |
300 } | |
301 | |
302 ThreadTest threadTest; | |
303 | |
304 ////////////////////////////////////////////////////////////////// | |
305 // General functions | |
306 ////////////////////////////////////////////////////////////////// | |
307 | |
308 ///////////////////////////////////////////// | |
309 // JNI_OnLoad | |
310 // | |
311 jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) | |
312 { | |
313 if (!vm) | |
314 { | |
315 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
316 "JNI_OnLoad did not receive a valid VM pointer"); | |
317 return -1; | |
318 } | |
319 | |
320 // Get JNI | |
321 JNIEnv* env; | |
322 if (JNI_OK != vm->GetEnv(reinterpret_cast<void**> (&env), | |
323 JNI_VERSION_1_4)) | |
324 { | |
325 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
326 "JNI_OnLoad could not get JNI env"); | |
327 return -1; | |
328 } | |
329 | |
330 // Get class to register the native functions with | |
331 // jclass regClass = env->FindClass("webrtc/android/AndroidTest"); | |
332 // if (!regClass) { | |
333 // return -1; // Exception thrown | |
334 // } | |
335 | |
336 // Register native functions | |
337 // JNINativeMethod methods[1]; | |
338 // methods[0].name = NULL; | |
339 // methods[0].signature = NULL; | |
340 // methods[0].fnPtr = NULL; | |
341 // if (JNI_OK != env->RegisterNatives(regClass, methods, 1)) | |
342 // { | |
343 // return -1; | |
344 // } | |
345 | |
346 // Init VoiceEngine data | |
347 memset(&veData1, 0, sizeof(veData1)); | |
348 memset(&veData2, 0, sizeof(veData2)); | |
349 | |
350 // Store the JVM | |
351 veData1.jvm = vm; | |
352 veData2.jvm = vm; | |
353 | |
354 return JNI_VERSION_1_4; | |
355 } | |
356 | |
357 ///////////////////////////////////////////// | |
358 // Native initialization | |
359 // | |
360 JNIEXPORT jboolean JNICALL | |
361 Java_org_webrtc_voiceengine_test_AndroidTest_NativeInit( | |
362 JNIEnv * env, | |
363 jclass) | |
364 { | |
365 // Look up and cache any interesting class, field and method IDs for | |
366 // any used java class here | |
367 | |
368 return true; | |
369 } | |
370 | |
371 ///////////////////////////////////////////// | |
372 // Run auto standard test | |
373 // | |
374 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_RunAutoTest( | |
375 JNIEnv *env, | |
376 jobject context, | |
377 jint testType, | |
378 jint extendedSel) | |
379 { | |
380 TestType tType(Invalid); | |
381 | |
382 switch (testType) | |
383 { | |
384 case 0: | |
385 return 0; | |
386 case 1: | |
387 tType = Standard; | |
388 break; | |
389 case 2: | |
390 tType = Extended; | |
391 break; | |
392 case 3: | |
393 tType = Stress; | |
394 break; | |
395 case 4: | |
396 tType = Unit; | |
397 break; | |
398 default: | |
399 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
400 "RunAutoTest - Invalid TestType"); | |
401 return -1; | |
402 } | |
403 | |
404 // Set instance independent Java objects | |
405 VoiceEngine::SetAndroidObjects(veData1.jvm, env, context); | |
406 | |
407 // Call voe test interface function | |
408 // TODO(leozwang) add autotest setAndroidObjects(veData1.jvm, context); | |
409 // jint retVal = runAutoTest(tType); | |
410 | |
411 // Clear instance independent Java objects | |
412 VoiceEngine::SetAndroidObjects(NULL, NULL, NULL); | |
413 | |
414 return 0; | |
415 } | |
416 | |
417 ////////////////////////////////////////////////////////////////// | |
418 // VoiceEngine API wrapper functions | |
419 ////////////////////////////////////////////////////////////////// | |
420 | |
421 ///////////////////////////////////////////// | |
422 // Create VoiceEngine instance | |
423 // | |
424 JNIEXPORT jboolean JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Create( | |
425 JNIEnv *env, | |
426 jobject context) | |
427 { | |
428 // Check if already created | |
429 if (veData1.ve) | |
430 { | |
431 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
432 "VoE already created"); | |
433 return false; | |
434 } | |
435 | |
436 // Set instance independent Java objects | |
437 VoiceEngine::SetAndroidObjects(veData1.jvm, env, context); | |
438 | |
439 #ifdef START_CALL_FROM_THREAD | |
440 threadTest.RunTest(); | |
441 #else | |
442 // Create | |
443 veData1.ve = VoiceEngine::Create(); | |
444 if (!veData1.ve) | |
445 { | |
446 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
447 "Create VoE failed"); | |
448 return false; | |
449 } | |
450 | |
451 // Get sub-APIs | |
452 if (!GetSubApis(veData1)) | |
453 { | |
454 // If not OK, release all sub-APIs and delete VoE | |
455 ReleaseSubApis(veData1); | |
456 if (!VoiceEngine::Delete(veData1.ve)) | |
457 { | |
458 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
459 "Delete VoE failed"); | |
460 } | |
461 return false; | |
462 } | |
463 #endif | |
464 | |
465 return true; | |
466 } | |
467 | |
468 ///////////////////////////////////////////// | |
469 // Delete VoiceEngine instance | |
470 // | |
471 JNIEXPORT jboolean JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Delete( | |
472 JNIEnv *, | |
473 jobject) | |
474 { | |
475 #ifdef START_CALL_FROM_THREAD | |
476 threadTest.CloseTest(); | |
477 #else | |
478 // Check if exists | |
479 if (!veData1.ve) | |
480 { | |
481 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
482 "VoE does not exist"); | |
483 return false; | |
484 } | |
485 | |
486 // Release sub-APIs | |
487 ReleaseSubApis(veData1); | |
488 | |
489 // Delete | |
490 if (!VoiceEngine::Delete(veData1.ve)) | |
491 { | |
492 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
493 "Delete VoE failed"); | |
494 return false; | |
495 } | |
496 | |
497 veData1.ve = NULL; | |
498 #endif | |
499 | |
500 // Clear instance independent Java objects | |
501 VoiceEngine::SetAndroidObjects(NULL, NULL, NULL); | |
502 | |
503 return true; | |
504 } | |
505 | |
506 ///////////////////////////////////////////// | |
507 // [Base] Initialize VoiceEngine | |
508 // | |
509 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Init( | |
510 JNIEnv *, | |
511 jobject, | |
512 jboolean enableTrace, | |
513 jboolean useExtTrans) | |
514 { | |
515 VALIDATE_BASE_POINTER; | |
516 | |
517 if (enableTrace) | |
518 { | |
519 if (0 != VoiceEngine::SetTraceFile("/sdcard/trace.txt")) | |
520 { | |
521 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
522 "Could not enable trace"); | |
523 } | |
524 if (0 != VoiceEngine::SetTraceFilter(kTraceAll)) | |
525 { | |
526 __android_log_write(ANDROID_LOG_WARN, WEBRTC_LOG_TAG, | |
527 "Could not set trace filter"); | |
528 } | |
529 } | |
530 | |
531 if (useExtTrans) | |
532 { | |
533 VALIDATE_NETWORK_POINTER; | |
534 veData1.extTrans = new my_transportation(veData1.netw); | |
535 } | |
536 | |
537 int retVal = 0; | |
538 #ifdef INIT_FROM_THREAD | |
539 threadTest.RunTest(); | |
540 usleep(200000); | |
541 #else | |
542 retVal = veData1.base->Init(); | |
543 #endif | |
544 return retVal; | |
545 } | |
546 | |
547 ///////////////////////////////////////////// | |
548 // [Base] Terminate VoiceEngine | |
549 // | |
550 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Terminate( | |
551 JNIEnv *, | |
552 jobject) | |
553 { | |
554 VALIDATE_BASE_POINTER; | |
555 | |
556 jint retVal = veData1.base->Terminate(); | |
557 | |
558 delete veData1.extTrans; | |
559 veData1.extTrans = NULL; | |
560 | |
561 return retVal; | |
562 } | |
563 | |
564 ///////////////////////////////////////////// | |
565 // [Base] Create channel | |
566 // | |
567 JNIEXPORT jint JNICALL | |
568 Java_org_webrtc_voiceengine_test_AndroidTest_CreateChannel( | |
569 JNIEnv *, | |
570 jobject) | |
571 { | |
572 VALIDATE_BASE_POINTER; | |
573 jint channel = veData1.base->CreateChannel(); | |
574 | |
575 if (veData1.extTrans) | |
576 { | |
577 VALIDATE_NETWORK_POINTER; | |
578 __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, | |
579 "Enabling external transport on channel %d", | |
580 channel); | |
581 if (veData1.netw->RegisterExternalTransport(channel, *veData1.extTrans) | |
582 < 0) | |
583 { | |
584 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
585 "Could not set external transport"); | |
586 return -1; | |
587 } | |
588 } | |
589 | |
590 return channel; | |
591 } | |
592 | |
593 ///////////////////////////////////////////// | |
594 // [Base] Delete channel | |
595 // | |
596 JNIEXPORT jint JNICALL | |
597 Java_org_webrtc_voiceengine_test_AndroidTest_DeleteChannel( | |
598 JNIEnv *, | |
599 jobject, | |
600 jint channel) | |
601 { | |
602 VALIDATE_BASE_POINTER; | |
603 return veData1.base->DeleteChannel(channel); | |
604 } | |
605 | |
606 ///////////////////////////////////////////// | |
607 // [Base] SetLocalReceiver | |
608 JNIEXPORT jint JNICALL | |
609 Java_org_webrtc_voiceengine_test_AndroidTest_SetLocalReceiver( | |
610 JNIEnv *, | |
611 jobject, | |
612 jint channel, | |
613 jint port) | |
614 { | |
615 VALIDATE_BASE_POINTER; | |
616 return veData1.base->SetLocalReceiver(channel, port); | |
617 } | |
618 | |
619 ///////////////////////////////////////////// | |
620 // [Base] SetSendDestination | |
621 // | |
622 JNIEXPORT jint JNICALL | |
623 Java_org_webrtc_voiceengine_test_AndroidTest_SetSendDestination( | |
624 JNIEnv *env, | |
625 jobject, | |
626 jint channel, | |
627 jint port, | |
628 jstring ipaddr) | |
629 { | |
630 VALIDATE_BASE_POINTER; | |
631 | |
632 const char* ipaddrNative = env->GetStringUTFChars(ipaddr, NULL); | |
633 if (!ipaddrNative) | |
634 { | |
635 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
636 "Could not get UTF string"); | |
637 return -1; | |
638 } | |
639 | |
640 jint retVal = veData1.base->SetSendDestination(channel, port, ipaddrNative); | |
641 | |
642 env->ReleaseStringUTFChars(ipaddr, ipaddrNative); | |
643 | |
644 return retVal; | |
645 } | |
646 | |
647 ///////////////////////////////////////////// | |
648 // [Base] StartListen | |
649 // | |
650 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StartListen( | |
651 JNIEnv *, | |
652 jobject, | |
653 jint channel) | |
654 { | |
655 VALIDATE_BASE_POINTER; | |
656 int retVal = veData1.base->StartReceive(channel); | |
657 | |
658 return retVal; | |
659 } | |
660 | |
661 ///////////////////////////////////////////// | |
662 // [Base] Start playout | |
663 // | |
664 JNIEXPORT jint JNICALL | |
665 Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayout( | |
666 JNIEnv *, | |
667 jobject, | |
668 jint channel) | |
669 { | |
670 VALIDATE_BASE_POINTER; | |
671 int retVal = veData1.base->StartPlayout(channel); | |
672 | |
673 return retVal; | |
674 } | |
675 | |
676 ///////////////////////////////////////////// | |
677 // [Base] Start send | |
678 // | |
679 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StartSend( | |
680 JNIEnv *, | |
681 jobject, | |
682 jint channel) | |
683 { | |
684 /* int dscp(0), serviceType(-1), overrideDscp(0), res(0); | |
685 bool gqosEnabled(false), useSetSockOpt(false); | |
686 | |
687 if (veData1.netw->SetSendTOS(channel, 13, useSetSockOpt) != 0) | |
688 { | |
689 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
690 "Failed to set TOS"); | |
691 return -1; | |
692 } | |
693 | |
694 res = veData1.netw->GetSendTOS(channel, dscp, useSetSockOpt); | |
695 if (res != 0 || dscp != 13 || useSetSockOpt != true) | |
696 { | |
697 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
698 "Failed to get TOS"); | |
699 return -1; | |
700 } */ | |
701 | |
702 /* if (veData1.rtp_rtcp->SetREDStatus(channel, 1) != 0) | |
703 { | |
704 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
705 "Failed to enable RED"); | |
706 return -1; | |
707 } */ | |
708 | |
709 VALIDATE_BASE_POINTER; | |
710 int retVal = veData1.base->StartSend(channel); | |
711 | |
712 return retVal; | |
713 } | |
714 | |
715 ///////////////////////////////////////////// | |
716 // [Base] Stop listen | |
717 // | |
718 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopListen( | |
719 JNIEnv *, | |
720 jobject, | |
721 jint channel) | |
722 { | |
723 VALIDATE_BASE_POINTER; | |
724 return veData1.base->StopReceive(channel); | |
725 } | |
726 | |
727 ///////////////////////////////////////////// | |
728 // [Base] Stop playout | |
729 // | |
730 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayout( | |
731 JNIEnv *, | |
732 jobject, | |
733 jint channel) | |
734 { | |
735 VALIDATE_BASE_POINTER; | |
736 return veData1.base->StopPlayout(channel); | |
737 } | |
738 | |
739 ///////////////////////////////////////////// | |
740 // [Base] Stop send | |
741 // | |
742 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopSend( | |
743 JNIEnv *, | |
744 jobject, | |
745 jint channel) | |
746 { | |
747 /* if (veData1.rtp_rtcp->SetREDStatus(channel, 0) != 0) | |
748 { | |
749 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
750 "Failed to disable RED"); | |
751 return -1; | |
752 } */ | |
753 | |
754 VALIDATE_BASE_POINTER; | |
755 return veData1.base->StopSend(channel); | |
756 } | |
757 | |
758 ///////////////////////////////////////////// | |
759 // [codec] Number of codecs | |
760 // | |
761 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_NumOfCodecs( | |
762 JNIEnv *, | |
763 jobject) | |
764 { | |
765 VALIDATE_CODEC_POINTER; | |
766 return veData1.codec->NumOfCodecs(); | |
767 } | |
768 | |
769 ///////////////////////////////////////////// | |
770 // [codec] Set send codec | |
771 // | |
772 JNIEXPORT jint JNICALL | |
773 Java_org_webrtc_voiceengine_test_AndroidTest_SetSendCodec( | |
774 JNIEnv *, | |
775 jobject, | |
776 jint channel, | |
777 jint index) | |
778 { | |
779 VALIDATE_CODEC_POINTER; | |
780 | |
781 CodecInst codec; | |
782 | |
783 if (veData1.codec->GetCodec(index, codec) != 0) | |
784 { | |
785 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
786 "Failed to get codec"); | |
787 return -1; | |
788 } | |
789 | |
790 return veData1.codec->SetSendCodec(channel, codec); | |
791 } | |
792 | |
793 ///////////////////////////////////////////// | |
794 // [codec] Set VAD status | |
795 // | |
796 JNIEXPORT jint JNICALL | |
797 Java_org_webrtc_voiceengine_test_AndroidTest_SetVADStatus( | |
798 JNIEnv *, | |
799 jobject, | |
800 jint channel, | |
801 jboolean enable, | |
802 jint mode) | |
803 { | |
804 VALIDATE_CODEC_POINTER; | |
805 | |
806 VadModes VADmode = kVadConventional; | |
807 | |
808 switch (mode) | |
809 { | |
810 case 0: | |
811 break; // already set | |
812 case 1: | |
813 VADmode = kVadAggressiveLow; | |
814 break; | |
815 case 2: | |
816 VADmode = kVadAggressiveMid; | |
817 break; | |
818 case 3: | |
819 VADmode = kVadAggressiveHigh; | |
820 break; | |
821 default: | |
822 VADmode = (VadModes) 17; // force error | |
823 break; | |
824 } | |
825 | |
826 return veData1.codec->SetVADStatus(channel, enable, VADmode); | |
827 } | |
828 | |
829 ///////////////////////////////////////////// | |
830 // [apm] SetNSStatus | |
831 // | |
832 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_SetNSStatus( | |
833 JNIEnv *, | |
834 jobject, | |
835 jboolean enable, | |
836 jint mode) | |
837 { | |
838 VALIDATE_APM_POINTER; | |
839 | |
840 NsModes NSmode = kNsDefault; | |
841 | |
842 switch (mode) | |
843 { | |
844 case 0: | |
845 NSmode = kNsUnchanged; | |
846 break; | |
847 case 1: | |
848 break; // already set | |
849 case 2: | |
850 NSmode = kNsConference; | |
851 break; | |
852 case 3: | |
853 NSmode = kNsLowSuppression; | |
854 break; | |
855 case 4: | |
856 NSmode = kNsModerateSuppression; | |
857 break; | |
858 case 5: | |
859 NSmode = kNsHighSuppression; | |
860 break; | |
861 case 6: | |
862 NSmode = kNsVeryHighSuppression; | |
863 break; | |
864 default: | |
865 NSmode = (NsModes) 17; // force error | |
866 break; | |
867 } | |
868 | |
869 return veData1.apm->SetNsStatus(enable, NSmode); | |
870 } | |
871 | |
872 ///////////////////////////////////////////// | |
873 // [apm] SetAGCStatus | |
874 // | |
875 JNIEXPORT jint JNICALL | |
876 Java_org_webrtc_voiceengine_test_AndroidTest_SetAGCStatus( | |
877 JNIEnv *, | |
878 jobject, | |
879 jboolean enable, | |
880 jint mode) | |
881 { | |
882 VALIDATE_APM_POINTER; | |
883 | |
884 AgcModes AGCmode = kAgcDefault; | |
885 | |
886 switch (mode) | |
887 { | |
888 case 0: | |
889 AGCmode = kAgcUnchanged; | |
890 break; | |
891 case 1: | |
892 break; // already set | |
893 case 2: | |
894 AGCmode = kAgcAdaptiveAnalog; | |
895 break; | |
896 case 3: | |
897 AGCmode = kAgcAdaptiveDigital; | |
898 break; | |
899 case 4: | |
900 AGCmode = kAgcFixedDigital; | |
901 break; | |
902 default: | |
903 AGCmode = (AgcModes) 17; // force error | |
904 break; | |
905 } | |
906 | |
907 /* AgcConfig agcConfig; | |
908 agcConfig.targetLeveldBOv = 3; | |
909 agcConfig.digitalCompressionGaindB = 50; | |
910 agcConfig.limiterEnable = 0; | |
911 | |
912 if (veData1.apm->SetAGCConfig(agcConfig) != 0) | |
913 { | |
914 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
915 "Failed to set AGC config"); | |
916 return -1; | |
917 } */ | |
918 | |
919 return veData1.apm->SetAgcStatus(enable, AGCmode); | |
920 } | |
921 | |
922 ///////////////////////////////////////////// | |
923 // [apm] SetECStatus | |
924 // | |
925 JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_SetECStatus( | |
926 JNIEnv *, | |
927 jobject, | |
928 jboolean enable, | |
929 jint mode) | |
930 { | |
931 VALIDATE_APM_POINTER; | |
932 | |
933 EcModes ECmode = kEcDefault; | |
934 | |
935 switch (mode) | |
936 { | |
937 case 0: | |
938 ECmode = kEcDefault; | |
939 break; | |
940 case 1: | |
941 break; // already set | |
942 case 2: | |
943 ECmode = kEcConference; | |
944 break; | |
945 case 3: | |
946 ECmode = kEcAec; | |
947 break; | |
948 case 4: | |
949 ECmode = kEcAecm; | |
950 break; | |
951 default: | |
952 ECmode = (EcModes) 17; // force error | |
953 break; | |
954 } | |
955 | |
956 return veData1.apm->SetEcStatus(enable, ECmode); | |
957 } | |
958 | |
959 ///////////////////////////////////////////// | |
960 // [File] Start play file locally | |
961 // | |
962 JNIEXPORT jint JNICALL | |
963 Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayingFileLocally( | |
964 JNIEnv * env, | |
965 jobject, | |
966 jint channel, | |
967 jstring fileName, | |
968 jboolean loop) | |
969 { | |
970 VALIDATE_FILE_POINTER; | |
971 | |
972 const char* fileNameNative = env->GetStringUTFChars(fileName, NULL); | |
973 if (!fileNameNative) | |
974 { | |
975 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
976 "Could not get UTF string"); | |
977 return -1; | |
978 } | |
979 | |
980 jint retVal = veData1.file->StartPlayingFileLocally(channel, | |
981 fileNameNative, loop); | |
982 | |
983 env->ReleaseStringUTFChars(fileName, fileNameNative); | |
984 | |
985 return retVal; | |
986 } | |
987 | |
988 ///////////////////////////////////////////// | |
989 // [File] Stop play file locally | |
990 // | |
991 JNIEXPORT jint JNICALL | |
992 Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayingFileLocally( | |
993 JNIEnv *, | |
994 jobject, | |
995 jint channel) | |
996 { | |
997 VALIDATE_FILE_POINTER; | |
998 return veData1.file->StopPlayingFileLocally(channel); | |
999 } | |
1000 | |
1001 /* | |
1002 * Class: org_webrtc_voiceengine_test_AndroidTest | |
1003 * Method: StartRecordingPlayout | |
1004 * Signature: (ILjava/lang/String;Z)I | |
1005 */ | |
1006 JNIEXPORT jint JNICALL | |
1007 Java_org_webrtc_voiceengine_test_AndroidTest_StartRecordingPlayout( | |
1008 JNIEnv * env, | |
1009 jobject, | |
1010 jint channel, | |
1011 jstring fileName, | |
1012 jboolean) | |
1013 { | |
1014 VALIDATE_FILE_POINTER; | |
1015 | |
1016 const char* fileNameNative = env->GetStringUTFChars(fileName, NULL); | |
1017 if (!fileNameNative) | |
1018 { | |
1019 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1020 "Could not get UTF string"); | |
1021 return -1; | |
1022 } | |
1023 | |
1024 jint retVal = veData1.file->StartRecordingPlayout(channel, fileNameNative, | |
1025 0); | |
1026 | |
1027 env->ReleaseStringUTFChars(fileName, fileNameNative); | |
1028 | |
1029 return retVal; | |
1030 } | |
1031 | |
1032 ///////////////////////////////////////////// | |
1033 // [File] Stop Recording Playout | |
1034 // | |
1035 JNIEXPORT jint JNICALL | |
1036 Java_org_webrtc_voiceengine_test_AndroidTest_StopRecordingPlayout( | |
1037 JNIEnv *, | |
1038 jobject, | |
1039 jint channel) | |
1040 { | |
1041 VALIDATE_FILE_POINTER; | |
1042 return veData1.file->StopRecordingPlayout(channel); | |
1043 } | |
1044 | |
1045 ///////////////////////////////////////////// | |
1046 // [File] Start playing file as microphone | |
1047 // | |
1048 JNIEXPORT jint JNICALL | |
1049 Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayingFileAsMicrophone( | |
1050 JNIEnv *env, | |
1051 jobject, | |
1052 jint channel, | |
1053 jstring fileName, | |
1054 jboolean loop) | |
1055 { | |
1056 VALIDATE_FILE_POINTER; | |
1057 | |
1058 const char* fileNameNative = env->GetStringUTFChars(fileName, NULL); | |
1059 if (!fileNameNative) | |
1060 { | |
1061 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1062 "Could not get UTF string"); | |
1063 return -1; | |
1064 } | |
1065 | |
1066 jint retVal = veData1.file->StartPlayingFileAsMicrophone(channel, | |
1067 fileNameNative, | |
1068 loop); | |
1069 | |
1070 env->ReleaseStringUTFChars(fileName, fileNameNative); | |
1071 | |
1072 return retVal; | |
1073 } | |
1074 | |
1075 ///////////////////////////////////////////// | |
1076 // [File] Stop playing file as microphone | |
1077 // | |
1078 JNIEXPORT jint JNICALL | |
1079 Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayingFileAsMicrophone( | |
1080 JNIEnv *, | |
1081 jobject, | |
1082 jint channel) | |
1083 { | |
1084 VALIDATE_FILE_POINTER; | |
1085 return veData1.file->StopPlayingFileAsMicrophone(channel); | |
1086 } | |
1087 | |
1088 ///////////////////////////////////////////// | |
1089 // [Volume] Set speaker volume | |
1090 // | |
1091 JNIEXPORT jint JNICALL | |
1092 Java_org_webrtc_voiceengine_test_AndroidTest_SetSpeakerVolume( | |
1093 JNIEnv *, | |
1094 jobject, | |
1095 jint level) | |
1096 { | |
1097 VALIDATE_VOLUME_POINTER; | |
1098 if (veData1.volume->SetSpeakerVolume(level) != 0) | |
1099 { | |
1100 return -1; | |
1101 } | |
1102 | |
1103 unsigned int storedVolume = 0; | |
1104 if (veData1.volume->GetSpeakerVolume(storedVolume) != 0) | |
1105 { | |
1106 return -1; | |
1107 } | |
1108 | |
1109 if (storedVolume != level) | |
1110 { | |
1111 return -1; | |
1112 } | |
1113 | |
1114 return 0; | |
1115 } | |
1116 | |
1117 ////////////////////////////////////////////////////////////////// | |
1118 // "Local" functions (i.e. not Java accessible) | |
1119 ////////////////////////////////////////////////////////////////// | |
1120 | |
1121 ///////////////////////////////////////////// | |
1122 // Get all sub-APIs | |
1123 // | |
1124 bool GetSubApis(VoiceEngineData &veData) | |
1125 { | |
1126 bool getOK = true; | |
1127 | |
1128 // Base | |
1129 veData.base = VoEBase::GetInterface(veData.ve); | |
1130 if (!veData.base) | |
1131 { | |
1132 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1133 "Get base sub-API failed"); | |
1134 getOK = false; | |
1135 } | |
1136 | |
1137 // Codec | |
1138 veData.codec = VoECodec::GetInterface(veData.ve); | |
1139 if (!veData.codec) | |
1140 { | |
1141 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1142 "Get codec sub-API failed"); | |
1143 getOK = false; | |
1144 } | |
1145 | |
1146 // File | |
1147 veData.file = VoEFile::GetInterface(veData.ve); | |
1148 if (!veData.file) | |
1149 { | |
1150 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1151 "Get file sub-API failed"); | |
1152 getOK = false; | |
1153 } | |
1154 | |
1155 // Network | |
1156 veData.netw = VoENetwork::GetInterface(veData.ve); | |
1157 if (!veData.netw) | |
1158 { | |
1159 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1160 "Get network sub-API failed"); | |
1161 getOK = false; | |
1162 } | |
1163 | |
1164 // AudioProcessing module | |
1165 veData.apm = VoEAudioProcessing::GetInterface(veData.ve); | |
1166 if (!veData.apm) | |
1167 { | |
1168 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1169 "Get apm sub-API failed"); | |
1170 getOK = false; | |
1171 } | |
1172 | |
1173 // Volume | |
1174 veData.volume = VoEVolumeControl::GetInterface(veData.ve); | |
1175 if (!veData.volume) | |
1176 { | |
1177 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1178 "Get volume sub-API failed"); | |
1179 getOK = false; | |
1180 } | |
1181 | |
1182 // Hardware | |
1183 veData.hardware = VoEHardware::GetInterface(veData.ve); | |
1184 if (!veData.hardware) | |
1185 { | |
1186 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1187 "Get hardware sub-API failed"); | |
1188 getOK = false; | |
1189 } | |
1190 | |
1191 // RTP / RTCP | |
1192 veData.rtp_rtcp = VoERTP_RTCP::GetInterface(veData.ve); | |
1193 if (!veData.rtp_rtcp) | |
1194 { | |
1195 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1196 "Get rtp_rtcp sub-API failed"); | |
1197 getOK = false; | |
1198 } | |
1199 | |
1200 return getOK; | |
1201 } | |
1202 | |
1203 ///////////////////////////////////////////// | |
1204 // Release all sub-APIs | |
1205 // | |
1206 bool ReleaseSubApis(VoiceEngineData &veData) | |
1207 { | |
1208 bool releaseOK = true; | |
1209 | |
1210 // Base | |
1211 if (veData.base) | |
1212 { | |
1213 if (0 != veData.base->Release()) | |
1214 { | |
1215 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1216 "Release base sub-API failed"); | |
1217 releaseOK = false; | |
1218 } | |
1219 else | |
1220 { | |
1221 veData.base = NULL; | |
1222 } | |
1223 } | |
1224 | |
1225 // Codec | |
1226 if (veData.codec) | |
1227 { | |
1228 if (0 != veData.codec->Release()) | |
1229 { | |
1230 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1231 "Release codec sub-API failed"); | |
1232 releaseOK = false; | |
1233 } | |
1234 else | |
1235 { | |
1236 veData.codec = NULL; | |
1237 } | |
1238 } | |
1239 | |
1240 // File | |
1241 if (veData.file) | |
1242 { | |
1243 if (0 != veData.file->Release()) | |
1244 { | |
1245 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1246 "Release file sub-API failed"); | |
1247 releaseOK = false; | |
1248 } | |
1249 else | |
1250 { | |
1251 veData.file = NULL; | |
1252 } | |
1253 } | |
1254 | |
1255 // Network | |
1256 if (veData.netw) | |
1257 { | |
1258 if (0 != veData.netw->Release()) | |
1259 { | |
1260 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1261 "Release network sub-API failed"); | |
1262 releaseOK = false; | |
1263 } | |
1264 else | |
1265 { | |
1266 veData.netw = NULL; | |
1267 } | |
1268 } | |
1269 | |
1270 // apm | |
1271 if (veData.apm) | |
1272 { | |
1273 if (0 != veData.apm->Release()) | |
1274 { | |
1275 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1276 "Release apm sub-API failed"); | |
1277 releaseOK = false; | |
1278 } | |
1279 else | |
1280 { | |
1281 veData.apm = NULL; | |
1282 } | |
1283 } | |
1284 | |
1285 // Volume | |
1286 if (veData.volume) | |
1287 { | |
1288 if (0 != veData.volume->Release()) | |
1289 { | |
1290 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1291 "Release volume sub-API failed"); | |
1292 releaseOK = false; | |
1293 } | |
1294 else | |
1295 { | |
1296 veData.volume = NULL; | |
1297 } | |
1298 } | |
1299 | |
1300 // Hardware | |
1301 if (veData.hardware) | |
1302 { | |
1303 if (0 != veData.hardware->Release()) | |
1304 { | |
1305 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1306 "Release hardware sub-API failed"); | |
1307 releaseOK = false; | |
1308 } | |
1309 else | |
1310 { | |
1311 veData.hardware = NULL; | |
1312 } | |
1313 } | |
1314 | |
1315 // RTP RTCP | |
1316 if (veData.rtp_rtcp) | |
1317 { | |
1318 if (0 != veData.rtp_rtcp->Release()) | |
1319 { | |
1320 __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, | |
1321 "Release rtp_rtcp sub-API failed"); | |
1322 releaseOK = false; | |
1323 } | |
1324 else | |
1325 { | |
1326 veData.rtp_rtcp = NULL; | |
1327 } | |
1328 } | |
1329 | |
1330 return releaseOK; | |
1331 } | |
OLD | NEW |