1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/gstreamer/GStreamerLoader.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,146 @@ 1.4 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include <dlfcn.h> 1.10 +#include <stdio.h> 1.11 + 1.12 +#include "nsDebug.h" 1.13 +#include "mozilla/NullPtr.h" 1.14 + 1.15 +#include "GStreamerLoader.h" 1.16 + 1.17 +#define LIBGSTREAMER 0 1.18 +#define LIBGSTAPP 1 1.19 +#define LIBGSTVIDEO 2 1.20 + 1.21 +#ifdef __OpenBSD__ 1.22 +#define LIB_GST_SUFFIX ".so" 1.23 +#else 1.24 +#define LIB_GST_SUFFIX ".so.0" 1.25 +#endif 1.26 + 1.27 +namespace mozilla { 1.28 + 1.29 +/* 1.30 + * Declare our function pointers using the types from the global gstreamer 1.31 + * definitions. 1.32 + */ 1.33 +#define GST_FUNC(_, func) typeof(::func)* func; 1.34 +#define REPLACE_FUNC(func) GST_FUNC(-1, func) 1.35 +#include "GStreamerFunctionList.h" 1.36 +#undef GST_FUNC 1.37 +#undef REPLACE_FUNC 1.38 + 1.39 +/* 1.40 + * Redefinitions of functions that have been defined in the gstreamer headers to 1.41 + * stop them calling the gstreamer functions in global scope. 1.42 + */ 1.43 +GstBuffer * gst_buffer_ref_impl(GstBuffer *buf); 1.44 +void gst_buffer_unref_impl(GstBuffer *buf); 1.45 +void gst_message_unref_impl(GstMessage *msg); 1.46 +void gst_caps_unref_impl(GstCaps *caps); 1.47 + 1.48 +#if GST_VERSION_MAJOR == 1 1.49 +void gst_sample_unref_impl(GstSample *sample); 1.50 +#endif 1.51 + 1.52 +bool 1.53 +load_gstreamer() 1.54 +{ 1.55 +#ifdef __APPLE__ 1.56 + return true; 1.57 +#endif 1.58 + static bool loaded = false; 1.59 + 1.60 + if (loaded) { 1.61 + return true; 1.62 + } 1.63 + 1.64 + void *gstreamerLib = nullptr; 1.65 + guint major = 0; 1.66 + guint minor = 0; 1.67 + guint micro, nano; 1.68 + 1.69 + typedef typeof(::gst_version) VersionFuncType; 1.70 + if (VersionFuncType *versionFunc = (VersionFuncType*)dlsym(RTLD_DEFAULT, "gst_version")) { 1.71 + versionFunc(&major, &minor, µ, &nano); 1.72 + } 1.73 + 1.74 + if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) { 1.75 + gstreamerLib = RTLD_DEFAULT; 1.76 + } else { 1.77 + gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL); 1.78 + } 1.79 + 1.80 + void *handles[3] = { 1.81 + gstreamerLib, 1.82 + dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL), 1.83 + dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL) 1.84 + }; 1.85 + 1.86 + for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) { 1.87 + if (!handles[i]) { 1.88 + NS_WARNING("Couldn't link gstreamer libraries"); 1.89 + goto fail; 1.90 + } 1.91 + } 1.92 + 1.93 +#define GST_FUNC(lib, symbol) \ 1.94 + if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \ 1.95 + NS_WARNING("Couldn't link symbol " #symbol); \ 1.96 + goto fail; \ 1.97 + } 1.98 +#define REPLACE_FUNC(symbol) symbol = symbol##_impl; 1.99 +#include "GStreamerFunctionList.h" 1.100 +#undef GST_FUNC 1.101 +#undef REPLACE_FUNC 1.102 + 1.103 + loaded = true; 1.104 + return true; 1.105 + 1.106 +fail: 1.107 + 1.108 + for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) { 1.109 + if (handles[i] && handles[i] != RTLD_DEFAULT) { 1.110 + dlclose(handles[i]); 1.111 + } 1.112 + } 1.113 + 1.114 + return false; 1.115 +} 1.116 + 1.117 +GstBuffer * 1.118 +gst_buffer_ref_impl(GstBuffer *buf) 1.119 +{ 1.120 + return (GstBuffer *)gst_mini_object_ref(GST_MINI_OBJECT_CAST(buf)); 1.121 +} 1.122 + 1.123 +void 1.124 +gst_buffer_unref_impl(GstBuffer *buf) 1.125 +{ 1.126 + gst_mini_object_unref(GST_MINI_OBJECT_CAST(buf)); 1.127 +} 1.128 + 1.129 +void 1.130 +gst_message_unref_impl(GstMessage *msg) 1.131 +{ 1.132 + gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg)); 1.133 +} 1.134 + 1.135 +#if GST_VERSION_MAJOR == 1 1.136 +void 1.137 +gst_sample_unref_impl(GstSample *sample) 1.138 +{ 1.139 + gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample)); 1.140 +} 1.141 +#endif 1.142 + 1.143 +void 1.144 +gst_caps_unref_impl(GstCaps *caps) 1.145 +{ 1.146 + gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps)); 1.147 +} 1.148 + 1.149 +}