[rygel/wip/media-engine: 1/2] server, engine: Move MediaEngine into .so



commit f3e4f2197beea7d2846d0793cb8d8015ea0bac4d
Author: Jens Georg <jensg openismus org>
Date:   Wed Sep 12 14:25:24 2012 +0200

    server,engine: Move MediaEngine into .so

 common.am                                          |   11 +-
 configure.ac                                       |    2 +
 data/rygel.conf                                    |    4 +
 doc/man/rygel.conf.xml                             |   16 ++
 examples/Makefile.am                               |    4 +-
 examples/standalone-server.c                       |   12 +-
 src/Makefile.am                                    |    5 +-
 src/librygel-core/filelist.am                      |    1 +
 src/librygel-core/rygel-build-config.vapi          |    7 +-
 src/librygel-core/rygel-configuration.vala         |    4 +
 src/librygel-core/rygel-meta-config.vala           |   41 ++++-
 src/librygel-core/rygel-plugin-loader.vala         |   96 ++--------
 .../rygel-recursive-module-loader.vala             |  206 ++++++++++++++++++++
 src/librygel-renderer/Makefile.am                  |    7 +-
 src/librygel-server/filelist.am                    |   16 +--
 src/librygel-server/rygel-engine-loader.vala       |   97 +++++++++
 src/librygel-server/rygel-http-byte-seek.vala      |    3 +
 src/librygel-server/rygel-http-seek.vala           |    6 +
 src/librygel-server/rygel-http-time-seek.vala      |    1 +
 src/librygel-server/rygel-media-engine.vala        |   18 ++-
 src/media-engines/Makefile.am                      |    1 +
 src/media-engines/gstreamer/Makefile.am            |   44 ++++
 .../gstreamer}/rygel-aac-transcoder.vala           |    0
 .../gstreamer}/rygel-audio-transcoder.vala         |    0
 .../gstreamer}/rygel-avc-transcoder.vala           |    0
 .../gstreamer}/rygel-gst-data-source.vala          |    4 +-
 .../gstreamer}/rygel-gst-media-engine.vala         |   23 ++-
 .../gstreamer}/rygel-gst-sink.vala                 |    2 +-
 .../gstreamer}/rygel-gst-transcoder.vala           |    0
 .../gstreamer}/rygel-gst-utils.vala                |    0
 .../gstreamer}/rygel-l16-transcoder.vala           |    0
 .../gstreamer}/rygel-mp2ts-transcoder.vala         |    0
 .../gstreamer}/rygel-mp3-transcoder.vala           |    0
 .../gstreamer}/rygel-video-transcoder.vala         |    0
 .../gstreamer}/rygel-wmv-transcoder.vala           |    0
 src/plugins/gst-launch/Makefile.am                 |   13 +-
 .../gst-launch/rygel-gst-launch-audio-item.vala    |   12 +-
 .../gst-launch/rygel-gst-launch-video-item.vala    |   11 +-
 src/plugins/mpris/Makefile.am                      |    3 +-
 src/plugins/playbin/Makefile.am                    |    3 +-
 src/plugins/test/Makefile.am                       |   13 +-
 src/plugins/test/rygel-test-audio-item.vala        |   10 +-
 src/plugins/test/rygel-test-video-item.vala        |   10 +-
 src/rygel/Makefile.am                              |    4 +
 src/rygel/rygel-cmdline-config.vala                |   17 ++-
 src/rygel/rygel-environment-config.vala            |   10 +
 src/rygel/rygel-main.vala                          |    9 +-
 src/rygel/rygel-user-config.vala                   |   10 +
 src/ui/Makefile.am                                 |    2 +-
 49 files changed, 617 insertions(+), 141 deletions(-)
---
diff --git a/common.am b/common.am
index 58512f7..9366323 100644
--- a/common.am
+++ b/common.am
@@ -3,6 +3,7 @@ shareddir = $(abs_top_builddir)/data
 sysconfigdir = $(shareddir)
 desktopdir = $(shareddir)
 plugindir = $(abs_top_builddir)/src/plugins
+enginedir = $(abs_top_builddir)/src/media-engines
 icondir = $(shareddir)/icons/32x32
 presetdir = $(shareddir)/presets
 
@@ -13,7 +14,8 @@ else
 shareddir = $(datadir)/rygel
 sysconfigdir = $(sysconfdir)
 desktopdir = $(datadir)/applications
-plugindir = $(libdir)/rygel-1.0
+plugindir = $(libdir)/rygel-1.0/plugins
+enginedir = $(libdir)/rygel-1.0/engines
 icondir = $(datadir)/icons/hicolor/32x32/apps
 presetdir = $(shareddir)/presets
 endif
@@ -31,8 +33,6 @@ MAINTAINERCLEANFILES = Makefile.in
 AM_CFLAGS = \
 	$(LIBGUPNP_CFLAGS) \
 	$(LIBGUPNP_AV_CFLAGS) \
-	$(LIBGSTREAMER_CFLAGS) \
-	$(GSTREAMER_BASE_CFLAGS) \
 	$(GEE_CFLAGS) \
 	$(UUID_CFLAGS) \
 	$(COVERAGE_CFLAGS) \
@@ -42,14 +42,12 @@ AM_CFLAGS = \
 	-I$(librygelrendererdir) \
 	-DDATA_DIR='"$(shareddir)"' -DSYS_CONFIG_DIR='"$(sysconfigdir)"'\
 	-DPLUGIN_DIR='"$(plugindir)"' -DDESKTOP_DIR='"$(desktopdir)"'\
-	-DPRESET_DIR='"$(presetdir)"'\
+	-DPRESET_DIR='"$(presetdir)"' -DENGINE_DIR='"$(enginedir)"' \
 	-include config.h
 
 RYGEL_BASE_LIBS = \
 	$(LIBGUPNP_LIBS) \
 	$(LIBGUPNP_AV_LIBS) \
-	$(LIBGSTREAMER_LIBS) \
-	$(GSTREAMER_BASE_LIBS) \
 	$(GEE_LIBS) \
 	$(UUID_LIBS) \
 	$(COVERAGE_LIBS)
@@ -66,6 +64,7 @@ RYGEL_COMMON_SERVER_LIBS = \
 
 RYGEL_COMMON_RENDERER_LIBS = \
 	$(top_builddir)/src/librygel-renderer/librygel-renderer-1.0.la \
+	$(LIBGSTREAMER_LIBS)
 	$(RYGEL_COMMON_LIBS)
 
 # Note: the -g needs to be at the end of VALAFLAGS to not break make dist
diff --git a/configure.ac b/configure.ac
index d7996a0..5f48fbf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -237,6 +237,8 @@ src/librygel-renderer/Makefile
 src/librygel-server/Makefile
 src/rygel/Makefile
 src/ui/Makefile
+src/media-engines/Makefile
+src/media-engines/gstreamer/Makefile
 src/plugins/Makefile
 data/Makefile
 data/xml/Makefile
diff --git a/data/rygel.conf b/data/rygel.conf
index c898602..a0f2736 100644
--- a/data/rygel.conf
+++ b/data/rygel.conf
@@ -25,6 +25,10 @@ music-upload-folder= MUSIC@
 # Defaults to @PICTURES@, the standard picture folder (typically ${HOME}/Pictures).
 picture-upload-folder= PICTURES@
 
+# Default media engine to load. If not specified, the engine directory is
+# searched recursively and the first engine found is loaded.
+media-engine=librygel-media-engine-gst.so
+
 # The network interface to attach rygel to. You can also use network IP or even
 # ESSID for wireless networks if you are using NetworkManager. Leave it blank
 # for dynamic configuration.
diff --git a/doc/man/rygel.conf.xml b/doc/man/rygel.conf.xml
index 9a2c6d1..fdcd4f4 100644
--- a/doc/man/rygel.conf.xml
+++ b/doc/man/rygel.conf.xml
@@ -165,6 +165,22 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
       </varlistentry>
       <varlistentry>
         <term>
+          <option>engine-path=<replaceable>PATH</replaceable></option>
+        </term>
+        <listitem>
+          <para>Set the engine search path.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
+          <option>media-engine=<replaceable>ENGINE</replaceable></option>
+        </term>
+        <listitem>
+          <para>Name of the loadable module to use as media engine back-end.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
           <option>allow-upload</option>
         </term>
         <listitem>
diff --git a/examples/Makefile.am b/examples/Makefile.am
index a750820..1f696a5 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -6,12 +6,14 @@ AM_CFLAGS += \
 	-I$(top_builddir)/src/librygel-server \
 	-I$(top_srcdir)/src/librygel-server \
 	-I$(top_builddir)/src/rygel \
-	-I$(top_srcdir)/src/rygel
+	-I$(top_srcdir)/src/rygel \
+	$(LIBGSTREAMER_CFLAGS)
 
 noinst_PROGRAMS = standalone-renderer standalone-server
 standalone_renderer_SOURCES = standalone-renderer.c
 standalone_renderer_LDADD = \
 	$(top_builddir)/src/librygel-renderer/librygel-renderer-1.0.la \
+	$(LIBGSTREAMER_LIBS) \
 	$(RYGEL_COMMON_LIBS)
 
 standalone_server_SOURCES = standalone-server.c
diff --git a/examples/standalone-server.c b/examples/standalone-server.c
index 36b22d2..1803816 100644
--- a/examples/standalone-server.c
+++ b/examples/standalone-server.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 Openismus GmbH.
+ * Copyright (C) 2012 Intel Corporation.
  *
  * Author: Jens Georg <jensg openismus com>
  *
@@ -46,10 +47,19 @@ int main (int argc, char *argv[])
     GFileInfo *info;
     int i;
     GMainLoop *loop;
+    GError *error = NULL;
 
     g_type_init ();
 
-    gst_init (&argc, &argv);
+    rygel_media_engine_init (&error);
+
+    if (error != NULL) {
+        g_print ("Could not initialize media engine: %s\n",
+                 error->message);
+        g_error_free (error);
+
+        return EXIT_FAILURE;
+    }
 
     g_set_application_name ("Standalone-Server");
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 2426f6f..e18dcf3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,6 @@
+SUBDIRS = librygel-core librygel-renderer librygel-server rygel media-engines plugins
 if BUILD_UI
-SUBDIRS = librygel-core librygel-renderer librygel-server rygel ui plugins
-else
-SUBDIRS = librygel-core librygel-renderer librygel-server rygel plugins
+SUBDIRS += ui
 endif
 
 MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/librygel-core/filelist.am b/src/librygel-core/filelist.am
index a349072..2331754 100644
--- a/src/librygel-core/filelist.am
+++ b/src/librygel-core/filelist.am
@@ -7,6 +7,7 @@ LIBRYGEL_CORE_VAPI_SOURCE_FILES = \
 	rygel-log-handler.vala \
 	rygel-meta-config.vala \
 	rygel-plugin-loader.vala \
+	rygel-recursive-module-loader.vala \
 	rygel-plugin.vala \
 	rygel-resource-info.vala \
 	rygel-media-device.vala \
diff --git a/src/librygel-core/rygel-build-config.vapi b/src/librygel-core/rygel-build-config.vapi
index bbf0ceb..8e3549c 100644
--- a/src/librygel-core/rygel-build-config.vapi
+++ b/src/librygel-core/rygel-build-config.vapi
@@ -1,7 +1,10 @@
 /*
  * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
+ * Copyright (C) 2008-2012 Nokia Corporation.
+ * Copytight (C) 2012 Intel Corporation.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *         Jens Georg <jensg openismus com>
  *
  * This file is part of Rygel.
  *
@@ -58,6 +61,6 @@ public class Rygel.BuildConfig {
     [CCode (cname = "LOCALEDIR")]
     public static const string LOCALEDIR;
 
-    [CCode (cname = "PRESET_DIR")]
-    public static const string PRESET_DIR;
+    [CCode (cname = "ENGINE_DIR")]
+    public static const string ENGINE_DIR;
 }
diff --git a/src/librygel-core/rygel-configuration.vala b/src/librygel-core/rygel-configuration.vala
index 6dfbd26..3da01e1 100644
--- a/src/librygel-core/rygel-configuration.vala
+++ b/src/librygel-core/rygel-configuration.vala
@@ -89,6 +89,10 @@ public interface Rygel.Configuration : GLib.Object {
 
     public abstract string get_plugin_path () throws GLib.Error;
 
+    public abstract string get_engine_path () throws GLib.Error;
+
+    public abstract string get_media_engine () throws GLib.Error;
+
     public abstract string get_video_upload_folder () throws GLib.Error;
 
     public abstract string get_music_upload_folder () throws GLib.Error;
diff --git a/src/librygel-core/rygel-meta-config.vala b/src/librygel-core/rygel-meta-config.vala
index 02f3aa0..13bb0e6 100644
--- a/src/librygel-core/rygel-meta-config.vala
+++ b/src/librygel-core/rygel-meta-config.vala
@@ -2,12 +2,11 @@
  * Copyright (C) 2008,2009 Nokia Corporation.
  * Copyright (C) 2008,2009 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
  * Copyright (C) 2012 Intel Corporation.
- * Copyright (C) 2012 Intel Corporation
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
  *                               <zeeshan ali nokia com>
- *         Jens Georg <jensg openismus com>
  *         Krzesimir Nowak <krnowak openismus com>
+ *         Jens Georg <jensg openismus com>
  *
  * This file is part of Rygel.
  *
@@ -226,6 +225,44 @@ public class Rygel.MetaConfig : GLib.Object, Configuration {
         return val;
     }
 
+    public string get_media_engine () throws GLib.Error {
+        string val = null;
+        bool unavailable = true;
+
+        foreach (var config in MetaConfig.configs) {
+            try {
+                val = config.get_media_engine ();
+                unavailable = false;
+                break;
+            } catch (GLib.Error err) {}
+        }
+
+        if (unavailable) {
+            throw new ConfigurationError.NO_VALUE_SET ("No value available");
+        }
+
+        return val;
+    }
+
+    public string get_engine_path () throws GLib.Error {
+        string val = null;
+        bool unavailable = true;
+
+        foreach (var config in MetaConfig.configs) {
+            try {
+                val = config.get_engine_path ();
+                unavailable = false;
+                break;
+            } catch (GLib.Error err) {}
+        }
+
+        if (unavailable) {
+            throw new ConfigurationError.NO_VALUE_SET ("No value available");
+        }
+
+        return val;
+    }
+
     public string get_video_upload_folder () throws GLib.Error {
         unowned string default = Environment.get_user_special_dir
                                         (UserDirectory.VIDEOS);
diff --git a/src/librygel-core/rygel-plugin-loader.vala b/src/librygel-core/rygel-plugin-loader.vala
index a5569dc..1c68008 100644
--- a/src/librygel-core/rygel-plugin-loader.vala
+++ b/src/librygel-core/rygel-plugin-loader.vala
@@ -1,8 +1,10 @@
 /*
  * Copyright (C) 2008 Nokia Corporation.
  * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
+ * Copyright (C) 2012 Intel Corporation.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *         Jens Georg <jensg openismus com>
  *
  * This file is part of Rygel.
  *
@@ -32,7 +34,7 @@ using Gee;
  * disabled by user using plugin_disabled method before creating the plugin
  * instance and resources related to that instance.
  */
-public class Rygel.PluginLoader : Object {
+public class Rygel.PluginLoader : RecursiveModuleLoader {
     private delegate void ModuleInitFunc (PluginLoader loader);
 
     private HashMap<string,Plugin> plugin_hash;
@@ -42,26 +44,16 @@ public class Rygel.PluginLoader : Object {
     public signal void plugin_available (Plugin plugin);
 
     public PluginLoader () {
-        this.plugin_hash = new HashMap<string,Plugin> (str_hash, str_equal);
-        this.loaded_modules = new HashSet<string> ();
-    }
-
-    // Plugin loading functions
-    public void load_plugins () {
-        assert (Module.supported());
-
-        string path;
+        var path = BuildConfig.PLUGIN_DIR;
         try {
             var config = MetaConfig.get_default ();
             path = config.get_plugin_path ();
-        } catch (Error error) {
-            path = BuildConfig.PLUGIN_DIR;
-        }
+        } catch (Error error) { }
 
-        File dir = File.new_for_path (path);
-        assert (dir != null && is_dir (dir));
+        base (path);
 
-        this.load_modules_from_dir.begin (dir);
+        this.plugin_hash = new HashMap<string,Plugin> (str_hash, str_equal);
+        this.loaded_modules = new HashSet<string> ();
     }
 
     /**
@@ -95,59 +87,12 @@ public class Rygel.PluginLoader : Object {
         return this.plugin_hash.values;
     }
 
-    private async void load_modules_from_dir (File dir) {
-        debug ("Searching for modules in folder '%s'.", dir.get_path ());
-
-        string attributes = FileAttribute.STANDARD_NAME + "," +
-                            FileAttribute.STANDARD_TYPE + "," +
-                            FileAttribute.STANDARD_CONTENT_TYPE;
-
-        GLib.List<FileInfo> infos;
-        FileEnumerator enumerator;
-
-        try {
-            enumerator = yield dir.enumerate_children_async
-                                        (attributes,
-                                         FileQueryInfoFlags.NONE,
-                                         Priority.DEFAULT,
-                                         null);
-
-            infos = yield enumerator.next_files_async (int.MAX,
-                                                       Priority.DEFAULT,
-                                                       null);
-        } catch (Error error) {
-            critical (_("Error listing contents of folder '%s': %s"),
-                      dir.get_path (),
-                      error.message);
-
-            return;
-        }
-
-        foreach (var info in infos) {
-            var file = dir.get_child (info.get_name ());
-            FileType file_type = info.get_file_type ();
-            string content_type = info.get_content_type ();
-            string mime = ContentType.get_mime_type (content_type);
-
-            if (file_type == FileType.DIRECTORY) {
-                // Recurse into directories
-                this.load_modules_from_dir.begin (file);
-            } else if (mime == "application/x-sharedlib") {
-                // Seems like we found a module
-                this.load_module_from_file (file);
-            }
-        }
-
-        debug ("Finished searching for modules in folder '%s'",
-               dir.get_path ());
-    }
-
-    private void load_module_from_file (File module_file) {
+    protected override bool load_module_from_file (File module_file) {
         if (module_file.get_basename () in this.loaded_modules) {
             warning (_("A module named %s is already loaded"),
                      module_file.get_basename ());
 
-            return;
+            return true;
         }
 
         Module module = Module.open (module_file.get_path (),
@@ -157,7 +102,7 @@ public class Rygel.PluginLoader : Object {
                      module_file.get_path (),
                      Module.error ());
 
-            return;
+            return true;
         }
 
         void* function;
@@ -168,7 +113,7 @@ public class Rygel.PluginLoader : Object {
                      module_file.get_path (),
                      Module.error ());
 
-            return;
+            return true;
         }
 
         unowned ModuleInitFunc module_init = (ModuleInitFunc) function;
@@ -181,22 +126,7 @@ public class Rygel.PluginLoader : Object {
         module_init (this);
 
         debug ("Loaded module source: '%s'", module.name());
-    }
-
-    private static bool is_dir (File file) {
-        FileInfo file_info;
-
-        try {
-            file_info = file.query_info (FileAttribute.STANDARD_TYPE,
-                                         FileQueryInfoFlags.NONE,
-                                         null);
-        } catch (Error error) {
-            critical (_("Failed to query content type for '%s'"),
-                      file.get_path ());
-
-            return false;
-        }
 
-        return file_info.get_file_type () == FileType.DIRECTORY;
+        return true;
     }
 }
diff --git a/src/librygel-core/rygel-recursive-module-loader.vala b/src/librygel-core/rygel-recursive-module-loader.vala
new file mode 100644
index 0000000..f2c2756
--- /dev/null
+++ b/src/librygel-core/rygel-recursive-module-loader.vala
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Author: Jens Georg <jensg openismus com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * Recursivly walk a folder looking for shared libraries.
+ *
+ * The folder can either be walked synchronously or asynchronously.
+ * Implementing classes need to implement the abstract method
+ * load_module_from_file() which is called when the walker encounters a
+ * dynamic module file.
+ */
+public abstract class Rygel.RecursiveModuleLoader : Object {
+    private static const string LOADER_ATTRIBUTES =
+                            FileAttribute.STANDARD_NAME + "," +
+                            FileAttribute.STANDARD_TYPE + "," +
+                            FileAttribute.STANDARD_CONTENT_TYPE;
+    private delegate void FolderHandler (File folder);
+
+    private string base_path;
+    private bool done;
+
+    /**
+     * Create a recursive module loader for a given path.
+     *
+     * Either call load_modules() or load_modules_sync() to start descending
+     * into the folder hierarchy and load the modules.
+     *
+     * @param path base path of the loader.
+     */
+    public RecursiveModuleLoader (string path) {
+        this.base_path = path;
+        this.done = false;
+    }
+
+    // Plugin loading functions
+
+    /**
+     * Walk asynchronously through the tree and load modules.
+     */
+    public void load_modules () {
+        assert (Module.supported());
+
+        var folder = File.new_for_path (this.base_path);
+        assert (folder != null && this.is_folder (folder));
+
+        this.load_modules_from_folder.begin (folder);
+    }
+
+    /**
+     * Walk synchronously through the tree and load modules.
+     */
+    public void load_modules_sync (Cancellable? cancellable = null) {
+        debug ("Searching for modules in folder '%s'",
+               this.base_path);
+        var queue = new Queue<File> ();
+
+        queue.push_head (File.new_for_path (this.base_path));
+        while (!queue.is_empty ()) {
+            if (cancellable != null && cancellable.is_cancelled ()) {
+                break;
+            }
+
+            var folder = queue.pop_head ();
+            try {
+                var enumerator = folder.enumerate_children
+                                        (LOADER_ATTRIBUTES,
+                                         FileQueryInfoFlags.NONE,
+                                         cancellable);
+                var info = enumerator.next_file (cancellable);
+                while (info != null) {
+                    this.handle_file_info (folder, info, (subfolder) => {
+                        queue.push_head (subfolder);
+                    });
+                    info = enumerator.next_file (cancellable);
+                }
+            } catch (Error error) {
+                debug ("Failed to enumerate folder %s: %s",
+                       folder.get_path (),
+                       error.message);
+            }
+        }
+    }
+
+    /**
+     * Load module from file.
+     * @param file File to load the module from
+     * @return The implementation should return true if the class should
+     * continue to search for modules, false otherwise.
+     */
+    protected abstract bool load_module_from_file (File file);
+
+    /**
+     * Process children of a folder.
+     *
+     * Recurse into folders or call load_module_from_file() if it looks
+     * like a shared library.
+     *
+     * @param folder the folder
+     */
+    private async void load_modules_from_folder (File folder) {
+        debug ("Searching for modules in folder '%s'.", folder.get_path ());
+
+        GLib.List<FileInfo> infos;
+        FileEnumerator enumerator;
+
+        try {
+            enumerator = yield folder.enumerate_children_async
+                                        (LOADER_ATTRIBUTES,
+                                         FileQueryInfoFlags.NONE,
+                                         Priority.DEFAULT,
+                                         null);
+
+            infos = yield enumerator.next_files_async (int.MAX,
+                                                       Priority.DEFAULT,
+                                                       null);
+        } catch (Error error) {
+            critical (_("Error listing contents of folder '%s': %s"),
+                      folder.get_path (),
+                      error.message);
+
+            return;
+        }
+
+        foreach (var info in infos) {
+            if (this.done) {
+                break;
+            }
+
+            this.handle_file_info (folder, info, (subfolder) => {
+                this.load_modules_from_folder.begin (subfolder);
+            });
+        }
+
+        debug ("Finished searching for modules in folder '%s'",
+               folder.get_path ());
+    }
+
+    /**
+     * Process a file info.
+     *
+     * Utility method used by sync and async tree walk.
+     * @param folder parent folder
+     * @param info the FileInfo of the file to process
+     * @param handler a call-back if the FileInfo represents a folder.
+     */
+    private void handle_file_info (File          folder,
+                                   FileInfo      info,
+                                   FolderHandler handler) {
+            var file = folder.get_child (info.get_name ());
+            FileType file_type = info.get_file_type ();
+            string content_type = info.get_content_type ();
+            string mime = ContentType.get_mime_type (content_type);
+
+            if (file_type == FileType.DIRECTORY) {
+                handler (file);
+            } else if (mime == "application/x-sharedlib") {
+                // Seems like we found a module
+                if (!this.load_module_from_file (file)) {
+                    this.done = true;
+                }
+            }
+
+    }
+
+    /**
+     * Check if a File is a folder.
+     *
+     * @param file the File to check
+     * @return true, if file is folder, false otherwise.
+     */
+    private bool is_folder (File file) {
+        FileInfo file_info;
+
+        try {
+            file_info = file.query_info (FileAttribute.STANDARD_TYPE,
+                                         FileQueryInfoFlags.NONE,
+                                         null);
+        } catch (Error error) {
+            critical (_("Failed to query content type for '%s'"),
+                      file.get_path ());
+
+            return false;
+        }
+
+        return file_info.get_file_type () == FileType.DIRECTORY;
+    }
+}
diff --git a/src/librygel-renderer/Makefile.am b/src/librygel-renderer/Makefile.am
index 1d8f7eb..9df80a6 100644
--- a/src/librygel-renderer/Makefile.am
+++ b/src/librygel-renderer/Makefile.am
@@ -12,10 +12,15 @@ librygel_renderer_1_0_la_SOURCES = \
 	$(LIBRYGEL_RENDERER_VAPI_SOURCE_FILES) \
 	$(LIBRYGEL_RENDERER_NONVAPI_SOURCE_FILES)
 
+librygel_renderer_1_0_la_CFLAGS = \
+	$(AM_CFLAGS) \
+	$(LIBGSTREAMER_CFLAGS)
+
 librygel_renderer_1_0_la_VALAFLAGS = \
 	-H rygel-renderer.h --library=rygel-renderer-1.0 \
+	--pkg gstreamer-0.10 \
 	$(RYGEL_COMMON_PLUGIN_VALAFLAGS)
-librygel_renderer_1_0_la_LIBADD = $(RYGEL_COMMON_LIBS)
+librygel_renderer_1_0_la_LIBADD = $(RYGEL_COMMON_LIBS) $(LIBGSTREAMER_LIBS)
 librygel_renderer_1_0_la_LDFLAGS = -version-info $(LIBRYGEL_RENDERER_VERSION)
 
 rygel-renderer.h rygel-renderer-1.0.vapi: librygel_renderer_1_0_la_vala.stamp
diff --git a/src/librygel-server/filelist.am b/src/librygel-server/filelist.am
index 2912d96..a389709 100644
--- a/src/librygel-server/filelist.am
+++ b/src/librygel-server/filelist.am
@@ -24,27 +24,23 @@ LIBRYGEL_SERVER_VAPI_SOURCE_FILES = \
 	rygel-writable-container.vala \
 	rygel-media-server.vala \
 	rygel-media-engine.vala \
+	rygel-http-seek.vala \
 	rygel-data-source.vala
 
 LIBRYGEL_SERVER_NONVAPI_SOURCE_FILES = \
-	rygel-aac-transcoder.vala \
-	rygel-audio-transcoder.vala \
-	rygel-avc-transcoder.vala \
 	rygel-browse.vala \
 	rygel-client-hacks.vala \
 	rygel-content-directory.vala \
 	rygel-dbus-thumbnailer.vala \
-	rygel-gst-utils.vala \
+    rygel-engine-loader.vala \
 	rygel-http-byte-seek.vala \
 	rygel-http-get-handler.vala \
 	rygel-http-get.vala \
-	rygel-gst-sink.vala \
 	rygel-http-identity-handler.vala \
 	rygel-http-item-uri.vala \
 	rygel-http-post.vala \
 	rygel-http-request.vala \
 	rygel-http-response.vala \
-	rygel-http-seek.vala \
 	rygel-http-server.vala \
 	rygel-http-time-seek.vala \
 	rygel-http-transcode-handler.vala \
@@ -52,11 +48,8 @@ LIBRYGEL_SERVER_NONVAPI_SOURCE_FILES = \
 	rygel-item-creator.vala \
 	rygel-item-destroyer.vala \
 	rygel-item-removal-queue.vala \
-	rygel-l16-transcoder.vala \
 	rygel-media-query-action.vala \
 	rygel-media-receiver-registrar.vala \
-	rygel-mp2ts-transcoder.vala \
-	rygel-mp3-transcoder.vala \
 	rygel-panasonic-hacks.vala \
 	rygel-search-criteria-parser.vala \
 	rygel-search.vala \
@@ -64,14 +57,9 @@ LIBRYGEL_SERVER_NONVAPI_SOURCE_FILES = \
 	rygel-subtitle-manager.vala \
 	rygel-thumbnailer.vala \
 	rygel-v1-hacks.vala \
-	rygel-video-transcoder.vala \
 	rygel-wmp-hacks.vala \
-	rygel-wmv-transcoder.vala \
 	rygel-xbmc-hacks.vala \
 	rygel-xbox-hacks.vala \
-	rygel-gst-media-engine.vala \
-	rygel-gst-transcoder.vala \
-	rygel-gst-data-source.vala \
 	rygel-data-sink.vala
 
 LIBRYGEL_SERVER_VALAFLAGS_PKG = \
diff --git a/src/librygel-server/rygel-engine-loader.vala b/src/librygel-server/rygel-engine-loader.vala
new file mode 100644
index 0000000..47c26cc
--- /dev/null
+++ b/src/librygel-server/rygel-engine-loader.vala
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Author: Jens Georg <jensg openismus com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * Load a media engine.
+ */
+internal class Rygel.EngineLoader : RecursiveModuleLoader {
+    private delegate MediaEngine ModuleInstanceFunc ();
+    private MediaEngine instance;
+    private string engine_name;
+
+    public EngineLoader () {
+        var path = BuildConfig.ENGINE_DIR;
+        var config = MetaConfig.get_default ();
+        try {
+            path = config.get_engine_path ();
+        } catch (Error error) { }
+
+        base (path);
+
+        try {
+            this.engine_name = config.get_media_engine ();
+            debug ("Looking for specific engine named '%s",
+                   this.engine_name);
+        } catch (Error error) {}
+    }
+
+    /**
+     * Load a media engine.
+     */
+    public MediaEngine load_engine () {
+        this.load_modules_sync ();
+
+        return instance;
+    }
+
+    protected override bool load_module_from_file (File file) {
+        if (this.engine_name != null) {
+            if (file.get_basename () != this.engine_name) {
+                return true;
+            }
+        }
+
+        var module = Module.open (file.get_path (), 0);
+        if (module == null) {
+            debug ("Failed to load engine %s: %s",
+                   file.get_path (),
+                   Module.error ());
+            if (this.engine_name != null) {
+                // If engine name is not null, we only got here because the
+                // names match. If we couldn't load the engine that matches,
+                // we stop loading.
+                return false;
+            }
+
+            return true;
+        }
+
+        void* function;
+        if (!module.symbol ("module_get_instance", out function)) {
+            if (this.engine_name != null) {
+                // If engine name is not null, we only got here because the
+                // names match. If we couldn't load the engine that matches,
+                // we stop loading.
+                return false;
+            }
+
+            return true;
+        }
+
+        unowned ModuleInstanceFunc get_instance =
+                                    (ModuleInstanceFunc) function;
+        module.make_resident ();
+        this.instance = get_instance ();
+
+        return false;
+    }
+}
diff --git a/src/librygel-server/rygel-http-byte-seek.vala b/src/librygel-server/rygel-http-byte-seek.vala
index 556ef75..604e2af 100644
--- a/src/librygel-server/rygel-http-byte-seek.vala
+++ b/src/librygel-server/rygel-http-byte-seek.vala
@@ -1,8 +1,10 @@
 /*
  * Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2012 Intel Corporation.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
  *                               <zeeshan ali nokia com>
+ *         Jens Georg <jensg openismus com>
  *
  * This file is part of Rygel.
  *
@@ -55,6 +57,7 @@ internal class Rygel.HTTPByteSeek : Rygel.HTTPSeek {
         }
 
         base (request.msg, start, stop, 1, total_length);
+        this.seek_type = HTTPSeekType.BYTE;
     }
 
     public static bool needed (HTTPGet request) {
diff --git a/src/librygel-server/rygel-http-seek.vala b/src/librygel-server/rygel-http-seek.vala
index 670816b..7828601 100644
--- a/src/librygel-server/rygel-http-seek.vala
+++ b/src/librygel-server/rygel-http-seek.vala
@@ -28,7 +28,13 @@ public errordomain Rygel.HTTPSeekError {
     OUT_OF_RANGE = Soup.KnownStatusCode.REQUESTED_RANGE_NOT_SATISFIABLE,
 }
 
+public enum Rygel.HTTPSeekType {
+    BYTE,
+    TIME
+}
+
 public abstract class Rygel.HTTPSeek : GLib.Object {
+    public HTTPSeekType seek_type { get; protected set; }
     public Soup.Message msg { get; private set; }
 
     // These are either number of bytes or microseconds
diff --git a/src/librygel-server/rygel-http-time-seek.vala b/src/librygel-server/rygel-http-time-seek.vala
index 00cdbea..1cb42e5 100644
--- a/src/librygel-server/rygel-http-time-seek.vala
+++ b/src/librygel-server/rygel-http-time-seek.vala
@@ -86,6 +86,7 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
         }
 
         base (request.msg, start, stop, TimeSpan.MILLISECOND, duration);
+        this.seek_type = HTTPSeekType.TIME;
     }
 
     public static bool needed (HTTPGet request) {
diff --git a/src/librygel-server/rygel-media-engine.vala b/src/librygel-server/rygel-media-engine.vala
index 5bbe6c2..7afc116 100644
--- a/src/librygel-server/rygel-media-engine.vala
+++ b/src/librygel-server/rygel-media-engine.vala
@@ -43,6 +43,10 @@ public class Rygel.DLNAProfile {
     }
 }
 
+public errordomain Rygel.MediaEngineError {
+    NOT_FOUND
+}
+
 /**
  * Base class for the media engine that will contain knowledge about streaming
  * and transcoding capabilites of the media library in use.
@@ -50,14 +54,24 @@ public class Rygel.DLNAProfile {
 public abstract class Rygel.MediaEngine : GLib.Object {
     private static MediaEngine instance;
 
+    public static void init () throws Error {
+        // lazy-load the engine plug-in
+        var loader = new EngineLoader ();
+        MediaEngine.instance = loader.load_engine ();
+        if (MediaEngine.instance == null) {
+            throw new MediaEngineError.NOT_FOUND
+                                        (_("No media engine found."));
+        }
+    }
+
     /**
      * Get the singleton instance of the currently used media engine.
      *
-     * @return An instance of a concreate #MediaEngine implementation.
+     * @return An instance of a concrete #MediaEngine implementation.
      */
     public static MediaEngine get_default () {
         if (instance == null) {
-            instance = new GstMediaEngine ();
+            error (_("MediaEngine.init was not called. Cannot continue."));
         }
 
         return instance;
diff --git a/src/media-engines/Makefile.am b/src/media-engines/Makefile.am
new file mode 100644
index 0000000..7d0d842
--- /dev/null
+++ b/src/media-engines/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=gstreamer
diff --git a/src/media-engines/gstreamer/Makefile.am b/src/media-engines/gstreamer/Makefile.am
new file mode 100644
index 0000000..b853a6a
--- /dev/null
+++ b/src/media-engines/gstreamer/Makefile.am
@@ -0,0 +1,44 @@
+include $(top_srcdir)/common.am
+
+engine_LTLIBRARIES = librygel-media-engine-gst.la
+
+AM_CFLAGS += -DG_LOG_DOMAIN='"MediaEngine-GStreamer"' \
+	$(GST_PBU_CFLAGS) \
+	$(LIBGUPNP_DLNA_CFLAGS)
+
+librygel_media_engine_gst_la_SOURCES = \
+	rygel-aac-transcoder.vala \
+	rygel-audio-transcoder.vala \
+	rygel-avc-transcoder.vala \
+	rygel-gst-data-source.vala \
+	rygel-gst-media-engine.vala \
+	rygel-gst-sink.vala \
+	rygel-gst-transcoder.vala \
+	rygel-gst-utils.vala \
+	rygel-l16-transcoder.vala \
+	rygel-mp2ts-transcoder.vala \
+	rygel-mp3-transcoder.vala \
+	rygel-video-transcoder.vala \
+	rygel-wmv-transcoder.vala
+
+librygel_media_engine_gst_la_VALAFLAGS = \
+	--pkg gstreamer-base-0.10 \
+	--pkg gstreamer-pbutils-0.10 \
+	--pkg gupnp-dlna-1.0 \
+	--library rygel-media-engine-gst \
+	--use-header \
+	--header=rygel-media-engine-gst.h \
+	$(RYGEL_COMMON_SERVER_PLUGIN_VALAFLAGS)
+
+rygel-media-engine-gst.h rygel-media-engine-gstreamer.vapi: librygel_media_engine_gst_la_vala.stamp
+
+librygel_media_engine_gst_la_LIBADD = \
+	$(GST_PBU_LIBS) \
+	$(LIBGUPNP_DLNA_LIBS) \
+	$(RYGEL_COMMON_SERVER_LIBS)
+
+librygel_media_engine_gst_la_LDFLAGS = $(RYGEL_PLUGIN_LINKER_FLAGS)
+
+EXTRA_DIST = \
+	rygel-media-engine-gst.vapi \
+	rygel-media-engine-gst.h
diff --git a/src/librygel-server/rygel-aac-transcoder.vala b/src/media-engines/gstreamer/rygel-aac-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-aac-transcoder.vala
rename to src/media-engines/gstreamer/rygel-aac-transcoder.vala
diff --git a/src/librygel-server/rygel-audio-transcoder.vala b/src/media-engines/gstreamer/rygel-audio-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-audio-transcoder.vala
rename to src/media-engines/gstreamer/rygel-audio-transcoder.vala
diff --git a/src/librygel-server/rygel-avc-transcoder.vala b/src/media-engines/gstreamer/rygel-avc-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-avc-transcoder.vala
rename to src/media-engines/gstreamer/rygel-avc-transcoder.vala
diff --git a/src/librygel-server/rygel-gst-data-source.vala b/src/media-engines/gstreamer/rygel-gst-data-source.vala
similarity index 98%
rename from src/librygel-server/rygel-gst-data-source.vala
rename to src/media-engines/gstreamer/rygel-gst-data-source.vala
index 41cf91a..4c2a497 100644
--- a/src/librygel-server/rygel-gst-data-source.vala
+++ b/src/media-engines/gstreamer/rygel-gst-data-source.vala
@@ -22,7 +22,7 @@
 
 using Gst;
 
-public class Rygel.GstDataSource : Rygel.DataSource, GLib.Object {
+internal class Rygel.GstDataSource : Rygel.DataSource, GLib.Object {
     internal dynamic Element src;
     private Pipeline pipeline;
     private HTTPSeek seek = null;
@@ -200,7 +200,7 @@ public class Rygel.GstDataSource : Rygel.DataSource, GLib.Object {
         var flags = SeekFlags.FLUSH;
         int64 start, stop;
 
-        if (this.seek is HTTPTimeSeek) {
+        if (this.seek.seek_type == HTTPSeekType.TIME) {
             format = Format.TIME;
             flags |= SeekFlags.KEY_UNIT;
             start = (this.seek.start) * Gst.USECOND;
diff --git a/src/librygel-server/rygel-gst-media-engine.vala b/src/media-engines/gstreamer/rygel-gst-media-engine.vala
similarity index 83%
rename from src/librygel-server/rygel-gst-media-engine.vala
rename to src/media-engines/gstreamer/rygel-gst-media-engine.vala
index 890de4c..9873af1 100644
--- a/src/librygel-server/rygel-gst-media-engine.vala
+++ b/src/media-engines/gstreamer/rygel-gst-media-engine.vala
@@ -23,11 +23,24 @@
 using Gst;
 using Gee;
 
-internal class Rygel.GstMediaEngine : Rygel.MediaEngine {
+// Remove for GStreamer 1.0
+[CCode (cname = "PRESET_DIR")]
+internal extern static const string PRESET_DIR;
+
+[CCode (cname="gst_preset_set_app_dir")]
+extern bool gst_preset_set_app_dir (string app_dir);
+
+public class Rygel.GstMediaEngine : Rygel.MediaEngine {
     private GLib.List<DLNAProfile> dlna_profiles = null;
     private GLib.List<Transcoder> transcoders = null;
 
     public GstMediaEngine () {
+        // Work-around vapi bug, fixed for GStreamer 1.0
+        unowned string[] args = null;
+
+        Gst.init (ref args);
+        gst_preset_set_app_dir (PRESET_DIR);
+
         var discoverer = new GUPnP.DLNADiscoverer ((ClockTime) SECOND,
                                                    true,
                                                    false);
@@ -91,4 +104,12 @@ internal class Rygel.GstMediaEngine : Rygel.MediaEngine {
     public override DataSource create_data_source (string uri) {
         return new GstDataSource (uri);
     }
+
+    public DataSource create_data_source_from_element (Element element) {
+        return new GstDataSource.from_element (element);
+    }
+}
+
+public static Rygel.MediaEngine module_get_instance () {
+    return new Rygel.GstMediaEngine ();
 }
diff --git a/src/librygel-server/rygel-gst-sink.vala b/src/media-engines/gstreamer/rygel-gst-sink.vala
similarity index 98%
rename from src/librygel-server/rygel-gst-sink.vala
rename to src/media-engines/gstreamer/rygel-gst-sink.vala
index eed08d0..690977e 100644
--- a/src/librygel-server/rygel-gst-sink.vala
+++ b/src/media-engines/gstreamer/rygel-gst-sink.vala
@@ -70,7 +70,7 @@ internal class Rygel.GstSink : BaseSink {
         this.frozen = false;
 
         if (this.offsets != null) {
-            if (this.offsets is HTTPByteSeek) {
+            if (this.offsets.seek_type == HTTPSeekType.BYTE) {
                 this.max_bytes = this.offsets.length;
             }
         }
diff --git a/src/librygel-server/rygel-gst-transcoder.vala b/src/media-engines/gstreamer/rygel-gst-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-gst-transcoder.vala
rename to src/media-engines/gstreamer/rygel-gst-transcoder.vala
diff --git a/src/librygel-server/rygel-gst-utils.vala b/src/media-engines/gstreamer/rygel-gst-utils.vala
similarity index 100%
rename from src/librygel-server/rygel-gst-utils.vala
rename to src/media-engines/gstreamer/rygel-gst-utils.vala
diff --git a/src/librygel-server/rygel-l16-transcoder.vala b/src/media-engines/gstreamer/rygel-l16-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-l16-transcoder.vala
rename to src/media-engines/gstreamer/rygel-l16-transcoder.vala
diff --git a/src/librygel-server/rygel-mp2ts-transcoder.vala b/src/media-engines/gstreamer/rygel-mp2ts-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-mp2ts-transcoder.vala
rename to src/media-engines/gstreamer/rygel-mp2ts-transcoder.vala
diff --git a/src/librygel-server/rygel-mp3-transcoder.vala b/src/media-engines/gstreamer/rygel-mp3-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-mp3-transcoder.vala
rename to src/media-engines/gstreamer/rygel-mp3-transcoder.vala
diff --git a/src/librygel-server/rygel-video-transcoder.vala b/src/media-engines/gstreamer/rygel-video-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-video-transcoder.vala
rename to src/media-engines/gstreamer/rygel-video-transcoder.vala
diff --git a/src/librygel-server/rygel-wmv-transcoder.vala b/src/media-engines/gstreamer/rygel-wmv-transcoder.vala
similarity index 100%
rename from src/librygel-server/rygel-wmv-transcoder.vala
rename to src/media-engines/gstreamer/rygel-wmv-transcoder.vala
diff --git a/src/plugins/gst-launch/Makefile.am b/src/plugins/gst-launch/Makefile.am
index e5fc0cf..05f237d 100644
--- a/src/plugins/gst-launch/Makefile.am
+++ b/src/plugins/gst-launch/Makefile.am
@@ -1,16 +1,21 @@
-include ../../../common.am
+include $(top_srcdir)/common.am
 
 plugin_LTLIBRARIES = librygel-gst-launch.la
 
-AM_CFLAGS += -DG_LOG_DOMAIN='"GstLaunch"'
+AM_CFLAGS += -DG_LOG_DOMAIN='"GstLaunch"' \
+	-I$(top_srcdir)/src/media-engines/gstreamer \
+	$(LIBGSTREAMER_CFLAGS)
 
 librygel_gst_launch_la_SOURCES = \
 	rygel-gst-launch-plugin.vala \
 	rygel-gst-launch-root-container.vala \
 	rygel-gst-launch-item.vala \
 	rygel-gst-launch-audio-item.vala \
-	rygel-gst-launch-video-item.vala
+	rygel-gst-launch-video-item.vala \
+	$(top_srcdir)/src/media-engines/gstreamer/rygel-media-engine-gst.vapi
 
 librygel_gst_launch_la_VALAFLAGS = $(RYGEL_COMMON_SERVER_PLUGIN_VALAFLAGS)
-librygel_gst_launch_la_LIBADD = $(RYGEL_COMMON_SERVER_LIBS)
+librygel_gst_launch_la_LIBADD = \
+	$(LIBGSTREAMER_LIBS) \
+	$(RYGEL_COMMON_SERVER_LIBS)
 librygel_gst_launch_la_LDFLAGS = $(RYGEL_PLUGIN_LINKER_FLAGS)
diff --git a/src/plugins/gst-launch/rygel-gst-launch-audio-item.vala b/src/plugins/gst-launch/rygel-gst-launch-audio-item.vala
index e847291..de9e62d 100644
--- a/src/plugins/gst-launch/rygel-gst-launch-audio-item.vala
+++ b/src/plugins/gst-launch/rygel-gst-launch-audio-item.vala
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Thijs Vermeir <thijsvermeir gmail com>
  * Copyright (C) 2010 Nokia Corporation.
+ * Copyright (C) 2012 Intel Corporation.
  *
  * Author: Thijs Vermeir <thijsvermeir gmail com>
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
@@ -44,6 +45,15 @@ public class Rygel.GstLaunch.AudioItem : Rygel.AudioItem, Item {
     }
 
     public override DataSource? create_stream_source (string? host_ip) {
-        return new GstDataSource.from_element (this.create_source ());
+        var engine = MediaEngine.get_default ();
+        var gst_engine = engine as GstMediaEngine;
+        if (gst_engine == null) {
+            warning ("The current media engine is not based on GStreamer.");
+
+            return null;
+        }
+
+        return gst_engine.create_data_source_from_element
+                                        (this.create_source ());
     }
 }
diff --git a/src/plugins/gst-launch/rygel-gst-launch-video-item.vala b/src/plugins/gst-launch/rygel-gst-launch-video-item.vala
index 7b7f2a4..7f7d433 100644
--- a/src/plugins/gst-launch/rygel-gst-launch-video-item.vala
+++ b/src/plugins/gst-launch/rygel-gst-launch-video-item.vala
@@ -45,6 +45,15 @@ public class Rygel.GstLaunch.VideoItem : Rygel.VideoItem, Item {
     }
 
     public override DataSource? create_stream_source (string? host_ip) {
-        return new GstDataSource.from_element (this.create_source ());
+        var engine = MediaEngine.get_default ();
+        var gst_engine = engine as GstMediaEngine;
+        if (gst_engine == null) {
+            warning ("The current media engine is not based on GStreamer.");
+
+            return null;
+        }
+
+        return gst_engine.create_data_source_from_element
+                                        (this.create_source ());
     }
 }
diff --git a/src/plugins/mpris/Makefile.am b/src/plugins/mpris/Makefile.am
index 4b609de..b108c38 100644
--- a/src/plugins/mpris/Makefile.am
+++ b/src/plugins/mpris/Makefile.am
@@ -2,7 +2,8 @@ include ../../../common.am
 
 plugin_LTLIBRARIES = librygel-mpris.la
 
-AM_CFLAGS += -DG_LOG_DOMAIN='"MPRIS"'
+AM_CFLAGS += -DG_LOG_DOMAIN='"MPRIS"' \
+	$(LIBGSTREAMER_CFLAGS)
 
 librygel_mpris_la_SOURCES = \
 	rygel-mpris-player.vala \
diff --git a/src/plugins/playbin/Makefile.am b/src/plugins/playbin/Makefile.am
index 734056c..3a53300 100644
--- a/src/plugins/playbin/Makefile.am
+++ b/src/plugins/playbin/Makefile.am
@@ -2,7 +2,8 @@ include ../../../common.am
 
 plugin_LTLIBRARIES = librygel-playbin.la
 
-AM_CFLAGS += -DG_LOG_DOMAIN='"Playbin"'
+AM_CFLAGS += -DG_LOG_DOMAIN='"Playbin"' \
+	$(LIBGSTREAMER_CFLAGS)
 
 librygel_playbin_la_SOURCES = rygel-module.vala
 librygel_playbin_la_CFLAGS = $(AM_CFLAGS)
diff --git a/src/plugins/test/Makefile.am b/src/plugins/test/Makefile.am
index 628b3cb..a508412 100644
--- a/src/plugins/test/Makefile.am
+++ b/src/plugins/test/Makefile.am
@@ -1,15 +1,20 @@
-include ../../../common.am
+include $(top_srcdir)/common.am
 
 plugin_LTLIBRARIES = librygel-test.la
 
-AM_CFLAGS += -DG_LOG_DOMAIN='"Test"'
+AM_CFLAGS += -DG_LOG_DOMAIN='"Test"' \
+	-I$(top_srcdir)/src/media-engines/gstreamer \
+	$(LIBGSTREAMER_CFLAGS)
 
 librygel_test_la_SOURCES = \
 	rygel-test-root-container.vala \
 	rygel-test-audio-item.vala \
 	rygel-test-video-item.vala \
-	rygel-test-plugin.vala
+	rygel-test-plugin.vala \
+	$(top_srcdir)/src/media-engines/gstreamer/rygel-media-engine-gst.vapi
 
 librygel_test_la_VALAFLAGS = $(RYGEL_COMMON_SERVER_PLUGIN_VALAFLAGS)
-librygel_test_la_LIBADD = $(RYGEL_COMMON_SERVER_LIBS)
+librygel_test_la_LIBADD = \
+	$(LIBGSTREAMER_LIBS) \
+	$(RYGEL_COMMON_SERVER_LIBS)
 librygel_test_la_LDFLAGS = $(RYGEL_PLUGIN_LINKER_FLAGS)
diff --git a/src/plugins/test/rygel-test-audio-item.vala b/src/plugins/test/rygel-test-audio-item.vala
index 021ecec..dbd2c46 100644
--- a/src/plugins/test/rygel-test-audio-item.vala
+++ b/src/plugins/test/rygel-test-audio-item.vala
@@ -40,10 +40,18 @@ public class Rygel.Test.AudioItem : Rygel.AudioItem {
     }
 
     public override DataSource? create_stream_source (string? host_ip) {
+        var engine = MediaEngine.get_default ();
+        var gst_engine = engine as GstMediaEngine;
+        if (gst_engine == null) {
+            warning ("The current media engine is not based on GStreamer.");
+
+            return null;
+        }
+
         try {
             var element = parse_bin_from_description (PIPELINE, true);
 
-            return new GstDataSource.from_element (element);
+            return gst_engine.create_data_source_from_element (element);
         } catch (Error err) {
             warning ("Required plugin missing (%s)", err.message);
 
diff --git a/src/plugins/test/rygel-test-video-item.vala b/src/plugins/test/rygel-test-video-item.vala
index 991a488..04cb6bd 100644
--- a/src/plugins/test/rygel-test-video-item.vala
+++ b/src/plugins/test/rygel-test-video-item.vala
@@ -42,10 +42,18 @@ public class Rygel.Test.VideoItem : Rygel.VideoItem {
     }
 
     public override DataSource? create_stream_source (string? host_ip) {
+        var engine = MediaEngine.get_default ();
+        var gst_engine = engine as GstMediaEngine;
+        if (gst_engine == null) {
+            warning ("The current media engine is not based on GStreamer.");
+
+            return null;
+        }
+
         try {
             var element =  parse_bin_from_description (PIPELINE, true);
 
-            return new GstDataSource.from_element (element);
+            return gst_engine.create_data_source_from_element (element);
         } catch (Error err) {
             warning ("Required plugin missing (%s)", err.message);
 
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index d2ceb4f..75c3f6e 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -22,10 +22,14 @@ rygel_SOURCES = \
 rygel_VALAFLAGS = \
 	--pkg posix \
 	--pkg gstreamer-0.10 \
+	--pkg rygel-server-1.0 \
+	--vapidir $(top_srcdir)/src/librygel-server \
 	$(RYGEL_COMMON_VALAFLAGS)
 
 rygel_LDADD = \
 	$(top_builddir)/src/librygel-core/librygel-core-1.0.la \
+	$(top_builddir)/src/librygel-server/librygel-server-1.0.la \
+	$(LIBGSTREAMER_LIBS) \
 	$(RYGEL_BASE_LIBS)
 
 rygel_LDFLAGS = -export-dynamic
diff --git a/src/rygel/rygel-cmdline-config.vala b/src/rygel/rygel-cmdline-config.vala
index ea00324..461ab53 100644
--- a/src/rygel/rygel-cmdline-config.vala
+++ b/src/rygel/rygel-cmdline-config.vala
@@ -46,6 +46,7 @@ public class Rygel.CmdlineConfig : GLib.Object, Configuration {
     private static string log_levels;
 
     private static string plugin_path;
+    private static string engine_path;
 
     private static bool version;
 
@@ -87,6 +88,8 @@ public class Rygel.CmdlineConfig : GLib.Object, Configuration {
           "DOMAIN1:LEVEL1[,DOMAIN2:LEVEL2,..]" },
         { "plugin-path", 'u', 0, OptionArg.STRING, ref plugin_path,
           "Plugin Path", "PLUGIN_PATH" },
+        { "engine-path", 'e', 0, OptionArg.STRING, ref engine_path,
+          "Engine Path", "ENGINE_PATH" },
         { "disable-plugin", 'd', 0, OptionArg.STRING_ARRAY,
           ref disabled_plugins,
           "Disable plugin", "PluginName" },
@@ -117,7 +120,6 @@ public class Rygel.CmdlineConfig : GLib.Object, Configuration {
         opt_context.set_help_enabled (true);
         opt_context.set_ignore_unknown_options (true);
         opt_context.add_main_entries (options, null);
-        opt_context.add_group (Gst.init_get_option_group ());
 
         try {
             opt_context.parse (ref args);
@@ -198,6 +200,19 @@ public class Rygel.CmdlineConfig : GLib.Object, Configuration {
         return plugin_path;
     }
 
+    public string get_engine_path () throws GLib.Error {
+        if (engine_path == null) {
+            throw new ConfigurationError.NO_VALUE_SET ("No value available");
+        }
+
+        return plugin_path;
+    }
+
+    public string get_media_engine () throws GLib.Error {
+        // We don't support setting this via commandline
+        throw new ConfigurationError.NO_VALUE_SET ("No value available");
+    }
+
     public bool get_enabled (string section) throws GLib.Error {
         var disabled = false;
         foreach (var plugin in disabled_plugins) {
diff --git a/src/rygel/rygel-environment-config.vala b/src/rygel/rygel-environment-config.vala
index 75d7d1f..e7188f7 100644
--- a/src/rygel/rygel-environment-config.vala
+++ b/src/rygel/rygel-environment-config.vala
@@ -42,6 +42,8 @@ internal class Rygel.EnvironmentConfig : GLib.Object, Configuration {
     private static string DISALLOW_DELETION_ENV = DISABLE_PREFIX + "_DELETION";
     private static string LOG_LEVELS_ENV = RYGEL_PREFIX + "_LOG";
     private static string PLUGIN_PATH_ENV = RYGEL_PREFIX + "_PLUGIN_PATH";
+    private static string ENGINE_PATH_ENV = RYGEL_PREFIX + "_ENGINE_PATH";
+    private static string MEDIA_ENGINE_ENV = RYGEL_PREFIX + "_MEDIA_ENGINE";
 
     // Our singleton
     private static EnvironmentConfig config;
@@ -86,6 +88,14 @@ internal class Rygel.EnvironmentConfig : GLib.Object, Configuration {
         return this.get_string_variable (PLUGIN_PATH_ENV);
     }
 
+    public string get_engine_path () throws GLib.Error {
+        return this.get_string_variable (ENGINE_PATH_ENV);
+    }
+
+    public string get_media_engine () throws GLib.Error {
+        return this.get_string_variable (MEDIA_ENGINE_ENV);
+    }
+
     public string get_video_upload_folder () throws GLib.Error {
         throw new ConfigurationError.NO_VALUE_SET (_("No value available"));
     }
diff --git a/src/rygel/rygel-main.vala b/src/rygel/rygel-main.vala
index 8207d82..a056989 100644
--- a/src/rygel/rygel-main.vala
+++ b/src/rygel/rygel-main.vala
@@ -2,6 +2,7 @@
  * Copyright (C) 2008 Nokia Corporation.
  * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
  * Copyright (C) 2012 Openismus GmbH.
+ * Copyright (C) 2012 Intel Corporation.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
  *         Jens Georg <jensg openismus com>
@@ -27,9 +28,6 @@ using Gee;
 using GUPnP;
 using Posix;
 
-[CCode (cname="gst_preset_set_app_dir")]
-extern bool gst_preset_set_app_dir (string app_dir);
-
 internal class Rygel.Main : Object {
     private static int PLUGIN_TIMEOUT = 5;
 
@@ -64,8 +62,6 @@ internal class Rygel.Main : Object {
         Unix.signal_add (SIGHUP, () => { this.restart (); return true; });
         Unix.signal_add (SIGINT, () => { this.exit (0); return false; });
         Unix.signal_add (SIGTERM, () => { this.exit (0); return false; });
-
-        gst_preset_set_app_dir (BuildConfig.PRESET_DIR);
     }
 
     public void exit (int exit_code) {
@@ -89,7 +85,7 @@ internal class Rygel.Main : Object {
 
     internal void dbus_available () {
         this.context_manager = this.create_context_manager ();
-        this.plugin_loader.load_plugins ();
+        this.plugin_loader.load_modules ();
 
         var timeout = PLUGIN_TIMEOUT;
         try {
@@ -280,6 +276,7 @@ internal class Rygel.Main : Object {
             // Parse commandline options
             CmdlineConfig.parse_args (ref args);
             Main.register_default_configurations ();
+            MediaEngine.init ();
 
             main = new Main ();
             service = new DBusService (main);
diff --git a/src/rygel/rygel-user-config.vala b/src/rygel/rygel-user-config.vala
index 022bc53..c39fbe8 100644
--- a/src/rygel/rygel-user-config.vala
+++ b/src/rygel/rygel-user-config.vala
@@ -49,6 +49,8 @@ public class Rygel.UserConfig : GLib.Object, Configuration {
     public static const string ALLOW_DELETION_KEY = "allow-deletion";
     public static const string LOG_LEVELS_KEY = "log-level";
     public static const string PLUGIN_PATH_KEY = "plugin-path";
+    public static const string ENGINE_PATH_KEY = "engine-path";
+    public static const string MEDIA_ENGINE_KEY = "media-engine";
     public static const string UPLOAD_FOLDER_KEY = "upload-folder";
     public static const string VIDEO_UPLOAD_DIR_PATH_KEY =
                                         "video-" + UPLOAD_FOLDER_KEY;
@@ -179,6 +181,14 @@ public class Rygel.UserConfig : GLib.Object, Configuration {
         return this.get_string (GENERAL_SECTION, PLUGIN_PATH_KEY);
     }
 
+    public string get_engine_path () throws GLib.Error {
+        return this.get_string (GENERAL_SECTION, ENGINE_PATH_KEY);
+    }
+
+    public string get_media_engine () throws GLib.Error {
+        return this.get_string (GENERAL_SECTION, MEDIA_ENGINE_KEY);
+    }
+
     public string get_video_upload_folder () throws GLib.Error {
         return this.get_string (GENERAL_SECTION, VIDEO_UPLOAD_DIR_PATH_KEY);
     }
diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am
index a5ad827..06cc965 100644
--- a/src/ui/Makefile.am
+++ b/src/ui/Makefile.am
@@ -16,7 +16,7 @@ rygel_preferences_SOURCES =  \
 	rygel-user-config.vala
 
 rygel_preferences_VALAFLAGS = \
-	--thread --pkg gio-2.0 \
+	--pkg gio-2.0 \
 	--pkg gtk+-3.0 $(RYGEL_COMMON_PLUGIN_VALAFLAGS)
 
 rygel_preferences_LDADD = \



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]