content/media/gstreamer/GStreamerLoader.cpp

changeset 0
6474c204b198
     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, &micro, &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 +}

mercurial