diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /dom/media/systemservices/OpenSLESProvider.cpp | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/systemservices/OpenSLESProvider.cpp')
-rw-r--r-- | dom/media/systemservices/OpenSLESProvider.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/dom/media/systemservices/OpenSLESProvider.cpp b/dom/media/systemservices/OpenSLESProvider.cpp new file mode 100644 index 0000000000..339fb44f86 --- /dev/null +++ b/dom/media/systemservices/OpenSLESProvider.cpp @@ -0,0 +1,174 @@ +/* -*- 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/IntegerPrintfMacros.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 { + SLresult 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: %lu", static_cast<unsigned long>(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: %lu", + static_cast<unsigned long>(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); +} +} |