gst/elements/gsttee.c: Remove usage of gst_pad_proxy_fixate.
authorDavid Schleef <ds@schleef.org>
Sun, 4 Jan 2004 23:43:11 +0000 (23:43 +0000)
committerDavid Schleef <ds@schleef.org>
Sun, 4 Jan 2004 23:43:11 +0000 (23:43 +0000)
Original commit message from CVS:
* gst/elements/gsttee.c: (gst_tee_init), (gst_tee_request_new_pad):
Remove usage of gst_pad_proxy_fixate.
* gst/gstcaps.c: (gst_caps_append), (gst_caps_append_structure),
(gst_caps_split_one), (gst_caps_replace):
Add poisoning code.
* gst/gstmarshal.list:
Add pointer__pointer for fixate signal
* gst/gstpad.c: (gst_real_pad_class_init),
(_gst_real_pad_fixate_accumulator), (gst_pad_link_fixate),
(_gst_pad_default_fixate_func), (gst_pad_proxy_fixate),
(gst_pad_set_explicit_caps), (gst_pad_template_new):
Add poisoning code. Add fixate signal on RealPad. Change
set_explicit_caps() to take const GstCaps, like try_set_caps().
* gst/gstpad.h:
* testsuite/caps/Makefile.am:
* testsuite/caps/app_fixate.c: Add a test for the fixate signal

ChangeLog
gst/elements/gsttee.c
gst/gstcaps.c
gst/gstmarshal.list
gst/gstpad.c
gst/gstpad.h
plugins/elements/gsttee.c
tests/old/testsuite/caps/Makefile.am
tests/old/testsuite/caps/app_fixate.c [new file with mode: 0644]
testsuite/caps/Makefile.am
testsuite/caps/app_fixate.c [new file with mode: 0644]

index 93c3b27..9f8e310 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2004-01-04  David Schleef  <ds@schleef.org>
+
+       * gst/elements/gsttee.c: (gst_tee_init), (gst_tee_request_new_pad):
+       Remove usage of gst_pad_proxy_fixate.
+       * gst/gstcaps.c: (gst_caps_append), (gst_caps_append_structure),
+       (gst_caps_split_one), (gst_caps_replace):
+       Add poisoning code.
+       * gst/gstmarshal.list:
+       Add pointer__pointer for fixate signal
+       * gst/gstpad.c: (gst_real_pad_class_init),
+       (_gst_real_pad_fixate_accumulator), (gst_pad_link_fixate),
+       (_gst_pad_default_fixate_func), (gst_pad_proxy_fixate),
+       (gst_pad_set_explicit_caps), (gst_pad_template_new):
+       Add poisoning code. Add fixate signal on RealPad. Change
+       set_explicit_caps() to take const GstCaps, like try_set_caps().
+       * gst/gstpad.h:
+       * testsuite/caps/Makefile.am:
+       * testsuite/caps/app_fixate.c: Add a test for the fixate signal
+
 2004-01-03  David Schleef  <ds@schleef.org>
 
        * gst/elements/gsttypefindelement.c:
index 55eb46e..c2b1cf2 100644 (file)
@@ -145,7 +145,6 @@ gst_tee_init (GstTee *tee)
   gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain));
   gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
   gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
-  gst_pad_set_fixate_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate));
 
   tee->silent = FALSE;
   tee->last_message = NULL;
@@ -205,7 +204,6 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
   g_free (name);
   gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
   gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
-  gst_pad_set_fixate_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate));
   gst_element_add_pad (GST_ELEMENT (tee), srcpad);
   GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL;
 
index 3d446d7..8724ce1 100644 (file)
 
 #include <gst/gst.h>
 
+#define CAPS_POISON(caps) do{ \
+  GstCaps *_newcaps = gst_caps_copy (caps); \
+  gst_caps_free(caps); \
+  caps = _newcaps; \
+} while (0)
+#define STRUCTURE_POISON(structure) do{ \
+  GstStructure *_newstruct = gst_structure_copy (structure); \
+  gst_structure_free(structure); \
+  structure = _newstruct; \
+} while (0)
+
+
 static void _gst_caps_transform_to_string (const GValue *src_value,
     GValue *dest_value);
 static void _gst_caps_value_init (GValue *value);
@@ -210,6 +222,9 @@ void gst_caps_append (GstCaps *caps1, GstCaps *caps2)
   g_return_if_fail (caps1 != NULL);
   g_return_if_fail (caps2 != NULL);
 
+#ifdef USE_POISONING
+  CAPS_POISON (caps2);
+#endif
   for(i=0;i<caps2->structs->len;i++){
     structure = gst_caps_get_structure (caps2, i);
     gst_caps_append_structure (caps1, structure);
@@ -225,6 +240,9 @@ void gst_caps_append_structure (GstCaps *caps, GstStructure *structure)
 {
   g_return_if_fail(caps != NULL);
 
+#ifdef USE_POISONING
+  STRUCTURE_POISON (structure);
+#endif
   if (structure){
     g_ptr_array_add (caps->structs, structure);
   }
@@ -233,6 +251,7 @@ void gst_caps_append_structure (GstCaps *caps, GstStructure *structure)
 GstCaps *gst_caps_split_one (GstCaps *caps)
 {
   /* FIXME */
+  g_critical ("unimplemented");
 
   return NULL;
 }
@@ -731,6 +750,9 @@ GstCaps *gst_caps_load_thyself (xmlNodePtr parent)
 /* utility */
 void gst_caps_replace (GstCaps **caps, GstCaps *newcaps)
 {
+#ifdef USE_POISONING
+  if (newcaps) CAPS_POISON (newcaps);
+#endif
   if (*caps) gst_caps_free(*caps);
   *caps = newcaps;
 }
index f136fbb..261e1ed 100644 (file)
@@ -14,3 +14,4 @@ VOID:UINT,BOXED
 VOID:UINT,POINTER
 BOOLEAN:VOID
 BOOLEAN:POINTER
+POINTER:POINTER
index d6c38cd..3e6ad9e 100644 (file)
@@ -54,7 +54,7 @@ static void           gst_pad_init                    (GstPad *pad);
 static void            gst_pad_dispose                 (GObject *object);
 
 static void            gst_pad_set_pad_template        (GstPad *pad, GstPadTemplate *templ);
-static GstCaps *        _gst_pad_default_fixate_func    (GstPad *pad, GstCaps *caps, gpointer unused);
+static GstCaps *        _gst_pad_default_fixate_func    (GstPad *pad, const GstCaps *caps);
 
 static gboolean                gst_pad_link_try                (GstPadLink *link);
 static void             gst_pad_link_free               (GstPadLink *link);
@@ -117,6 +117,7 @@ enum {
   REAL_CAPS_NEGO_FAILED,
   REAL_LINKED,
   REAL_UNLINKED,
+  REAL_FIXATE,
   /* FILL ME */
   REAL_LAST_SIGNAL
 };
@@ -132,6 +133,8 @@ static void gst_real_pad_class_init         (GstRealPadClass *klass);
 static void    gst_real_pad_init               (GstRealPad *pad);
 static void    gst_real_pad_dispose            (GObject *object);
 
+static gboolean _gst_real_pad_fixate_accumulator (GSignalInvocationHint *ihint,
+    GValue *return_accu, const GValue *handler_return, gpointer dummy);
 static void    gst_real_pad_set_property       (GObject *object, guint prop_id,
                                                  const GValue *value, 
                                                 GParamSpec *pspec);
@@ -190,6 +193,12 @@ gst_real_pad_class_init (GstRealPadClass *klass)
                   G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL,
                   gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
                   GST_TYPE_PAD);
+  gst_real_pad_signals[REAL_FIXATE] =
+    g_signal_new ("fixate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GstRealPadClass, appfixatefunc), 
+                 _gst_real_pad_fixate_accumulator, NULL,
+                 gst_marshal_POINTER__POINTER, G_TYPE_POINTER, 1,
+                  G_TYPE_POINTER);
 
 /*  gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
 /*                           GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
@@ -206,6 +215,17 @@ gst_real_pad_class_init (GstRealPadClass *klass)
   gstobject_class->path_string_separator = ".";
 }
 
+static gboolean
+_gst_real_pad_fixate_accumulator (GSignalInvocationHint *ihint,
+    GValue *return_accu, const GValue *handler_return, gpointer dummy)
+{
+  if (g_value_get_pointer (handler_return)) {
+    /* stop emission if something was returned */
+    return FALSE;
+  }
+  return TRUE;
+}
+
 static void
 gst_real_pad_init (GstRealPad *pad)
 {
@@ -1059,38 +1079,49 @@ gst_pad_link_fixate (GstPadLink *link)
   GST_DEBUG_CAPS ("trying to fixate caps", caps);
 
   while (!gst_caps_is_fixed (caps)) {
-    if (link->app_fixate) {
-      newcaps = (link->app_fixate) (GST_PAD (link->srcpad), caps, NULL);
-      if (newcaps) {
-        caps = newcaps;
-        GST_DEBUG_CAPS ("app fixated to", caps);
-        continue;
-      }
-    }
-    if (GST_RPAD_FIXATEFUNC(link->srcpad)) {
-      newcaps = GST_RPAD_FIXATEFUNC(link->srcpad) (GST_PAD (link->srcpad),
-          caps, NULL);
-      if (newcaps) {
-        caps = newcaps;
-        GST_DEBUG_CAPS ("src pad fixated to", caps);
-        continue;
+    int i;
+
+    for (i=0;i<5;i++){
+      newcaps = NULL;
+      switch (i) {
+       case 0:
+         g_signal_emit (G_OBJECT (link->srcpad),
+             gst_real_pad_signals[REAL_FIXATE], 0, caps, &newcaps);
+         GST_DEBUG_CAPS ("app srcpad signal fixated to", newcaps);
+         break;
+       case 1:
+         g_signal_emit (G_OBJECT (link->sinkpad),
+             gst_real_pad_signals[REAL_FIXATE], 0, caps, &newcaps);
+         GST_DEBUG_CAPS ("app sinkpad signal fixated to", newcaps);
+         break;
+       case 2:
+          if (GST_RPAD_FIXATEFUNC(link->srcpad)) {
+           newcaps = GST_RPAD_FIXATEFUNC(link->srcpad) (
+               GST_PAD (link->srcpad), caps);
+           GST_DEBUG_CAPS ("srcpad fixated to", newcaps);
+         }
+         break;
+       case 3:
+          if (GST_RPAD_FIXATEFUNC(link->sinkpad)) {
+           newcaps = GST_RPAD_FIXATEFUNC(link->sinkpad) (
+               GST_PAD (link->sinkpad), caps);
+           GST_DEBUG_CAPS ("sinkpad fixated to", newcaps);
+         }
+         break;
+       case 4:
+          newcaps = _gst_pad_default_fixate_func (
+             GST_PAD(link->srcpad), caps);
+         GST_DEBUG_CAPS ("core fixated to", newcaps);
+         break;
       }
-    }
-    if (GST_RPAD_FIXATEFUNC(link->sinkpad)) {
-      newcaps = GST_RPAD_FIXATEFUNC(link->sinkpad) (GST_PAD (link->sinkpad),
-          caps, NULL);
       if (newcaps) {
-        caps = newcaps;
-        GST_DEBUG_CAPS ("sink pad fixated to", caps);
-        continue;
+       gst_caps_free (caps);
+       caps = newcaps;
+       break;
       }
     }
-    caps = _gst_pad_default_fixate_func (GST_PAD(link->srcpad), caps, NULL);
-    GST_DEBUG_CAPS ("core fixated to", caps);
   }
 
-  GST_DEBUG_CAPS ("fixate decided on", caps);
-
   link->caps = caps;
 }
 
@@ -1809,32 +1840,32 @@ _gst_pad_default_fixate_foreach (GQuark field_id, GValue *value,
 }
 
 static GstCaps *
-_gst_pad_default_fixate_func (GstPad *pad, GstCaps *caps, gpointer unused)
+_gst_pad_default_fixate_func (GstPad *pad, const GstCaps *caps)
 {
   static GstStaticCaps octetcaps = GST_STATIC_CAPS (
       "application/octet-stream");
   GstStructure *structure;
+  GstCaps *newcaps;
 
   g_return_val_if_fail (pad != NULL, NULL);
   g_return_val_if_fail (caps != NULL, NULL);
   g_return_val_if_fail (!gst_caps_is_empty (caps), NULL);
 
   if (gst_caps_is_any (caps)) {
-    gst_caps_free (caps);
     return gst_caps_copy (gst_static_caps_get (&octetcaps));
   }
 
   if (caps->structs->len > 1) {
     GstCaps *retcaps = gst_caps_copy_1 (caps);
-    gst_caps_free (caps);
     return retcaps;
   }
 
-  structure = gst_caps_get_structure (caps, 0);
+  newcaps = gst_caps_copy (caps);
+  structure = gst_caps_get_structure (newcaps, 0);
   gst_structure_foreach (structure, _gst_pad_default_fixate_foreach,
       structure);
 
-  return caps;
+  return newcaps;
 }
 
 /**
@@ -2080,7 +2111,7 @@ gst_pad_proxy_pad_link (GstPad *pad, const GstCaps *caps)
  * Returns: a fixated caps, or NULL if caps cannot be fixed
  */
 GstCaps *
-gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps, gpointer unused)
+gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps)
 {
   GstElement *element;
   const GList *pads;
@@ -2132,7 +2163,7 @@ gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps, gpointer unused)
  * Returns: TRUE if the caps were set correctly, otherwise FALSE
  */
 gboolean
-gst_pad_set_explicit_caps (GstPad *pad, GstCaps *caps)
+gst_pad_set_explicit_caps (GstPad *pad, const GstCaps *caps)
 {
   GstPadLinkReturn link_ret;
 
@@ -2141,12 +2172,13 @@ gst_pad_set_explicit_caps (GstPad *pad, GstCaps *caps)
   GST_CAT_DEBUG (GST_CAT_PADS, "setting explicit caps to %s",
       gst_caps_to_string (caps));
 
-  gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), caps);
-
   if (caps == NULL) {
     GST_CAT_DEBUG (GST_CAT_PADS, "caps is NULL");
+    gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
     return TRUE;
   }
+
+  gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), gst_caps_copy(caps));
     
   if (!GST_PAD_IS_LINKED (pad)) {
     GST_CAT_DEBUG (GST_CAT_PADS, "pad is not linked");
@@ -3114,6 +3146,15 @@ gst_pad_template_new (const gchar *name_template,
   if (!name_is_valid (name_template, presence))
     return NULL;
 
+#if 0
+#ifdef USE_POISONING
+  if (caps) {
+    GstCaps *newcaps = gst_caps_copy (caps);
+    gst_caps_free(caps);
+    caps = newcaps;
+  }
+#endif
+#endif
   new = g_object_new (gst_pad_template_get_type (),
                       "name", name_template,
                       NULL);
index 8e46c4e..c0efb0f 100644 (file)
@@ -124,7 +124,7 @@ typedef const GstQueryType* (*GstPadQueryTypeFunction)      (GstPad *pad);
 typedef GstPadLinkReturn       (*GstPadLinkFunction)           (GstPad *pad, const GstCaps *caps);
 typedef void                   (*GstPadUnlinkFunction)         (GstPad *pad);
 typedef GstCaps*               (*GstPadGetCapsFunction)        (GstPad *pad);
-typedef GstCaps*               (*GstPadFixateFunction)         (GstPad *pad, const GstCaps *caps, gpointer user_data);
+typedef GstCaps*               (*GstPadFixateFunction)         (GstPad *pad, const GstCaps *caps);
 typedef GstBuffer*             (*GstPadBufferAllocFunction)    (GstPad *pad, guint64 offset, guint size);
 
 typedef gboolean               (*GstPadDispatcherFunction)     (GstPad *pad, gpointer data);
@@ -212,8 +212,9 @@ struct _GstRealPadClass {
 
   void                 (*linked)               (GstPad *pad, GstPad *peer);
   void                 (*unlinked)             (GstPad *pad, GstPad *peer);
+  GstPadFixateFunction          appfixatefunc;
 
-  gpointer _gst_reserved[GST_PADDING];
+  gpointer _gst_reserved[GST_PADDING - 1];
 };
 
 struct _GstGhostPad {
@@ -414,11 +415,11 @@ void                      gst_pad_set_getcaps_function            (GstPad *pad, GstPadGetCapsFunction getcaps
 void                   gst_pad_set_fixate_function             (GstPad *pad, GstPadFixateFunction fixate);
 GstCaps *              gst_pad_proxy_getcaps                   (GstPad *pad);
 GstPadLinkReturn        gst_pad_proxy_pad_link                  (GstPad *pad, const GstCaps *caps);
-GstCaps *               gst_pad_proxy_fixate                    (GstPad *pad, const GstCaps *caps, gpointer unused);
+GstCaps *               gst_pad_proxy_fixate                    (GstPad *pad, const GstCaps *caps);
 #ifndef GST_DISABLE_DEPRECATED
 GstPadLinkReturn       gst_pad_proxy_link                      (GstPad *pad, const GstCaps *caps);
 #endif
-gboolean               gst_pad_set_explicit_caps               (GstPad *pad, GstCaps *caps);
+gboolean               gst_pad_set_explicit_caps               (GstPad *pad, const GstCaps *caps);
 void                   gst_pad_use_explicit_caps               (GstPad *pad);
 gboolean               gst_pad_relink_filtered                 (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps);
 #ifndef GST_DISABLE_DEPRECATED
index 55eb46e..c2b1cf2 100644 (file)
@@ -145,7 +145,6 @@ gst_tee_init (GstTee *tee)
   gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain));
   gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
   gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
-  gst_pad_set_fixate_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate));
 
   tee->silent = FALSE;
   tee->last_message = NULL;
@@ -205,7 +204,6 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
   g_free (name);
   gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
   gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
-  gst_pad_set_fixate_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate));
   gst_element_add_pad (GST_ELEMENT (tee), srcpad);
   GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL;
 
index aad5b07..10d217a 100644 (file)
@@ -2,6 +2,7 @@ include ../Rules
 
 
 tests_pass = \
+       app_fixate \
        intersection \
        compatibility \
        normalisation \
@@ -16,6 +17,8 @@ tests_pass = \
 tests_fail =
 
 
+app_fixate_LDADD = $(GST_LIBS) 
+app_fixate_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 intersection_LDADD = $(GST_LIBS) 
 intersection_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 compatibility_LDADD = $(GST_LIBS) 
diff --git a/tests/old/testsuite/caps/app_fixate.c b/tests/old/testsuite/caps/app_fixate.c
new file mode 100644 (file)
index 0000000..fbaea42
--- /dev/null
@@ -0,0 +1,52 @@
+
+#include <gst/gst.h>
+
+
+static GstCaps *
+handler (GObject *object, GstCaps *caps, gpointer user_data)
+{
+  g_print("in handler %p, %p, %p\n", object, caps, user_data);
+
+  g_assert (GST_IS_PAD(object));
+
+  g_print("caps: %s\n", gst_caps_to_string(caps));
+
+  if (gst_caps_is_any (caps)) {
+    return gst_caps_new_simple ("application/x-foo",
+       "field", GST_TYPE_INT_RANGE, 1, 10, NULL);
+  }
+
+  return NULL;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  GstElement *a;
+  GstElement *b;
+  GstElement *pipeline;
+  GstPad *pad;
+
+  gst_init(&argc, &argv);
+
+  pipeline = gst_pipeline_new (NULL);
+
+  a = gst_element_factory_make ("fakesrc", NULL);
+  g_assert (a);
+  b = gst_element_factory_make ("fakesink", NULL);
+  g_assert (b);
+
+  gst_bin_add_many (GST_BIN (pipeline), a,b, NULL);
+  gst_element_link (a,b);
+
+  pad = gst_element_get_pad (a, "src");
+  g_signal_connect (G_OBJECT (pad), "fixate", G_CALLBACK (handler),
+      (void *)0xdeadbeef);
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+
+  return 0;
+}
+
index aad5b07..10d217a 100644 (file)
@@ -2,6 +2,7 @@ include ../Rules
 
 
 tests_pass = \
+       app_fixate \
        intersection \
        compatibility \
        normalisation \
@@ -16,6 +17,8 @@ tests_pass = \
 tests_fail =
 
 
+app_fixate_LDADD = $(GST_LIBS) 
+app_fixate_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 intersection_LDADD = $(GST_LIBS) 
 intersection_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 compatibility_LDADD = $(GST_LIBS) 
diff --git a/testsuite/caps/app_fixate.c b/testsuite/caps/app_fixate.c
new file mode 100644 (file)
index 0000000..fbaea42
--- /dev/null
@@ -0,0 +1,52 @@
+
+#include <gst/gst.h>
+
+
+static GstCaps *
+handler (GObject *object, GstCaps *caps, gpointer user_data)
+{
+  g_print("in handler %p, %p, %p\n", object, caps, user_data);
+
+  g_assert (GST_IS_PAD(object));
+
+  g_print("caps: %s\n", gst_caps_to_string(caps));
+
+  if (gst_caps_is_any (caps)) {
+    return gst_caps_new_simple ("application/x-foo",
+       "field", GST_TYPE_INT_RANGE, 1, 10, NULL);
+  }
+
+  return NULL;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  GstElement *a;
+  GstElement *b;
+  GstElement *pipeline;
+  GstPad *pad;
+
+  gst_init(&argc, &argv);
+
+  pipeline = gst_pipeline_new (NULL);
+
+  a = gst_element_factory_make ("fakesrc", NULL);
+  g_assert (a);
+  b = gst_element_factory_make ("fakesink", NULL);
+  g_assert (b);
+
+  gst_bin_add_many (GST_BIN (pipeline), a,b, NULL);
+  gst_element_link (a,b);
+
+  pad = gst_element_get_pad (a, "src");
+  g_signal_connect (G_OBJECT (pad), "fixate", G_CALLBACK (handler),
+      (void *)0xdeadbeef);
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+
+  return 0;
+}
+