1 /* 2 * Copyright (c) 2012 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 #if defined(WEBRTC_ANDROID) 12 #include "webrtc/modules/audio_device/android/audio_device_template.h" 13 #include "webrtc/modules/audio_device/android/audio_record_jni.h" 14 #include "webrtc/modules/audio_device/android/audio_track_jni.h" 15 #if !defined(WEBRTC_CHROMIUM_BUILD) 16 #include "webrtc/modules/audio_device/android/opensles_input.h" 17 #include "webrtc/modules/audio_device/android/opensles_output.h" 18 #endif 19 #endif 20 21 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" 22 #include "webrtc/system_wrappers/interface/trace.h" 23 #include "webrtc/voice_engine/voice_engine_impl.h" 24 25 namespace webrtc 26 { 27 28 // Counter to be ensure that we can add a correct ID in all static trace 29 // methods. It is not the nicest solution, especially not since we already 30 // have a counter in VoEBaseImpl. In other words, there is room for 31 // improvement here. 32 static int32_t gVoiceEngineInstanceCounter = 0; 33 34 VoiceEngine* GetVoiceEngine(const Config* config, bool owns_config) 35 { 36 #if (defined _WIN32) 37 HMODULE hmod = LoadLibrary(TEXT("VoiceEngineTestingDynamic.dll")); 38 39 if (hmod) { 40 typedef VoiceEngine* (*PfnGetVoiceEngine)(void); 41 PfnGetVoiceEngine pfn = (PfnGetVoiceEngine)GetProcAddress( 42 hmod,"GetVoiceEngine"); 43 if (pfn) { 44 VoiceEngine* self = pfn(); 45 if (owns_config) { 46 delete config; 47 } 48 return (self); 49 } 50 } 51 #endif 52 53 VoiceEngineImpl* self = new VoiceEngineImpl(config, owns_config); 54 if (self != NULL) 55 { 56 self->AddRef(); // First reference. Released in VoiceEngine::Delete. 57 gVoiceEngineInstanceCounter++; 58 } 59 return self; 60 } 61 62 int VoiceEngineImpl::AddRef() { 63 return ++_ref_count; 64 } 65 66 // This implements the Release() method for all the inherited interfaces. 67 int VoiceEngineImpl::Release() { 68 int new_ref = --_ref_count; 69 assert(new_ref >= 0); 70 if (new_ref == 0) { 71 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, -1, 72 "VoiceEngineImpl self deleting (voiceEngine=0x%p)", 73 this); 74 75 // Clear any pointers before starting destruction. Otherwise worker- 76 // threads will still have pointers to a partially destructed object. 77 // Example: AudioDeviceBuffer::RequestPlayoutData() can access a 78 // partially deconstructed |_ptrCbAudioTransport| during destruction 79 // if we don't call Terminate here. 80 Terminate(); 81 delete this; 82 } 83 84 return new_ref; 85 } 86 87 VoiceEngine* VoiceEngine::Create() { 88 Config* config = new Config(); 89 return GetVoiceEngine(config, true); 90 } 91 92 VoiceEngine* VoiceEngine::Create(const Config& config) { 93 return GetVoiceEngine(&config, false); 94 } 95 96 int VoiceEngine::SetTraceFilter(unsigned int filter) 97 { 98 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, 99 VoEId(gVoiceEngineInstanceCounter, -1), 100 "SetTraceFilter(filter=0x%x)", filter); 101 102 // Remember old filter 103 uint32_t oldFilter = Trace::level_filter(); 104 Trace::set_level_filter(filter); 105 106 // If previous log was ignored, log again after changing filter 107 if (kTraceNone == oldFilter) 108 { 109 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, -1, 110 "SetTraceFilter(filter=0x%x)", filter); 111 } 112 113 return 0; 114 } 115 116 int VoiceEngine::SetTraceFile(const char* fileNameUTF8, 117 bool addFileCounter) 118 { 119 int ret = Trace::SetTraceFile(fileNameUTF8, addFileCounter); 120 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, 121 VoEId(gVoiceEngineInstanceCounter, -1), 122 "SetTraceFile(fileNameUTF8=%s, addFileCounter=%d)", 123 fileNameUTF8, addFileCounter); 124 return (ret); 125 } 126 127 int VoiceEngine::SetTraceCallback(TraceCallback* callback) 128 { 129 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, 130 VoEId(gVoiceEngineInstanceCounter, -1), 131 "SetTraceCallback(callback=0x%x)", callback); 132 return (Trace::SetTraceCallback(callback)); 133 } 134 135 bool VoiceEngine::Delete(VoiceEngine*& voiceEngine) 136 { 137 if (voiceEngine == NULL) 138 return false; 139 140 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine); 141 // Release the reference that was added in GetVoiceEngine. 142 int ref = s->Release(); 143 voiceEngine = NULL; 144 145 if (ref != 0) { 146 WEBRTC_TRACE(kTraceWarning, kTraceVoice, -1, 147 "VoiceEngine::Delete did not release the very last reference. " 148 "%d references remain.", ref); 149 } 150 151 return true; 152 } 153 154 #if !defined(WEBRTC_CHROMIUM_BUILD) 155 int VoiceEngine::SetAndroidObjects(void* javaVM, void* env, void* context) 156 { 157 #ifdef WEBRTC_ANDROID 158 #ifdef WEBRTC_ANDROID_OPENSLES 159 typedef AudioDeviceTemplate<OpenSlesInput, OpenSlesOutput> 160 AudioDeviceInstance; 161 #else 162 typedef AudioDeviceTemplate<AudioRecordJni, AudioTrackJni> 163 AudioDeviceInstance; 164 #endif 165 if (javaVM && env && context) { 166 AudioDeviceInstance::SetAndroidAudioDeviceObjects(javaVM, env, context); 167 } else { 168 AudioDeviceInstance::ClearAndroidAudioDeviceObjects(); 169 } 170 return 0; 171 #else 172 return -1; 173 #endif 174 } 175 #endif 176 177 } // namespace webrtc 178