summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/omx/OmxCoreLibLinker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/platforms/omx/OmxCoreLibLinker.cpp')
-rw-r--r--dom/media/platforms/omx/OmxCoreLibLinker.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/dom/media/platforms/omx/OmxCoreLibLinker.cpp b/dom/media/platforms/omx/OmxCoreLibLinker.cpp
new file mode 100644
index 0000000000..a0ee61ec42
--- /dev/null
+++ b/dom/media/platforms/omx/OmxCoreLibLinker.cpp
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 "OmxCoreLibLinker.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Preferences.h"
+#include "MainThreadUtils.h"
+#include "prlink.h"
+#include "PlatformDecoderModule.h"
+
+#ifdef LOG
+# undef LOG
+#endif
+
+#define LOG(arg, ...) \
+ MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, \
+ ("OmxCoreLibLinker::%s: " arg, __func__, ##__VA_ARGS__))
+
+namespace mozilla {
+
+OmxCoreLibLinker::LinkStatus OmxCoreLibLinker::sLinkStatus = LinkStatus_INIT;
+
+const char* OmxCoreLibLinker::sLibNames[] = {
+ "libopenmaxil.so", // Raspberry Pi
+ "libomxr_core.so", // Renesas R-Car, RZ/G
+ "libomxil-bellagio.so.0", // Bellagio: An OSS implementation of OpenMAX IL
+};
+
+PRLibrary* OmxCoreLibLinker::sLinkedLib = nullptr;
+const char* OmxCoreLibLinker::sLibName = nullptr;
+
+#define OMX_FUNC(func) void (*func)();
+#include "OmxFunctionList.h"
+#undef OMX_FUNC
+
+bool OmxCoreLibLinker::TryLinkingLibrary(const char* libName) {
+ PRLibSpec lspec;
+ lspec.type = PR_LibSpec_Pathname;
+ lspec.value.pathname = libName;
+ sLinkedLib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
+ if (sLinkedLib) {
+ if (Bind(libName)) {
+ sLibName = libName;
+ LOG("Succeeded to load %s", libName);
+ return true;
+ } else {
+ LOG("Failed to link %s", libName);
+ }
+ Unlink();
+ }
+ return false;
+}
+
+/* static */
+bool OmxCoreLibLinker::Link() {
+ LOG("");
+
+ if (sLinkStatus) {
+ return sLinkStatus == LinkStatus_SUCCEEDED;
+ }
+
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoCString libPath;
+ nsresult rv = Preferences::GetCString("media.omx.core-lib-path", libPath);
+ if (NS_SUCCEEDED(rv) && !libPath.IsEmpty()) {
+ if (TryLinkingLibrary(libPath.Data())) {
+ sLinkStatus = LinkStatus_SUCCEEDED;
+ return true;
+ }
+ }
+
+ // try known paths
+ for (size_t i = 0; i < ArrayLength(sLibNames); i++) {
+ if (TryLinkingLibrary(sLibNames[i])) {
+ sLinkStatus = LinkStatus_SUCCEEDED;
+ return true;
+ }
+ }
+ sLinkStatus = LinkStatus_FAILED;
+ return false;
+}
+
+/* static */
+bool OmxCoreLibLinker::Bind(const char* aLibName) {
+#define OMX_FUNC(func) \
+ { \
+ if (!(func = (typeof(func))PR_FindSymbol(sLinkedLib, #func))) { \
+ LOG("Couldn't load function " #func " from %s.", aLibName); \
+ return false; \
+ } \
+ }
+#include "OmxFunctionList.h"
+#undef OMX_FUNC
+ return true;
+}
+
+/* static */
+void OmxCoreLibLinker::Unlink() {
+ LOG("");
+
+ if (sLinkedLib) {
+ PR_UnloadLibrary(sLinkedLib);
+ sLinkedLib = nullptr;
+ sLibName = nullptr;
+ sLinkStatus = LinkStatus_INIT;
+ }
+}
+
+} // namespace mozilla