content/media/gstreamer/GStreamerLoader.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include <dlfcn.h>
michael@0 7 #include <stdio.h>
michael@0 8
michael@0 9 #include "nsDebug.h"
michael@0 10 #include "mozilla/NullPtr.h"
michael@0 11
michael@0 12 #include "GStreamerLoader.h"
michael@0 13
michael@0 14 #define LIBGSTREAMER 0
michael@0 15 #define LIBGSTAPP 1
michael@0 16 #define LIBGSTVIDEO 2
michael@0 17
michael@0 18 #ifdef __OpenBSD__
michael@0 19 #define LIB_GST_SUFFIX ".so"
michael@0 20 #else
michael@0 21 #define LIB_GST_SUFFIX ".so.0"
michael@0 22 #endif
michael@0 23
michael@0 24 namespace mozilla {
michael@0 25
michael@0 26 /*
michael@0 27 * Declare our function pointers using the types from the global gstreamer
michael@0 28 * definitions.
michael@0 29 */
michael@0 30 #define GST_FUNC(_, func) typeof(::func)* func;
michael@0 31 #define REPLACE_FUNC(func) GST_FUNC(-1, func)
michael@0 32 #include "GStreamerFunctionList.h"
michael@0 33 #undef GST_FUNC
michael@0 34 #undef REPLACE_FUNC
michael@0 35
michael@0 36 /*
michael@0 37 * Redefinitions of functions that have been defined in the gstreamer headers to
michael@0 38 * stop them calling the gstreamer functions in global scope.
michael@0 39 */
michael@0 40 GstBuffer * gst_buffer_ref_impl(GstBuffer *buf);
michael@0 41 void gst_buffer_unref_impl(GstBuffer *buf);
michael@0 42 void gst_message_unref_impl(GstMessage *msg);
michael@0 43 void gst_caps_unref_impl(GstCaps *caps);
michael@0 44
michael@0 45 #if GST_VERSION_MAJOR == 1
michael@0 46 void gst_sample_unref_impl(GstSample *sample);
michael@0 47 #endif
michael@0 48
michael@0 49 bool
michael@0 50 load_gstreamer()
michael@0 51 {
michael@0 52 #ifdef __APPLE__
michael@0 53 return true;
michael@0 54 #endif
michael@0 55 static bool loaded = false;
michael@0 56
michael@0 57 if (loaded) {
michael@0 58 return true;
michael@0 59 }
michael@0 60
michael@0 61 void *gstreamerLib = nullptr;
michael@0 62 guint major = 0;
michael@0 63 guint minor = 0;
michael@0 64 guint micro, nano;
michael@0 65
michael@0 66 typedef typeof(::gst_version) VersionFuncType;
michael@0 67 if (VersionFuncType *versionFunc = (VersionFuncType*)dlsym(RTLD_DEFAULT, "gst_version")) {
michael@0 68 versionFunc(&major, &minor, &micro, &nano);
michael@0 69 }
michael@0 70
michael@0 71 if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) {
michael@0 72 gstreamerLib = RTLD_DEFAULT;
michael@0 73 } else {
michael@0 74 gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL);
michael@0 75 }
michael@0 76
michael@0 77 void *handles[3] = {
michael@0 78 gstreamerLib,
michael@0 79 dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL),
michael@0 80 dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL)
michael@0 81 };
michael@0 82
michael@0 83 for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
michael@0 84 if (!handles[i]) {
michael@0 85 NS_WARNING("Couldn't link gstreamer libraries");
michael@0 86 goto fail;
michael@0 87 }
michael@0 88 }
michael@0 89
michael@0 90 #define GST_FUNC(lib, symbol) \
michael@0 91 if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \
michael@0 92 NS_WARNING("Couldn't link symbol " #symbol); \
michael@0 93 goto fail; \
michael@0 94 }
michael@0 95 #define REPLACE_FUNC(symbol) symbol = symbol##_impl;
michael@0 96 #include "GStreamerFunctionList.h"
michael@0 97 #undef GST_FUNC
michael@0 98 #undef REPLACE_FUNC
michael@0 99
michael@0 100 loaded = true;
michael@0 101 return true;
michael@0 102
michael@0 103 fail:
michael@0 104
michael@0 105 for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
michael@0 106 if (handles[i] && handles[i] != RTLD_DEFAULT) {
michael@0 107 dlclose(handles[i]);
michael@0 108 }
michael@0 109 }
michael@0 110
michael@0 111 return false;
michael@0 112 }
michael@0 113
michael@0 114 GstBuffer *
michael@0 115 gst_buffer_ref_impl(GstBuffer *buf)
michael@0 116 {
michael@0 117 return (GstBuffer *)gst_mini_object_ref(GST_MINI_OBJECT_CAST(buf));
michael@0 118 }
michael@0 119
michael@0 120 void
michael@0 121 gst_buffer_unref_impl(GstBuffer *buf)
michael@0 122 {
michael@0 123 gst_mini_object_unref(GST_MINI_OBJECT_CAST(buf));
michael@0 124 }
michael@0 125
michael@0 126 void
michael@0 127 gst_message_unref_impl(GstMessage *msg)
michael@0 128 {
michael@0 129 gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg));
michael@0 130 }
michael@0 131
michael@0 132 #if GST_VERSION_MAJOR == 1
michael@0 133 void
michael@0 134 gst_sample_unref_impl(GstSample *sample)
michael@0 135 {
michael@0 136 gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample));
michael@0 137 }
michael@0 138 #endif
michael@0 139
michael@0 140 void
michael@0 141 gst_caps_unref_impl(GstCaps *caps)
michael@0 142 {
michael@0 143 gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps));
michael@0 144 }
michael@0 145
michael@0 146 }

mercurial