[farsight2/master] Make the element addition notification thing into a GObject so that we can use regular signals

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:21:19 PST 2008


---
 docs/libs/farsight-libs-docs.sgml                 |    4 +-
 docs/libs/farsight-libs-sections.txt              |   26 +-
 docs/libs/farsight-libs.types                     |    2 +
 gst-libs/gst/farsight/Makefile.am                 |    4 +-
 gst-libs/gst/farsight/fs-element-added-notifier.c |  452 +++++++++++++++++++++
 gst-libs/gst/farsight/fs-element-added-notifier.h |   97 +++++
 gst-libs/gst/farsight/fs-marshal.list             |    1 +
 gst-libs/gst/farsight/fs-utils.c                  |  411 -------------------
 gst-libs/gst/farsight/fs-utils.h                  |   61 ---
 tests/check/utils/binadded.c                      |   60 ++--
 10 files changed, 605 insertions(+), 513 deletions(-)
 create mode 100644 gst-libs/gst/farsight/fs-element-added-notifier.c
 create mode 100644 gst-libs/gst/farsight/fs-element-added-notifier.h
 delete mode 100644 gst-libs/gst/farsight/fs-utils.c
 delete mode 100644 gst-libs/gst/farsight/fs-utils.h

diff --git a/docs/libs/farsight-libs-docs.sgml b/docs/libs/farsight-libs-docs.sgml
index ab78075..b90a162 100644
--- a/docs/libs/farsight-libs-docs.sgml
+++ b/docs/libs/farsight-libs-docs.sgml
@@ -21,8 +21,8 @@
       <xi:include href="xml/fs-codec.xml"/>
     </chapter>
     <chapter>
-      <title>Farsight Utility Functions</title>
-      <xi:include href="xml/fs-utils.xml"/>
+      <title>Farsight Utility Functions and Objects</title>
+      <xi:include href="xml/fs-element-added-notifier.xml"/>
     </chapter>
   </part>
   <part>
diff --git a/docs/libs/farsight-libs-sections.txt b/docs/libs/farsight-libs-sections.txt
index fe14249..ea5d955 100644
--- a/docs/libs/farsight-libs-sections.txt
+++ b/docs/libs/farsight-libs-sections.txt
@@ -78,7 +78,6 @@ FS_IS_CONFERENCE
 FS_TYPE_CONFERENCE
 fs_conference_get_type
 FS_CONFERENCE_GET_IFACE
-FsConference
 FsConferenceClass
 fs_error_quark
 </SECTION>
@@ -191,11 +190,11 @@ fs_stream_transmitter_get_type
 <SECTION>
 <FILE>fs-plugin</FILE>
 <TITLE>FsPlugin</TITLE>
+FsPlugin
 fs_plugin_create_valist
 fs_plugin_create
 FS_INIT_PLUGIN
 <SUBSECTION Standard>
-FsPlugin
 FsPluginClass
 FS_IS_PLUGIN
 FS_IS_PLUGIN_CLASS
@@ -208,10 +207,21 @@ fs_plugin_get_type
 </SECTION>
 
 <SECTION>
-<FILE>fs-utils</FILE>
-<TITLE>Utils</TITLE>
-FsElementAddedCallback
-fs_utils_add_recursive_element_added_notification
-fs_utils_remove_recursive_element_added_notification
-fs_utils_add_recursive_element_setter_from_keyfile
+<FILE>fs-element-added-notifier</FILE>
+<TITLE>FsElementAddedNotifier</TITLE>
+FsElementAddedNotifier
+fs_element_added_notifier_new
+fs_element_added_notifier_add
+fs_element_added_notifier_remove
+fs_element_added_notifier_set_properties_from_keyfile
+<SUBSECTION Standard>
+FsElementAddedNotifierClass
+FsElementAddedNotifierPrivate
+FS_ELEMENT_ADDED_NOTIFIER
+FS_ELEMENT_ADDED_NOTIFIER_CLASS
+FS_ELEMENT_ADDED_NOTIFIER_GET_CLASS
+FS_IS_ELEMENT_ADDED_NOTIFIER
+FS_IS_ELEMENT_ADDED_NOTIFIER_CLASS
+FS_TYPE_ELEMENT_ADDED_NOTIFIER
+fs_element_added_notifier_get_type
 </SECTION>
diff --git a/docs/libs/farsight-libs.types b/docs/libs/farsight-libs.types
index e924ef2..e092b68 100644
--- a/docs/libs/farsight-libs.types
+++ b/docs/libs/farsight-libs.types
@@ -12,6 +12,7 @@
 #include "../../gst-libs/gst/farsight/fs-base-conference.h"
 #include "../../gst-libs/gst/farsight/fs-transmitter.h"
 #include "../../gst-libs/gst/farsight/fs-stream-transmitter.h"
+#include "../../gst-libs/gst/farsight/fs-element-added-notifier.h"
 
 fs_participant_get_type
 fs_session_get_type
@@ -19,3 +20,4 @@ fs_stream_get_type
 fs_base_conference_get_type
 fs_transmitter_get_type
 fs_stream_transmitter_get_type
+fs_element_added_notifier_get_type
diff --git a/gst-libs/gst/farsight/Makefile.am b/gst-libs/gst/farsight/Makefile.am
index f687cbb..e07d206 100644
--- a/gst-libs/gst/farsight/Makefile.am
+++ b/gst-libs/gst/farsight/Makefile.am
@@ -13,7 +13,7 @@ libgstfarsightinclude_HEADERS = \
 		fs-plugin.h \
 		fs-marshal.h \
 		fs-enum-types.h \
-		fs-utils.h
+		fs-element-added-notifier.h
 
 lib_LTLIBRARIES = libgstfarsight- at GST_MAJORMINOR@.la
 
@@ -38,7 +38,7 @@ libgstfarsight_ at GST_MAJORMINOR@_la_SOURCES = \
 		fs-plugin.c \
 		fs-marshal.c \
 		fs-enum-types.c \
-		fs-utils.c
+		fs-element-added-notifier.c
 
 noinst_HEADERS = \
 	fs-marshal.h \
diff --git a/gst-libs/gst/farsight/fs-element-added-notifier.c b/gst-libs/gst/farsight/fs-element-added-notifier.c
new file mode 100644
index 0000000..068040b
--- /dev/null
+++ b/gst-libs/gst/farsight/fs-element-added-notifier.c
@@ -0,0 +1,452 @@
+/*
+ * Farsight2 - Recursive element addition notifier
+ *
+ * Copyright 2007-2008 Collabora Ltd.
+ *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ * Copyright 2007-2008 Nokia Corp.
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+
+/**
+ * SECTION:fs-element-added-notifier
+ * @short_description: Recursive element addition notifier
+ *
+ * This object can be attach to any #GstBin and will emit a the
+ * #FsElementAddedNotifier::element-added signal for every element inside the
+ * #GstBin or any sub-bin and any element added in the future to the bin or
+ * its sub-bins. There is also a utility method to have it used to
+ * set the properties of elements based on a GKeyfile.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "fs-element-added-notifier.h"
+#include "fs-marshal.h"
+
+
+/* Signals */
+enum
+{
+  ELEMENT_ADDED,
+  LAST_SIGNAL
+};
+
+#define FS_ELEMENT_ADDED_NOTIFIER_GET_PRIVATE(o)                     \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
+      FsElementAddedNotifierPrivate))
+
+struct _FsElementAddedNotifierPrivate {
+  GList *keyfiles;
+};
+
+static void _element_added_callback (GstBin *parent, GstElement *element,
+    gpointer user_data);
+
+static void fs_element_added_notifier_finalize (GObject *object);
+
+
+G_DEFINE_TYPE(FsElementAddedNotifier, fs_element_added_notifier, G_TYPE_OBJECT);
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GObjectClass *parent_class = NULL;
+
+static void
+fs_element_added_notifier_class_init (FsElementAddedNotifierClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class->finalize = fs_element_added_notifier_finalize;
+
+   /**
+   * FsElementAddedNotifier::element-added:
+   * @self: #FsElementAddedNotifier that emitted the signal
+   * @bin: The #GstBin to which this object was added
+   * @element: The #GstElement that was added
+   *
+   * This signal is emitted when an element is added to a #GstBin that was added
+   * to this object or one of its sub-bins.
+   */
+  signals[ELEMENT_ADDED] = g_signal_new ("element-added",
+      G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      0,
+      NULL,
+      NULL,
+      fs_marshal_VOID__OBJECT_OBJECT,
+      G_TYPE_NONE, 2, GST_TYPE_BIN, GST_TYPE_ELEMENT);
+
+  g_type_class_add_private (klass, sizeof (FsElementAddedNotifierPrivate));
+}
+
+
+static void
+fs_element_added_notifier_init (FsElementAddedNotifier *notifier)
+{
+  notifier->priv = FS_ELEMENT_ADDED_NOTIFIER_GET_PRIVATE(notifier);
+}
+
+
+
+static void
+fs_element_added_notifier_finalize (GObject *object)
+{
+  FsElementAddedNotifier *self = FS_ELEMENT_ADDED_NOTIFIER (object);
+
+  g_list_foreach (self->priv->keyfiles, (GFunc) g_key_file_free, NULL);
+  g_list_free (self->priv->keyfiles);
+  self->priv->keyfiles = NULL;
+}
+
+/**
+ * fs_element_added_notifier_new:
+ *
+ * Creates a new #FsElementAddedNotifier object
+ *
+ * Returns: the newly-created #FsElementAddedNotifier
+ */
+
+FsElementAddedNotifier *
+fs_element_added_notifier_new (void)
+{
+  return (FsElementAddedNotifier *)
+    g_object_new (FS_TYPE_ELEMENT_ADDED_NOTIFIER, NULL);
+}
+
+/**
+ * fs_element_added_notifier_add:
+ * @notifier: a #FsElementAddedNotifier
+ * @bin: A #GstBin to watch to added elements
+ *
+ * Add a #GstBin to on which the #FsElementAddedNotifier::element-added signal
+ * will be called on every element and sub-element present and added in the
+ * future.
+ */
+
+void
+fs_element_added_notifier_add (FsElementAddedNotifier *notifier,
+    GstBin *bin)
+{
+  _element_added_callback (NULL, GST_ELEMENT_CAST (bin), notifier);
+}
+
+
+static void
+_bin_unparented_cb (GstObject *object, GstObject *parent, gpointer user_data)
+{
+  GstIterator *iter = NULL;
+  gboolean done;
+
+  /* Return if there was no handler connected */
+  if (g_signal_handlers_disconnect_by_func(object, _element_added_callback,
+          user_data) == 0)
+    return;
+
+  iter = gst_bin_iterate_elements (GST_BIN (object));
+
+  done = FALSE;
+  while (!done)
+  {
+    gpointer item;
+
+    switch (gst_iterator_next (iter, &item)) {
+      case GST_ITERATOR_OK:
+        {
+        if (GST_IS_BIN (item))
+          _bin_unparented_cb (GST_OBJECT (item), object, user_data);
+        }
+        break;
+      case GST_ITERATOR_RESYNC:
+        // We don't rollback anything, we just ignore already processed ones
+        gst_iterator_resync (iter);
+        break;
+      case GST_ITERATOR_ERROR:
+        g_error ("Wrong parameters were given?");
+        done = TRUE;
+        break;
+      case GST_ITERATOR_DONE:
+        done = TRUE;
+        break;
+    }
+  }
+
+  gst_iterator_free (iter);
+}
+
+
+/**
+ * fs_element_added_notifier_remove:
+ * @notifier: a #FsElementAddedNotifier
+ * @bin: A #GstBin to stop watching
+ *
+ * Stop watching the passed bin and its subbins.
+ *
+ * Returns: %TRUE if the #GstBin was being watched, %FALSE otherwise
+ */
+
+gboolean
+fs_element_added_notifier_remove (FsElementAddedNotifier *notifier,
+    GstBin *bin)
+{
+  if (g_signal_handler_find (bin,
+          G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+          0, 0, NULL, /* id, detail, closure */
+          _element_added_callback, notifier) != 0)
+  {
+    _bin_unparented_cb (GST_OBJECT (bin), NULL, notifier);
+    return TRUE;
+  }
+  else
+  {
+    return FALSE;
+  }
+}
+
+
+#if 1
+# define DEBUG(...) do {} while (0)
+#else
+# define DEBUG g_debug
+#endif
+
+static void
+_bin_added_from_keyfile (FsElementAddedNotifier *notifier, GstBin *bin,
+    GstElement *element, gpointer user_data)
+{
+  GKeyFile *keyfile = user_data;
+  GstElementFactory *factory = NULL;
+  const gchar *name;
+  gchar **keys;
+  gint i;
+
+  factory = gst_element_get_factory (element);
+
+  g_assert (factory);
+
+  name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
+
+  if (!name)
+    return;
+
+
+  if (!g_key_file_has_group (keyfile, name))
+    return;
+
+
+  DEBUG ("Found config for %s", name);
+  keys = g_key_file_get_keys (keyfile, name, NULL, NULL);
+
+  for (i = 0; keys[i]; i++)
+  {
+    GParamSpec *param_spec;
+    GValue key_value = { 0 };
+    GValue prop_value = { 0 };
+
+    gchar *str_key_value;
+    gboolean bool_key_value;
+    gint int_key_value;
+    gdouble double_key_value;
+    glong long_key_value;
+    gulong ulong_key_value;
+
+    DEBUG ("getting %s", keys[i]);
+    param_spec = g_object_class_find_property
+      (G_OBJECT_GET_CLASS(element), keys[i]);
+
+    /* If the paremeter does not exist, or is one of those,
+     * then lets skip it
+     * TODO: What if we want to pass GstCaps as strings?
+     */
+    if (!param_spec ||
+        g_type_is_a (param_spec->value_type, G_TYPE_OBJECT) ||
+        g_type_is_a (param_spec->value_type, GST_TYPE_MINI_OBJECT) ||
+        g_type_is_a (param_spec->value_type, G_TYPE_INTERFACE) ||
+        g_type_is_a (param_spec->value_type, G_TYPE_BOXED) ||
+        g_type_is_a (param_spec->value_type, G_TYPE_GTYPE) ||
+        g_type_is_a (param_spec->value_type, G_TYPE_POINTER))
+    {
+      continue;
+    }
+
+    g_value_init (&prop_value, param_spec->value_type);
+
+    switch (param_spec->value_type)
+    {
+      case G_TYPE_STRING:
+        str_key_value = g_key_file_get_value (keyfile, name,
+            keys[i], NULL);
+        g_value_init (&key_value, G_TYPE_STRING);
+        g_value_set_string (&key_value, str_key_value);
+        DEBUG ("%s is a string: %s", keys[i], str_key_value);
+        g_free (str_key_value);
+        break;
+      case G_TYPE_BOOLEAN:
+        bool_key_value = g_key_file_get_boolean (keyfile, name,
+            keys[i], NULL);
+        g_value_init (&key_value, G_TYPE_BOOLEAN);
+        g_value_set_boolean (&key_value, bool_key_value);
+        DEBUG ("%s is a boolean: %d", keys[i], bool_key_value);
+        break;
+      case G_TYPE_UINT64:
+      case G_TYPE_INT64:
+      case G_TYPE_DOUBLE:
+        /* FIXME it seems get_double is only in 2.12, so for now get a
+         * string and convert it to double */
+#if GLIB_CHECK_VERSION(2,12,0)
+        double_key_value = g_key_file_get_double (keyfile, name,
+            keys[i], NULL);
+#else
+        str_key_value = g_key_file_get_value (keyfile, name, keys[i],
+            NULL);
+        double_key_value = g_strtod(str_key_value, NULL);
+#endif
+        g_value_init (&key_value, G_TYPE_DOUBLE);
+        g_value_set_double (&key_value, double_key_value);
+        DEBUG ("%s is a uint64", keys[i]);
+        DEBUG ("%s is a int64", keys[i]);
+        DEBUG ("%s is a double: %f", keys[i], double_key_value);
+        break;
+      case G_TYPE_ULONG:
+        str_key_value = g_key_file_get_value (keyfile, name, keys[i],
+            NULL);
+        ulong_key_value = strtoul(str_key_value, NULL, 10);
+        g_value_init (&key_value, G_TYPE_ULONG);
+        g_value_set_ulong (&key_value, ulong_key_value);
+        DEBUG ("%s is a ulong: %lu", keys[i], ulong_key_value);
+        break;
+      case G_TYPE_LONG:
+        str_key_value = g_key_file_get_value (keyfile, name, keys[i],
+            NULL);
+        long_key_value = strtol(str_key_value, NULL, 10);
+        g_value_init (&key_value, G_TYPE_LONG);
+        g_value_set_long (&key_value, long_key_value);
+        DEBUG ("%s is a long: %ld", keys[i], long_key_value);
+        break;
+      case G_TYPE_INT:
+      case G_TYPE_UINT:
+      case G_TYPE_ENUM:
+      default:
+        int_key_value = g_key_file_get_integer (keyfile, name,
+            keys[i], NULL);
+        g_value_init (&key_value, G_TYPE_INT);
+        g_value_set_int (&key_value, int_key_value);
+        DEBUG ("%s is a int: %d", keys[i], int_key_value);
+        DEBUG ("%s is a uint", keys[i]);
+        DEBUG ("%s is an enum", keys[i]);
+        DEBUG ("%s is something else, attempting to int conv", keys[i]);
+        break;
+    }
+
+    if (!g_value_transform (&key_value, &prop_value))
+    {
+      DEBUG ("Could not transform gvalue pair");
+      continue;
+    }
+
+    DEBUG ("Setting %s to on %s", keys[i], name);
+    g_object_set_property (G_OBJECT(element), keys[i], &prop_value);
+  }
+
+  g_strfreev(keys);
+}
+
+
+/**
+ * fs_element_added_notifier_set_properties_from_keyfile:
+ * @notifier: a #FsElementAddedNotifier
+ * @keyfile: a #GKeyFile
+ *
+ * Using a #GKeyFile where the groups are the element's type and the key=value
+ * are the property and its value, this function will set the properties
+ * on the elements added to this object after this function has been called.
+ * It will take ownership of the GKeyFile structure.
+ */
+void
+fs_element_added_notifier_set_properties_from_keyfile (
+    FsElementAddedNotifier *notifier,
+    GKeyFile *keyfile)
+{
+  g_signal_connect (notifier, "element-added",
+      G_CALLBACK (_bin_added_from_keyfile), keyfile);
+
+  notifier->priv->keyfiles =
+    g_list_prepend (notifier->priv->keyfiles, keyfile);
+}
+
+
+static void
+_element_added_callback (GstBin *parent, GstElement *element,
+    gpointer user_data)
+{
+  FsElementAddedNotifier *notifier = FS_ELEMENT_ADDED_NOTIFIER (user_data);
+
+  if (GST_IS_BIN (element)) {
+    GstIterator *iter = NULL;
+    gboolean done;
+
+    g_object_ref (notifier);
+    g_object_weak_ref (G_OBJECT (element), (GWeakNotify) g_object_unref,
+        notifier);
+    g_signal_connect (element, "element-added",
+        G_CALLBACK (_element_added_callback), notifier);
+
+    if (parent)
+      g_signal_connect (element, "parent-unset",
+          G_CALLBACK (_bin_unparented_cb), notifier);
+
+    iter = gst_bin_iterate_elements (GST_BIN (element));
+
+    done = FALSE;
+    while (!done)
+    {
+      gpointer item = NULL;
+
+      switch (gst_iterator_next (iter, &item)) {
+       case GST_ITERATOR_OK:
+         /* We make sure the callback has not already been added */
+         if (g_signal_handler_find (item,
+                 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+                 0, 0, NULL, /* id, detail, closure */
+                 _element_added_callback, notifier) == 0)
+           _element_added_callback (GST_BIN_CAST (element), item, notifier);
+         gst_object_unref (item);
+         break;
+       case GST_ITERATOR_RESYNC:
+         // We don't rollback anything, we just ignore already processed ones
+         gst_iterator_resync (iter);
+         break;
+       case GST_ITERATOR_ERROR:
+         g_error ("Wrong parameters were given?");
+         done = TRUE;
+         break;
+       case GST_ITERATOR_DONE:
+         done = TRUE;
+         break;
+     }
+    }
+
+    gst_iterator_free (iter);
+  }
+
+  g_signal_emit (notifier, signals[ELEMENT_ADDED], 0, parent, element);
+}
+
diff --git a/gst-libs/gst/farsight/fs-element-added-notifier.h b/gst-libs/gst/farsight/fs-element-added-notifier.h
new file mode 100644
index 0000000..aa62895
--- /dev/null
+++ b/gst-libs/gst/farsight/fs-element-added-notifier.h
@@ -0,0 +1,97 @@
+/*
+ * Farsight2 - Recursive element addition notifier
+ *
+ * Copyright 2007-2008 Collabora Ltd.
+ *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
+ * Copyright 2007-2008 Nokia Corp.
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __FS_ELEMENT_ADDED_NOTIFIER_H__
+#define __FS_ELEMENT_ADDED_NOTIFIER_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+
+/* TYPE MACROS */
+#define FS_TYPE_ELEMENT_ADDED_NOTIFIER \
+  (fs_element_added_notifier_get_type())
+#define FS_ELEMENT_ADDED_NOTIFIER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER,    \
+      FsElementAddedNotifier))
+#define FS_ELEMENT_ADDED_NOTIFIER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_ELEMENT_ADDED_NOTIFIER,     \
+      FsElementAddedNotifierClass))
+#define FS_IS_ELEMENT_ADDED_NOTIFIER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER))
+#define FS_IS_ELEMENT_ADDED_NOTIFIER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_ELEMENT_ADDED_NOTIFIER))
+#define FS_ELEMENT_ADDED_NOTIFIER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER,    \
+      FsElementAddedNotifierClass))
+
+
+typedef struct _FsElementAddedNotifier FsElementAddedNotifier;
+typedef struct _FsElementAddedNotifierClass FsElementAddedNotifierClass;
+typedef struct _FsElementAddedNotifierPrivate FsElementAddedNotifierPrivate;
+
+/**
+ * FsElementAddedNotifier:
+ * @parent: the #GObject parent
+ *
+ * All members are private
+ */
+
+struct _FsElementAddedNotifier
+{
+  GObject parent;
+
+  /*< private >*/
+
+  FsElementAddedNotifierPrivate *priv;
+};
+
+/**
+ * FsElementAddedNotifierClass:
+ * @parent_class: the #GObjectClass parent
+ *
+ * All members are private
+ */
+struct _FsElementAddedNotifierClass
+{
+  GObjectClass parent_class;
+};
+
+
+GType fs_element_added_notifier_get_type (void);
+
+FsElementAddedNotifier *fs_element_added_notifier_new (void);
+
+void fs_element_added_notifier_add (FsElementAddedNotifier *notifier,
+    GstBin *bin);
+
+gboolean fs_element_added_notifier_remove (FsElementAddedNotifier *notifier,
+    GstBin *bin);
+
+void fs_element_added_notifier_set_properties_from_keyfile (
+    FsElementAddedNotifier *notifier,
+    GKeyFile *keyfile);
+
+G_END_DECLS
+
+#endif /* __FS_ELEMENT_ADDED_NOTIFIER_H__ */
diff --git a/gst-libs/gst/farsight/fs-marshal.list b/gst-libs/gst/farsight/fs-marshal.list
index 5b8f6ef..e16bb50 100644
--- a/gst-libs/gst/farsight/fs-marshal.list
+++ b/gst-libs/gst/farsight/fs-marshal.list
@@ -1,3 +1,4 @@
 VOID:OBJECT,INT,STRING,STRING
 VOID:INT,STRING,STRING
 VOID:BOXED,BOXED
+VOID:OBJECT,OBJECT
diff --git a/gst-libs/gst/farsight/fs-utils.c b/gst-libs/gst/farsight/fs-utils.c
deleted file mode 100644
index d1eb424..0000000
--- a/gst-libs/gst/farsight/fs-utils.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Farsight2 - Utility functions
- *
- * Copyright 2007 Collabora Ltd.
- *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
- * Copyright 2007 Nokia Corp.
- *
- * fs-session.h - A Farsight Session gobject (base implementation)
- *
- * This library 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.1 of the License, or (at your option) any later version.
- *
- * This library 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 library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-
-/**
- * SECTION:fs-utils
- * @short_description: Various utility functions
- *
- * This file contains various utility functions for farsight
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "fs-utils.h"
-
-struct FsElementAddedData {
-  gint refcount;
-  FsElementAddedCallback callback;
-  gpointer user_data;
-  GstElement *head;
-};
-
-
-static gpointer _element_added_callback (GstBin *parent, GstElement *element,
-    gpointer user_data);
-
-
-static struct FsElementAddedData *
-element_added_data_new (FsElementAddedCallback callback, gpointer user_data,
-                        GstElement *head)
-{
-  struct FsElementAddedData *data =
-    g_new (struct FsElementAddedData, 1);
-
-  data->refcount = 0;
-  data->callback = callback;
-  data->user_data = user_data;
-  data->head = head;
-
-  return data;
-}
-
-static void
-element_added_data_inc (struct FsElementAddedData *data)
-{
-  g_atomic_int_inc (&data->refcount);
-}
-
-
-static void
-element_added_data_dec (struct FsElementAddedData *data)
-{
-  if (g_atomic_int_dec_and_test (&data->refcount))
-  {
-    g_free (data);
-  }
-}
-
-
-static void
-_bin_unparented_cb (GstObject *object, GstObject *parent, gpointer user_data)
-{
-  GstIterator *iter = NULL;
-  gboolean done;
-
-  /* Return if there was no handler connected */
-  if (g_signal_handlers_disconnect_by_func(object, _element_added_callback,
-          user_data) == 0)
-    return;
-
-  iter = gst_bin_iterate_elements (GST_BIN (object));
-
-  done = FALSE;
-  while (!done)
-  {
-    gpointer item;
-
-    switch (gst_iterator_next (iter, &item)) {
-      case GST_ITERATOR_OK:
-        {
-        if (GST_IS_BIN (item))
-          _bin_unparented_cb (GST_OBJECT (item), object, user_data);
-        }
-        break;
-      case GST_ITERATOR_RESYNC:
-        // We don't rollback anything, we just ignore already processed ones
-        gst_iterator_resync (iter);
-        break;
-      case GST_ITERATOR_ERROR:
-        g_error ("Wrong parameters were given?");
-        done = TRUE;
-        break;
-      case GST_ITERATOR_DONE:
-        done = TRUE;
-        break;
-    }
-  }
-
-  gst_iterator_free (iter);
-}
-
-static gpointer
-_element_added_callback (GstBin *parent, GstElement *element,
-    gpointer user_data)
-{
-  struct FsElementAddedData *data = user_data;
-
-  if (GST_IS_BIN (element)) {
-    GstIterator *iter = NULL;
-    gboolean done;
-
-    element_added_data_inc (data);
-    g_object_weak_ref (G_OBJECT (element), (GWeakNotify) element_added_data_dec,
-        user_data);
-    g_signal_connect (element, "element-added",
-        G_CALLBACK (_element_added_callback), user_data);
-
-    if (data->head != element)
-      g_signal_connect (element, "parent-unset",
-          G_CALLBACK (_bin_unparented_cb), user_data);
-
-    iter = gst_bin_iterate_elements (GST_BIN (element));
-
-    done = FALSE;
-    while (!done)
-    {
-      gpointer item = NULL;
-
-      switch (gst_iterator_next (iter, &item)) {
-       case GST_ITERATOR_OK:
-         /* We make sure the callback has not already been added */
-         if (g_signal_handler_find (item,
-                 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
-                 0, 0, NULL, /* id, detail, closure */
-                 _element_added_callback, user_data) == 0)
-           _element_added_callback (GST_BIN_CAST (element), item, user_data);
-         gst_object_unref (item);
-         break;
-       case GST_ITERATOR_RESYNC:
-         // We don't rollback anything, we just ignore already processed ones
-         gst_iterator_resync (iter);
-         break;
-       case GST_ITERATOR_ERROR:
-         g_error ("Wrong parameters were given?");
-         done = TRUE;
-         break;
-       case GST_ITERATOR_DONE:
-         done = TRUE;
-         break;
-     }
-    }
-
-    gst_iterator_free (iter);
-  }
-
-  data->callback (parent, element, data->user_data);
-
-  return data;
-}
-
-/**
- * fs_utils_add_recursive_element_added_notification:
- * @element: A #GstElement
- * @callback: the function to be called when a new element is added
- * @user_data: data that will be passed to the callback
- *
- * The callback will be called on the element and every sub-element if its a
- * bin and this will be done recursively. The function will also be called on
- * any element added in the future to the bin. The callback may be called more
- * than once and should be thread safe (elements may be added from the streaming
- * threads).
- *
- * Returns: a handle that can be used when calling
- *  fs_utils_remove_recursive_element_added_notification(), or NULL if there was
- *  an error
- */
-
-gpointer
-fs_utils_add_recursive_element_added_notification (GstElement *element,
-    FsElementAddedCallback callback,
-    gpointer user_data)
-{
-  g_assert (callback);
-
-  return _element_added_callback (NULL, element,
-      element_added_data_new (callback, user_data, element));
-}
-
-/**
- * fs_utils_remove_recursive_element_added_notification:
- * @element: a #GstElement on which
- *  fs_utils_add_recursive_element_added_notification() has been called
- * @handle: the handle returned by
- *     fs_utils_add_recursive_element_added_notification()
- *
- * This function will remove the callback added by
- * fs_utils_add_recursive_element_added_notification()
- *
- * Returns: TRUE if the notification could be removed, FALSE otherwise
- */
-gboolean
-fs_utils_remove_recursive_element_added_notification (GstElement *element,
-    gpointer handle)
-{
-  struct FsElementAddedData *data = handle;
-
-  if (g_signal_handler_find (element,
-          G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
-          0, 0, NULL, /* id, detail, closure */
-          _element_added_callback, data) != 0)
-  {
-    g_assert (data->head == element);
-    _bin_unparented_cb (GST_OBJECT (data->head), NULL, data);
-    return TRUE;
-  }
-  else
-  {
-    return FALSE;
-  }
-}
-
-#if 1
-# define DEBUG(...) do {} while (0)
-#else
-# define DEBUG g_debug
-#endif
-
-static void
-_bin_added_from_keyfile (GstBin *bin, GstElement *element, gpointer user_data)
-{
-  GKeyFile *keyfile = user_data;
-  GstElementFactory *factory = NULL;
-  const gchar *name;
-  gchar **keys;
-  gint i;
-
-  factory = gst_element_get_factory (element);
-
-  g_assert (factory);
-
-  name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
-
-  if (!name)
-    return;
-
-
-  if (!g_key_file_has_group (keyfile, name))
-    return;
-
-
-  DEBUG ("Found config for %s", name);
-  keys = g_key_file_get_keys (keyfile, name, NULL, NULL);
-
-  for (i = 0; keys[i]; i++)
-  {
-    GParamSpec *param_spec;
-    GValue key_value = { 0 };
-    GValue prop_value = { 0 };
-
-    gchar *str_key_value;
-    gboolean bool_key_value;
-    gint int_key_value;
-    gdouble double_key_value;
-    glong long_key_value;
-    gulong ulong_key_value;
-
-    DEBUG ("getting %s", keys[i]);
-    param_spec = g_object_class_find_property
-      (G_OBJECT_GET_CLASS(element), keys[i]);
-
-    /* If the paremeter does not exist, or is one of those,
-     * then lets skip it
-     * TODO: What if we want to pass GstCaps as strings?
-     */
-    if (!param_spec ||
-        g_type_is_a (param_spec->value_type, G_TYPE_OBJECT) ||
-        g_type_is_a (param_spec->value_type, GST_TYPE_MINI_OBJECT) ||
-        g_type_is_a (param_spec->value_type, G_TYPE_INTERFACE) ||
-        g_type_is_a (param_spec->value_type, G_TYPE_BOXED) ||
-        g_type_is_a (param_spec->value_type, G_TYPE_GTYPE) ||
-        g_type_is_a (param_spec->value_type, G_TYPE_POINTER))
-    {
-      continue;
-    }
-
-    g_value_init (&prop_value, param_spec->value_type);
-
-    switch (param_spec->value_type)
-    {
-      case G_TYPE_STRING:
-        str_key_value = g_key_file_get_value (keyfile, name,
-            keys[i], NULL);
-        g_value_init (&key_value, G_TYPE_STRING);
-        g_value_set_string (&key_value, str_key_value);
-        DEBUG ("%s is a string: %s", keys[i], str_key_value);
-        g_free (str_key_value);
-        break;
-      case G_TYPE_BOOLEAN:
-        bool_key_value = g_key_file_get_boolean (keyfile, name,
-            keys[i], NULL);
-        g_value_init (&key_value, G_TYPE_BOOLEAN);
-        g_value_set_boolean (&key_value, bool_key_value);
-        DEBUG ("%s is a boolean: %d", keys[i], bool_key_value);
-        break;
-      case G_TYPE_UINT64:
-      case G_TYPE_INT64:
-      case G_TYPE_DOUBLE:
-        /* FIXME it seems get_double is only in 2.12, so for now get a
-         * string and convert it to double */
-#if GLIB_CHECK_VERSION(2,12,0)
-        double_key_value = g_key_file_get_double (keyfile, name,
-            keys[i], NULL);
-#else
-        str_key_value = g_key_file_get_value (keyfile, name, keys[i],
-            NULL);
-        double_key_value = g_strtod(str_key_value, NULL);
-#endif
-        g_value_init (&key_value, G_TYPE_DOUBLE);
-        g_value_set_double (&key_value, double_key_value);
-        DEBUG ("%s is a uint64", keys[i]);
-        DEBUG ("%s is a int64", keys[i]);
-        DEBUG ("%s is a double: %f", keys[i], double_key_value);
-        break;
-      case G_TYPE_ULONG:
-        str_key_value = g_key_file_get_value (keyfile, name, keys[i],
-            NULL);
-        ulong_key_value = strtoul(str_key_value, NULL, 10);
-        g_value_init (&key_value, G_TYPE_ULONG);
-        g_value_set_ulong (&key_value, ulong_key_value);
-        DEBUG ("%s is a ulong: %lu", keys[i], ulong_key_value);
-        break;
-      case G_TYPE_LONG:
-        str_key_value = g_key_file_get_value (keyfile, name, keys[i],
-            NULL);
-        long_key_value = strtol(str_key_value, NULL, 10);
-        g_value_init (&key_value, G_TYPE_LONG);
-        g_value_set_long (&key_value, long_key_value);
-        DEBUG ("%s is a long: %ld", keys[i], long_key_value);
-        break;
-      case G_TYPE_INT:
-      case G_TYPE_UINT:
-      case G_TYPE_ENUM:
-      default:
-        int_key_value = g_key_file_get_integer (keyfile, name,
-            keys[i], NULL);
-        g_value_init (&key_value, G_TYPE_INT);
-        g_value_set_int (&key_value, int_key_value);
-        DEBUG ("%s is a int: %d", keys[i], int_key_value);
-        DEBUG ("%s is a uint", keys[i]);
-        DEBUG ("%s is an enum", keys[i]);
-        DEBUG ("%s is something else, attempting to int conv", keys[i]);
-        break;
-    }
-
-    if (!g_value_transform (&key_value, &prop_value))
-    {
-      DEBUG ("Could not transform gvalue pair");
-      continue;
-    }
-
-    DEBUG ("Setting %s to on %s", keys[i], name);
-    g_object_set_property (G_OBJECT(element), keys[i], &prop_value);
-  }
-
-  g_strfreev(keys);
-}
-
-/**
- * fs_utils_add_recursive_element_setter_from_keyfile:
- * @element: a #GstElement
- * @keyfile: a #GKeyFile
- *
- * Using a keyfile where the groups are the element's type and the key=value
- * are the property and its value, this function will set the properties on the
- * element passed and its subelements.
- *
- * Returns: a handle that can be used for
- *  fs_utils_remove_recursive_element_added_notification(), or NULL if there is
- *  an error
- */
-gpointer
-fs_utils_add_recursive_element_setter_from_keyfile (GstElement *element,
-    GKeyFile *keyfile)
-{
-  return fs_utils_add_recursive_element_added_notification (element,
-      _bin_added_from_keyfile,
-      keyfile);
-}
diff --git a/gst-libs/gst/farsight/fs-utils.h b/gst-libs/gst/farsight/fs-utils.h
deleted file mode 100644
index 4dcb0d4..0000000
--- a/gst-libs/gst/farsight/fs-utils.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Farsight2 - Utility functions
- *
- * Copyright 2007 Collabora Ltd.
- *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
- * Copyright 2007 Nokia Corp.
- *
- * fs-session.h - A Farsight Session gobject (base implementation)
- *
- * This library 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.1 of the License, or (at your option) any later version.
- *
- * This library 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 library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef __FS_UTILS_H__
-#define __FS_UTILS_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-/**
- * FsElementAddedCallback:
- * @bin: The #GstBin to which the element was added, will be NULL if the element
- *   is the top-level bin
- * @element: The just-added #GstElement
- * @user_data: The user data passed by the user
- *
- * The callback used by #fs_utils_add_recursive_element_added_notification
- */
-
-typedef void (*FsElementAddedCallback) (GstBin *bin,
-    GstElement *element,
-    gpointer user_data);
-
-gpointer fs_utils_add_recursive_element_added_notification (GstElement *element,
-    FsElementAddedCallback callback,
-    gpointer user_data);
-
-gboolean fs_utils_remove_recursive_element_added_notification (
-    GstElement *element,
-    gpointer handle);
-
-
-gpointer fs_utils_add_recursive_element_setter_from_keyfile (
-    GstElement *element,
-    GKeyFile *keyfile);
-
-G_END_DECLS
-
-#endif /* __FS_UTILS_H__ */
diff --git a/tests/check/utils/binadded.c b/tests/check/utils/binadded.c
index acca926..5d1891f 100644
--- a/tests/check/utils/binadded.c
+++ b/tests/check/utils/binadded.c
@@ -24,14 +24,15 @@
 #endif
 
 #include <gst/check/gstcheck.h>
-#include <gst/farsight/fs-utils.h>
+#include <gst/farsight/fs-element-added-notifier.h>
 
 gboolean called = FALSE;
 gpointer last_added = NULL;
 gpointer last_bin = NULL;
 
 static void
-_added_cb (GstBin *bin, GstElement *element, gpointer user_data)
+_added_cb (FsElementAddedNotifier *notifier, GstBin *bin, GstElement *element,
+    gpointer user_data)
 {
   GstObject *parent = NULL;
 
@@ -54,17 +55,19 @@ GST_START_TEST (test_bin_added_simple)
 {
   GstElement *pipeline = NULL;
   GstElement *identity = NULL;
-  gpointer handle = NULL;
+  FsElementAddedNotifier *notifier = NULL;
 
   pipeline = gst_pipeline_new (NULL);
 
   identity = gst_element_factory_make ("identity", NULL);
   gst_object_ref (identity);
 
-  handle = fs_utils_add_recursive_element_added_notification (pipeline,
-      _added_cb, &last_added);
+  notifier = fs_element_added_notifier_new ();
 
-  fail_if (handle == NULL, "Could not add notification to pipeline");
+  g_signal_connect (notifier, "element-added",
+      G_CALLBACK (_added_cb), &last_added);
+
+  fs_element_added_notifier_add (notifier, GST_BIN (pipeline));
 
   fail_unless (gst_bin_add (GST_BIN (pipeline), identity),
       "Could not add identity to pipeline");
@@ -85,10 +88,9 @@ GST_START_TEST (test_bin_added_simple)
   called = FALSE;
   last_added = last_bin = NULL;
 
-
   fail_unless (
-      fs_utils_remove_recursive_element_added_notification (pipeline, handle),
-      "Could not remove notification handle %p", handle);
+      fs_element_added_notifier_remove (notifier, GST_BIN (pipeline)),
+      "Could not remove notification");
 
   fail_unless (gst_bin_add (GST_BIN (pipeline), identity),
       "Could not add identity to pipeline");
@@ -98,6 +100,7 @@ GST_START_TEST (test_bin_added_simple)
   called = FALSE;
   last_added = last_bin = NULL;
 
+  g_object_unref (notifier);
   gst_object_unref (identity);
   gst_object_unref (pipeline);
 }
@@ -109,7 +112,7 @@ GST_START_TEST (test_bin_added_recursive)
   GstElement *pipeline = NULL;
   GstElement *bin = NULL;
   GstElement *identity = NULL;
-  gpointer handle = NULL;
+  FsElementAddedNotifier *notifier = NULL;
 
   pipeline = gst_pipeline_new (NULL);
 
@@ -121,10 +124,12 @@ GST_START_TEST (test_bin_added_recursive)
   identity = gst_element_factory_make ("identity", NULL);
   gst_object_ref (identity);
 
-  handle = fs_utils_add_recursive_element_added_notification (pipeline,
-      _added_cb, &last_added);
+  notifier = fs_element_added_notifier_new ();
+
+  g_signal_connect (notifier, "element-added",
+      G_CALLBACK (_added_cb), &last_added);
 
-  fail_if (handle == NULL, "Could not add notification to bin");
+  fs_element_added_notifier_add (notifier, GST_BIN (pipeline));
 
   fail_unless (gst_bin_add (GST_BIN (bin), identity),
       "Could not add identity to bin");
@@ -147,8 +152,8 @@ GST_START_TEST (test_bin_added_recursive)
 
 
   fail_unless (
-      fs_utils_remove_recursive_element_added_notification (pipeline, handle),
-      "Could not remove notification handle %p", handle);
+      fs_element_added_notifier_remove (notifier, GST_BIN (pipeline)),
+      "Could not remove notification");
 
   fail_unless (gst_bin_add (GST_BIN (bin), identity),
       "Could not add identity to bin");
@@ -158,10 +163,7 @@ GST_START_TEST (test_bin_added_recursive)
   fail_unless (gst_bin_remove (GST_BIN (bin), identity),
       "Could not remove identity from bin");
 
-  handle = fs_utils_add_recursive_element_added_notification (pipeline,
-      _added_cb, &last_added);
-
-  fail_if (handle == NULL, "Could not re-add notification to bin");
+  fs_element_added_notifier_add (notifier, GST_BIN (pipeline));
 
   called = FALSE;
   last_added = last_bin = NULL;
@@ -175,6 +177,7 @@ GST_START_TEST (test_bin_added_recursive)
       " but the callback was still called");
 
 
+  g_object_unref (notifier);
   gst_object_unref (identity);
   gst_object_unref (bin);
   gst_object_unref (pipeline);
@@ -187,7 +190,7 @@ GST_START_TEST (test_bin_keyfile)
   GKeyFile *keyfile = g_key_file_new ();
   GstElement *pipeline = NULL;
   GstElement *identity = NULL;
-  gpointer handle = NULL;
+  FsElementAddedNotifier *notifier = NULL;
   gboolean sync;
 
   g_key_file_set_boolean (keyfile, "identity", "sync", TRUE);
@@ -200,9 +203,11 @@ GST_START_TEST (test_bin_keyfile)
   g_object_get (identity, "sync", &sync, NULL);
   fail_unless (sync == FALSE, "sync prop on identity does not start at FALSE");
 
-  handle = fs_utils_add_recursive_element_setter_from_keyfile (pipeline,
-      keyfile);
-  fail_if (handle == NULL, "Could not add notification to pipeline");
+  notifier = fs_element_added_notifier_new ();
+
+  fs_element_added_notifier_set_properties_from_keyfile (notifier, keyfile);
+
+  fs_element_added_notifier_add (notifier, GST_BIN (pipeline));
 
   fail_unless (gst_bin_add (GST_BIN (pipeline), identity),
       "Could not add identity to pipeline");
@@ -220,8 +225,8 @@ GST_START_TEST (test_bin_keyfile)
   fail_unless (sync == FALSE, "sync prop on identity not reset to FALSE");
 
   fail_unless (
-      fs_utils_remove_recursive_element_added_notification (pipeline, handle),
-      "Could not remove notification handle %p", handle);
+      fs_element_added_notifier_remove (notifier, GST_BIN (pipeline)),
+      "Could not remove notification");
 
   fail_unless (gst_bin_add (GST_BIN (pipeline), identity),
       "Could not add identity to bin");
@@ -229,16 +234,13 @@ GST_START_TEST (test_bin_keyfile)
   g_object_get (identity, "sync", &sync, NULL);
   fail_if (sync == TRUE, "sync prop on identity changed to TRUE");
 
-  handle = fs_utils_add_recursive_element_setter_from_keyfile (pipeline,
-      keyfile);
-  fail_if (handle == NULL, "Could not add notification to pipeline");
+  fs_element_added_notifier_add (notifier, GST_BIN (pipeline));
 
   g_object_get (identity, "sync", &sync, NULL);
   fail_unless (sync == TRUE, "sync prop on identity is not changed to TRUE");
 
   gst_object_unref (identity);
   gst_object_unref (pipeline);
-  g_key_file_free (keyfile);
 }
 GST_END_TEST;
 
-- 
1.5.6.5




More information about the farsight-commits mailing list