Bug 1015932 - Shareable OpenSLES engine between cubeb and WebRTC. r=jesup
☠☠ backed out by 1bab131ebe62 ☠ ☠
authorGian-Carlo Pascutto <gpascutto@mozilla.com>
Mon, 28 Jul 2014 11:29:31 +0200
changeset 219270 4058c55db5644f4519db0c400789794e2f2f142b
parent 219269 fedb725da886f0759f1ab21801bec368bf9f3d1f
child 219271 e9b23c66ef1009a9ed38fd399a8ccfb535081637
push id583
push userbhearsum@mozilla.com
push dateMon, 24 Nov 2014 19:04:58 +0000
treeherdermozilla-release@c107e74250f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1015932
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1015932 - Shareable OpenSLES engine between cubeb and WebRTC. r=jesup
content/media/moz.build
content/media/systemservices/OpenSLESProvider.cpp
content/media/systemservices/OpenSLESProvider.h
content/media/systemservices/moz.build
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -4,16 +4,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 PARALLEL_DIRS += [
   'encoder',
   'gmp',
   'mediasource',
   'ogg',
+  'systemservices',
   'webaudio',
   'webvtt'
 ]
 
 TEST_TOOL_DIRS += ['compiledtest']
 
 if CONFIG['MOZ_RAW']:
     PARALLEL_DIRS += ['raw']
new file mode 100644
--- /dev/null
+++ b/content/media/systemservices/OpenSLESProvider.cpp
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "OpenSLESProvider.h"
+#include "prlog.h"
+#include "nsDebug.h"
+#include "mozilla/NullPtr.h"
+
+#include <dlfcn.h>
+#include <SLES/OpenSLES_Android.h>
+#include <SLES/OpenSLES_AndroidConfiguration.h>
+
+// NSPR_LOG_MODULES=OpenSLESProvider:5
+#undef LOG
+#undef LOG_ENABLED
+#if defined(PR_LOGGING)
+PRLogModuleInfo *gOpenSLESProviderLog;
+#define LOG(args) PR_LOG(gOpenSLESProviderLog, PR_LOG_DEBUG, args)
+#define LOG_ENABLED() PR_LOG_TEST(gLoadManagerLog, 5)
+#else
+#define LOG(args)
+#define LOG_ENABLED() (false)
+#endif
+
+namespace mozilla {
+
+OpenSLESProvider::OpenSLESProvider()
+  : mLock("OpenSLESProvider.mLock"),
+    mSLEngine(nullptr),
+    mSLEngineUsers(0),
+    mOpenSLESLib(nullptr)
+{
+#if defined(PR_LOGGING)
+  if (!gOpenSLESProviderLog)
+    gOpenSLESProviderLog = PR_NewLogModule("OpenSLESProvider");
+  LOG(("OpenSLESProvider being initialized"));
+#endif
+}
+
+OpenSLESProvider::~OpenSLESProvider()
+{
+  if (mOpenSLESLib) {
+    LOG(("OpenSLES Engine was not properly Destroyed"));
+    (void)dlclose(mOpenSLESLib);
+  }
+}
+
+/* static */
+OpenSLESProvider& OpenSLESProvider::getInstance()
+{
+  // This doesn't need a Mutex in C++11 or GCC 4.3+, see N2660 and
+  // https://gcc.gnu.org/projects/cxx0x.html
+  static OpenSLESProvider instance;
+  return instance;
+}
+
+/* static */
+int OpenSLESProvider::Get(SLObjectItf * aObjectm,
+                          SLuint32 aOptionCount,
+                          const SLEngineOption *aOptions)
+{
+  OpenSLESProvider& provider = OpenSLESProvider::getInstance();
+  return provider.GetEngine(aObjectm, aOptionCount, aOptions);
+}
+
+int OpenSLESProvider::GetEngine(SLObjectItf * aObjectm,
+                                SLuint32 aOptionCount,
+                                const SLEngineOption *aOptions)
+{
+  MutexAutoLock lock(mLock);
+  LOG(("Getting OpenSLES engine"));
+  // Bug 1042051: Validate options are the same
+  if (mSLEngine != nullptr) {
+    *aObjectm = mSLEngine;
+    mSLEngineUsers++;
+    LOG(("Returning existing engine, %d users", mSLEngineUsers));
+    return SL_RESULT_SUCCESS;
+  } else {
+    int res = ConstructEngine(aObjectm, aOptionCount, aOptions);
+    if (res == SL_RESULT_SUCCESS) {
+      // Bug 1042051: Store engine options
+      mSLEngine = *aObjectm;
+      mSLEngineUsers++;
+      LOG(("Returning new engine"));
+    } else {
+      LOG(("Error getting engine: %d", res));
+    }
+    return res;
+  }
+}
+
+int OpenSLESProvider::ConstructEngine(SLObjectItf * aObjectm,
+                                      SLuint32 aOptionCount,
+                                      const SLEngineOption *aOptions)
+{
+  mLock.AssertCurrentThreadOwns();
+
+  if (!mOpenSLESLib) {
+    mOpenSLESLib = dlopen("libOpenSLES.so", RTLD_LAZY);
+    if (!mOpenSLESLib) {
+      LOG(("Failed to dlopen OpenSLES library"));
+      return SL_RESULT_MEMORY_FAILURE;
+    }
+  }
+
+  typedef SLresult (*slCreateEngine_t)(SLObjectItf *,
+                                       SLuint32,
+                                       const SLEngineOption *,
+                                       SLuint32,
+                                       const SLInterfaceID *,
+                                       const SLboolean *);
+
+  slCreateEngine_t f_slCreateEngine =
+    (slCreateEngine_t)dlsym(mOpenSLESLib, "slCreateEngine");
+  int result = f_slCreateEngine(aObjectm, aOptionCount, aOptions, 0, NULL, NULL);
+  return result;
+}
+
+/* static */
+void OpenSLESProvider::Destroy(SLObjectItf * aObjectm)
+{
+  OpenSLESProvider& provider = OpenSLESProvider::getInstance();
+  provider.DestroyEngine(aObjectm);
+}
+
+void OpenSLESProvider::DestroyEngine(SLObjectItf * aObjectm)
+{
+  MutexAutoLock lock(mLock);
+  NS_ASSERTION(mOpenSLESLib, "OpenSLES destroy called but library is not open");
+
+  mSLEngineUsers--;
+  LOG(("Freeing engine, %d users left", mSLEngineUsers));
+  if (mSLEngineUsers) {
+    return;
+  }
+
+  (*(*aObjectm))->Destroy(*aObjectm);
+  // This assumes SLObjectItf is a pointer, but given the previous line,
+  // that's a given.
+  *aObjectm = nullptr;
+
+  (void)dlclose(mOpenSLESLib);
+  mOpenSLESLib = nullptr;
+}
+
+} // namespace mozilla
+
+extern "C" {
+int mozilla_get_sles_engine(SLObjectItf * aObjectm,
+                            SLuint32 aOptionCount,
+                            const SLEngineOption *aOptions)
+{
+  return mozilla::OpenSLESProvider::Get(aObjectm, aOptionCount, aOptions);
+}
+
+void mozilla_destroy_sles_engine(SLObjectItf * aObjectm)
+{
+  return mozilla::OpenSLESProvider::Destroy(aObjectm);
+}
+
+}
new file mode 100644
--- /dev/null
+++ b/content/media/systemservices/OpenSLESProvider.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _OPENSLESPROVIDER_H_
+#define _OPENSLESPROVIDER_H_
+
+#include <SLES/OpenSLES.h>
+#include <mozilla/Types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern MOZ_EXPORT
+int mozilla_get_sles_engine(SLObjectItf * aObjectm,
+                            SLuint32 aOptionCount,
+                            const SLEngineOption *aOptions);
+extern MOZ_EXPORT
+void mozilla_destroy_sles_engine(SLObjectItf * aObjectm);
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+#include "mozilla/Mutex.h"
+
+extern PRLogModuleInfo *gOpenSLESProviderLog;
+
+namespace mozilla {
+
+class OpenSLESProvider {
+public:
+    static int Get(SLObjectItf * aObjectm,
+                   SLuint32 aOptionCount,
+                   const SLEngineOption *aOptions);
+    static void Destroy(SLObjectItf * aObjectm);
+private:
+    OpenSLESProvider();
+    ~OpenSLESProvider();
+    OpenSLESProvider(OpenSLESProvider const&); // NO IMPLEMENTATION
+    void operator=(OpenSLESProvider const&);   // NO IMPLEMENTATION
+    static OpenSLESProvider& getInstance();
+    int GetEngine(SLObjectItf * aObjectm,
+                  SLuint32 aOptionCount,
+                  const SLEngineOption *aOptions);
+    int ConstructEngine(SLObjectItf * aObjectm,
+                        SLuint32 aOptionCount,
+                        const SLEngineOption *aOptions);
+    void DestroyEngine(SLObjectItf * aObjectm);
+
+    // Protect all our internal variables
+    mozilla::Mutex mLock;
+    SLObjectItf mSLEngine;
+    int mSLEngineUsers;
+    void *mOpenSLESLib;
+};
+
+} //namespace
+#endif // cplusplus
+
+#endif /* _OPENSLESPROVIDER_H_ */
new file mode 100644
--- /dev/null
+++ b/content/media/systemservices/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
+    EXPORTS += [
+        'OpenSLESProvider.h'
+    ]
+    UNIFIED_SOURCES += [
+        'OpenSLESProvider.cpp',
+    ]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'