summaryrefslogtreecommitdiffstats
path: root/dom/media/systemservices/OpenSLESProvider.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/media/systemservices/OpenSLESProvider.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/media/systemservices/OpenSLESProvider.cpp')
-rw-r--r--dom/media/systemservices/OpenSLESProvider.cpp189
1 files changed, 189 insertions, 0 deletions
diff --git a/dom/media/systemservices/OpenSLESProvider.cpp b/dom/media/systemservices/OpenSLESProvider.cpp
new file mode 100644
index 000000000..c7348afa0
--- /dev/null
+++ b/dom/media/systemservices/OpenSLESProvider.cpp
@@ -0,0 +1,189 @@
+/* -*- 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 "mozilla/Logging.h"
+#include "nsDebug.h"
+
+#include <dlfcn.h>
+#include <SLES/OpenSLES_Android.h>
+#include <SLES/OpenSLES_AndroidConfiguration.h>
+
+// MOZ_LOG=OpenSLESProvider:5
+#undef LOG
+#undef LOG_ENABLED
+mozilla::LazyLogModule gOpenSLESProviderLog("OpenSLESProvider");
+#define LOG(args) MOZ_LOG(gOpenSLESProviderLog, mozilla::LogLevel::Debug, args)
+#define LOG_ENABLED() MOZ_LOG_TEST(gOpenSLESProviderLog, mozilla::LogLevel::Debug)
+
+namespace mozilla {
+
+OpenSLESProvider::OpenSLESProvider()
+ : mLock("OpenSLESProvider.mLock"),
+ mSLEngine(nullptr),
+ mSLEngineUsers(0),
+ mIsRealized(false),
+ mOpenSLESLib(nullptr)
+{
+ LOG(("OpenSLESProvider being initialized"));
+}
+
+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 */
+SLresult OpenSLESProvider::Get(SLObjectItf * aObjectm,
+ SLuint32 aOptionCount,
+ const SLEngineOption *aOptions)
+{
+ OpenSLESProvider& provider = OpenSLESProvider::getInstance();
+ return provider.GetEngine(aObjectm, aOptionCount, aOptions);
+}
+
+SLresult 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;
+ }
+}
+
+SLresult 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;
+ mIsRealized = false;
+}
+
+/* static */
+SLresult OpenSLESProvider::Realize(SLObjectItf aObjectm)
+{
+ OpenSLESProvider& provider = OpenSLESProvider::getInstance();
+ return provider.RealizeEngine(aObjectm);
+}
+
+SLresult OpenSLESProvider::RealizeEngine(SLObjectItf aObjectm)
+{
+ MutexAutoLock lock(mLock);
+ NS_ASSERTION(mOpenSLESLib, "OpenSLES realize called but library is not open");
+ NS_ASSERTION(aObjectm != nullptr, "OpenSLES realize engine with empty ObjectItf");
+
+ if (mIsRealized) {
+ LOG(("Not realizing already realized engine"));
+ return SL_RESULT_SUCCESS;
+ } else {
+ SLresult res = (*aObjectm)->Realize(aObjectm, SL_BOOLEAN_FALSE);
+ if (res != SL_RESULT_SUCCESS) {
+ LOG(("Error realizing OpenSLES engine: %d", res));
+ } else {
+ LOG(("Realized OpenSLES engine"));
+ mIsRealized = true;
+ }
+ return res;
+ }
+}
+
+} // namespace mozilla
+
+extern "C" {
+SLresult 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)
+{
+ mozilla::OpenSLESProvider::Destroy(aObjectm);
+}
+
+SLresult mozilla_realize_sles_engine(SLObjectItf aObjectm)
+{
+ return mozilla::OpenSLESProvider::Realize(aObjectm);
+}
+
+}
+