1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
2a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1182f014aa0bc225076516a3d77ad02deb69cfd809henrike@webrtc.org#if defined(WEBRTC_ANDROID)
129ee75e9c77b467e74e470905822d0279b0e8a639henrike@webrtc.org#include "webrtc/modules/audio_device/android/audio_device_template.h"
139ee75e9c77b467e74e470905822d0279b0e8a639henrike@webrtc.org#include "webrtc/modules/audio_device/android/audio_record_jni.h"
149ee75e9c77b467e74e470905822d0279b0e8a639henrike@webrtc.org#include "webrtc/modules/audio_device/android/audio_track_jni.h"
15ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/utility/include/jvm_android.h"
168883a0f47fa22fa8194c8afb23006610e2c647abhenrika@webrtc.org#endif
172db85bcba7f77f99b1ee077c7dcd2a017e2a6034leozwang@webrtc.org
1813725089ef91f932b37b2447c3f05d9cd9f89984solenberg#include "webrtc/base/checks.h"
193e6db2321ccdc8738c9cecbe9bdab13d4f0f658dkjellander#include "webrtc/modules/audio_coding/include/audio_coding_module.h"
2013725089ef91f932b37b2447c3f05d9cd9f89984solenberg#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
2198f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/trace.h"
2213725089ef91f932b37b2447c3f05d9cd9f89984solenberg#include "webrtc/voice_engine/channel_proxy.h"
23956aa7e0874f2e08c335a82a2c32f400fac8b031pbos@webrtc.org#include "webrtc/voice_engine/voice_engine_impl.h"
2473d65513f13dc8e5a2d865282be6db69f9067c25henrika@google.com
250d266054acece70259fc1e85026194154f41e5a0Jelena Marusicnamespace webrtc {
26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// Counter to be ensure that we can add a correct ID in all static trace
28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// methods. It is not the nicest solution, especially not since we already
29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// have a counter in VoEBaseImpl. In other words, there is room for
30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// improvement here.
316141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgstatic int32_t gVoiceEngineInstanceCounter = 0;
32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
330d266054acece70259fc1e85026194154f41e5a0Jelena MarusicVoiceEngine* GetVoiceEngine(const Config* config, bool owns_config) {
340d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  VoiceEngineImpl* self = new VoiceEngineImpl(config, owns_config);
350d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  if (self != NULL) {
360d266054acece70259fc1e85026194154f41e5a0Jelena Marusic    self->AddRef();  // First reference.  Released in VoiceEngine::Delete.
370d266054acece70259fc1e85026194154f41e5a0Jelena Marusic    gVoiceEngineInstanceCounter++;
380d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  }
390d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  return self;
40470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
42a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.orgint VoiceEngineImpl::AddRef() {
43a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org  return ++_ref_count;
44a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org}
45a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org
46a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org// This implements the Release() method for all the inherited interfaces.
47a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.orgint VoiceEngineImpl::Release() {
48a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org  int new_ref = --_ref_count;
49a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org  assert(new_ref >= 0);
50a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org  if (new_ref == 0) {
51a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, -1,
520d266054acece70259fc1e85026194154f41e5a0Jelena Marusic                 "VoiceEngineImpl self deleting (voiceEngine=0x%p)", this);
53a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org
54944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org    // Clear any pointers before starting destruction. Otherwise worker-
55944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org    // threads will still have pointers to a partially destructed object.
56944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org    // Example: AudioDeviceBuffer::RequestPlayoutData() can access a
57944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org    // partially deconstructed |_ptrCbAudioTransport| during destruction
58944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org    // if we don't call Terminate here.
59944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org    Terminate();
60a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org    delete this;
61a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org  }
62a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org
63a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org  return new_ref;
64a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org}
65a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org
6613725089ef91f932b37b2447c3f05d9cd9f89984solenbergrtc::scoped_ptr<voe::ChannelProxy> VoiceEngineImpl::GetChannelProxy(
6713725089ef91f932b37b2447c3f05d9cd9f89984solenberg    int channel_id) {
6813725089ef91f932b37b2447c3f05d9cd9f89984solenberg  RTC_DCHECK(channel_id >= 0);
6913725089ef91f932b37b2447c3f05d9cd9f89984solenberg  CriticalSectionScoped cs(crit_sec());
7013725089ef91f932b37b2447c3f05d9cd9f89984solenberg  RTC_DCHECK(statistics().Initialized());
7113725089ef91f932b37b2447c3f05d9cd9f89984solenberg  return rtc::scoped_ptr<voe::ChannelProxy>(
7213725089ef91f932b37b2447c3f05d9cd9f89984solenberg      new voe::ChannelProxy(channel_manager().GetChannel(channel_id)));
7313725089ef91f932b37b2447c3f05d9cd9f89984solenberg}
7413725089ef91f932b37b2447c3f05d9cd9f89984solenberg
75e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.orgVoiceEngine* VoiceEngine::Create() {
76e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org  Config* config = new Config();
77e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org  return GetVoiceEngine(config, true);
78e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org}
79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
80e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.orgVoiceEngine* VoiceEngine::Create(const Config& config) {
81e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org  return GetVoiceEngine(&config, false);
82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
840d266054acece70259fc1e85026194154f41e5a0Jelena Marusicint VoiceEngine::SetTraceFilter(unsigned int filter) {
850d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
860d266054acece70259fc1e85026194154f41e5a0Jelena Marusic               VoEId(gVoiceEngineInstanceCounter, -1),
870d266054acece70259fc1e85026194154f41e5a0Jelena Marusic               "SetTraceFilter(filter=0x%x)", filter);
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
890d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  // Remember old filter
900d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  uint32_t oldFilter = Trace::level_filter();
910d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  Trace::set_level_filter(filter);
92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
930d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  // If previous log was ignored, log again after changing filter
940d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  if (kTraceNone == oldFilter) {
950d266054acece70259fc1e85026194154f41e5a0Jelena Marusic    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, -1, "SetTraceFilter(filter=0x%x)",
960d266054acece70259fc1e85026194154f41e5a0Jelena Marusic                 filter);
970d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  }
98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
990d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  return 0;
100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1020d266054acece70259fc1e85026194154f41e5a0Jelena Marusicint VoiceEngine::SetTraceFile(const char* fileNameUTF8, bool addFileCounter) {
1030d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  int ret = Trace::SetTraceFile(fileNameUTF8, addFileCounter);
1040d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
1050d266054acece70259fc1e85026194154f41e5a0Jelena Marusic               VoEId(gVoiceEngineInstanceCounter, -1),
1060d266054acece70259fc1e85026194154f41e5a0Jelena Marusic               "SetTraceFile(fileNameUTF8=%s, addFileCounter=%d)", fileNameUTF8,
1070d266054acece70259fc1e85026194154f41e5a0Jelena Marusic               addFileCounter);
1080d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  return (ret);
1090d266054acece70259fc1e85026194154f41e5a0Jelena Marusic}
110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1110d266054acece70259fc1e85026194154f41e5a0Jelena Marusicint VoiceEngine::SetTraceCallback(TraceCallback* callback) {
1120d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
1130d266054acece70259fc1e85026194154f41e5a0Jelena Marusic               VoEId(gVoiceEngineInstanceCounter, -1),
1140d266054acece70259fc1e85026194154f41e5a0Jelena Marusic               "SetTraceCallback(callback=0x%x)", callback);
1150d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  return (Trace::SetTraceCallback(callback));
1160d266054acece70259fc1e85026194154f41e5a0Jelena Marusic}
117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1180d266054acece70259fc1e85026194154f41e5a0Jelena Marusicbool VoiceEngine::Delete(VoiceEngine*& voiceEngine) {
1190d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  if (voiceEngine == NULL)
1200d266054acece70259fc1e85026194154f41e5a0Jelena Marusic    return false;
1210d266054acece70259fc1e85026194154f41e5a0Jelena Marusic
1220d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
1230d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  // Release the reference that was added in GetVoiceEngine.
1240d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  int ref = s->Release();
1250d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  voiceEngine = NULL;
1260d266054acece70259fc1e85026194154f41e5a0Jelena Marusic
1270d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  if (ref != 0) {
1280d266054acece70259fc1e85026194154f41e5a0Jelena Marusic    WEBRTC_TRACE(
1290d266054acece70259fc1e85026194154f41e5a0Jelena Marusic        kTraceWarning, kTraceVoice, -1,
1300d266054acece70259fc1e85026194154f41e5a0Jelena Marusic        "VoiceEngine::Delete did not release the very last reference.  "
1310d266054acece70259fc1e85026194154f41e5a0Jelena Marusic        "%d references remain.",
1320d266054acece70259fc1e85026194154f41e5a0Jelena Marusic        ref);
1330d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  }
134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1350d266054acece70259fc1e85026194154f41e5a0Jelena Marusic  return true;
136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1388883a0f47fa22fa8194c8afb23006610e2c647abhenrika@webrtc.org#if !defined(WEBRTC_CHROMIUM_BUILD)
139b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// TODO(henrika): change types to JavaVM* and jobject instead of void*.
1400d266054acece70259fc1e85026194154f41e5a0Jelena Marusicint VoiceEngine::SetAndroidObjects(void* javaVM, void* context) {
141cf1375a1f1698300e6e93cba878575e93777ab34leozwang@webrtc.org#ifdef WEBRTC_ANDROID
142b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika  webrtc::JVM::Initialize(reinterpret_cast<JavaVM*>(javaVM),
143b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika                          reinterpret_cast<jobject>(context));
144573a1b45b5b7638605d9727be57c73e838d6ee45henrike@webrtc.org  return 0;
145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else
1462db85bcba7f77f99b1ee077c7dcd2a017e2a6034leozwang@webrtc.org  return -1;
147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1498883a0f47fa22fa8194c8afb23006610e2c647abhenrika@webrtc.org#endif
150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1512515af28e97213b4a4b89269f6b855378d31e153solenbergstd::string VoiceEngine::GetVersionString() {
1522515af28e97213b4a4b89269f6b855378d31e153solenberg  std::string version = "VoiceEngine 4.1.0";
1532515af28e97213b4a4b89269f6b855378d31e153solenberg#ifdef WEBRTC_EXTERNAL_TRANSPORT
1542515af28e97213b4a4b89269f6b855378d31e153solenberg  version += " (External transport build)";
1552515af28e97213b4a4b89269f6b855378d31e153solenberg#endif
1562515af28e97213b4a4b89269f6b855378d31e153solenberg  return version;
1572515af28e97213b4a4b89269f6b855378d31e153solenberg}
1582515af28e97213b4a4b89269f6b855378d31e153solenberg
159d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org}  // namespace webrtc
160