gst/gstutils.c: RPAD fixes all around.
authorAndy Wingo <wingo@pobox.com>
Wed, 8 Jun 2005 22:16:27 +0000 (22:16 +0000)
committerAndy Wingo <wingo@pobox.com>
Wed, 8 Jun 2005 22:16:27 +0000 (22:16 +0000)
Original commit message from CVS:
2005-06-08  Andy Wingo  <wingo@pobox.com>

* gst/gstutils.c: RPAD fixes all around.
(gst_element_link_pads): Refcounting fixes.

* tools/gst-inspect.c:
* tools/gst-xmlinspect.c:
* parse/grammar.y:
* gst/base/gsttypefindhelper.c:
* gst/base/gstbasesink.c:
* gst/gstqueue.c: RPAD fixes.

* gst/gstghostpad.h:
* gst/gstghostpad.c: New ghost pad implementation as full proxy
pads. The tricky thing is they provide both source and sink
interfaces, since they proxy the internal pad for the external
pad, and vice versa. Implement with lower-level ProxyPad objects,
with the interior proxy pad as a child of the exterior ghost pad.
Should write a doc on this.

* gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/.
(gst_pad_set_name, gst_pad_set_parent): Macros removed, use
gst_object API.

* gst/gstpad.c: Big changes. No more stub base GstPad, now all
pads are real pads. No ghost pads in this file. Not documenting
the myriad s/RPAD/PAD/ and REALIZE fixes.
(gst_pad_class_init): Add properties for "direction" and
"template". Both are construct-only, so they can't change during
the life of the pad. Fixes properly deriving from GstPad.
(gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For
derived objects, just set properties when creating the objects via
g_object_new.
(gst_pad_get_parent): Implement as a function, return NULL if the
parent is not an element.
(gst_pad_get_real_parent, gst_pad_add_ghost_pad)
(gst_pad_remove_ghost_pad, gst_pad_realize): Removed.

* gst/gstobject.c (gst_object_class_init): Make name a construct
property. Don't set it in the object init.

* gst/gstelement.c (gst_element_add_pad): Don't allow adding pads
with UNKNOWN direction.
(gst_element_add_ghost_pad): Remove non-orthogonal API. Replace
with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)).
(gst_element_remove_pad): Remove ghost-pad special cases.
(gst_element_pads_activate): Remove rpad cruft.

* gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to
catch the pad's-parent-not-an-element case.

* gst/gst.h: Include gstghostpad.h.

* gst/gst.c (init_post): No more real, ghost pads.

* gst/Makefile.am: Add gstghostpad.[ch].

* check/Makefile.am:
* check/gst/gstbin.c:
* check/gst/gstghostpad.c (test_ghost_pads): Check that linking
into a bin creates ghost pads, and that the refcounts are right.
Partly moved from gstbin.c.

32 files changed:
ChangeLog
check/Makefile.am
check/gst/gstbin.c
check/gst/gstghostpad.c [new file with mode: 0644]
docs/gst/tmpl/gstelement.sgml
docs/gst/tmpl/gstghostpad.sgml
docs/gst/tmpl/gstpad.sgml
docs/gst/tmpl/gstpadtemplate.sgml
gst/Makefile.am
gst/base/gstbasesink.c
gst/base/gsttypefindhelper.c
gst/gst.c
gst/gst.h
gst/gstbin.c
gst/gstelement.c
gst/gstelement.h
gst/gstghostpad.c [new file with mode: 0644]
gst/gstghostpad.h [new file with mode: 0644]
gst/gstobject.c
gst/gstpad.c
gst/gstpad.h
gst/gstqueue.c
gst/gstutils.c
gst/parse/grammar.y
libs/gst/base/gstbasesink.c
libs/gst/base/gsttypefindhelper.c
plugins/elements/gstqueue.c
tests/check/Makefile.am
tests/check/gst/gstbin.c
tests/check/gst/gstghostpad.c [new file with mode: 0644]
tools/gst-inspect.c
tools/gst-xmlinspect.c

index b8cf3f9..2e6ae41 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+2005-06-08  Andy Wingo  <wingo@pobox.com>
+
+       * gst/gstutils.c: RPAD fixes all around.
+       (gst_element_link_pads): Refcounting fixes.
+
+       * tools/gst-inspect.c:
+       * tools/gst-xmlinspect.c:
+       * parse/grammar.y:
+       * gst/base/gsttypefindhelper.c:
+       * gst/base/gstbasesink.c:
+       * gst/gstqueue.c: RPAD fixes.
+
+       * gst/gstghostpad.h:
+       * gst/gstghostpad.c: New ghost pad implementation as full proxy
+       pads. The tricky thing is they provide both source and sink
+       interfaces, since they proxy the internal pad for the external
+       pad, and vice versa. Implement with lower-level ProxyPad objects,
+       with the interior proxy pad as a child of the exterior ghost pad.
+       Should write a doc on this.
+       
+       * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/.
+       (gst_pad_set_name, gst_pad_set_parent): Macros removed, use
+       gst_object API.
+       
+       * gst/gstpad.c: Big changes. No more stub base GstPad, now all
+       pads are real pads. No ghost pads in this file. Not documenting
+       the myriad s/RPAD/PAD/ and REALIZE fixes.
+       (gst_pad_class_init): Add properties for "direction" and
+       "template". Both are construct-only, so they can't change during
+       the life of the pad. Fixes properly deriving from GstPad.
+       (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For
+       derived objects, just set properties when creating the objects via
+       g_object_new.
+       (gst_pad_get_parent): Implement as a function, return NULL if the
+       parent is not an element.
+       (gst_pad_get_real_parent, gst_pad_add_ghost_pad)
+       (gst_pad_remove_ghost_pad, gst_pad_realize): Removed.
+       
+       * gst/gstobject.c (gst_object_class_init): Make name a construct
+       property. Don't set it in the object init.
+
+       * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads
+       with UNKNOWN direction.
+       (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace
+       with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)).
+       (gst_element_remove_pad): Remove ghost-pad special cases.
+       (gst_element_pads_activate): Remove rpad cruft.
+
+       * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to
+       catch the pad's-parent-not-an-element case.
+
+       * gst/gst.h: Include gstghostpad.h.
+
+       * gst/gst.c (init_post): No more real, ghost pads.
+
+       * gst/Makefile.am: Add gstghostpad.[ch].
+
+       * check/Makefile.am:
+       * check/gst/gstbin.c:
+       * check/gst/gstghostpad.c (test_ghost_pads): Check that linking
+       into a bin creates ghost pads, and that the refcounts are right.
+       Partly moved from gstbin.c.
+
 2005-06-08  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * check/gst-libs/.cvsignore:
index 592308b..6df71a4 100644 (file)
@@ -27,6 +27,7 @@ TESTS = $(top_builddir)/tools/gst-register    \
         gst/gstbuffer                          \
         gst/gstbus                             \
        gst/gstcaps                             \
+       gst/gstghostpad                         \
        gst/gstiterator                         \
        gst/gstmessage                          \
        gst/gstobject                           \
index 9057279..abd93bf 100644 (file)
@@ -81,37 +81,6 @@ START_TEST (test_interface)
 
   gst_object_unref (GST_OBJECT (bin));
 }
-
-END_TEST
-START_TEST (test_ghost_pads)
-{
-  GstElement *b1, *b2, *src, *i1, *sink;
-
-  b1 = gst_element_factory_make ("pipeline", NULL);
-  b2 = gst_element_factory_make ("bin", NULL);
-  src = gst_element_factory_make ("fakesrc", NULL);
-  i1 = gst_element_factory_make ("identity", NULL);
-  sink = gst_element_factory_make ("fakesink", NULL);
-
-  fail_unless (gst_bin_add (GST_BIN (b2), i1));
-  fail_unless (gst_bin_add (GST_BIN (b1), src));
-  fail_unless (gst_bin_add (GST_BIN (b1), b2));
-  fail_unless (gst_bin_add (GST_BIN (b1), sink));
-  fail_unless (gst_element_link_pads (src, NULL, i1, NULL));
-  fail_unless (gst_element_link_pads (i1, NULL, sink, NULL));
-  GST_LOCK (b2);
-  fail_unless (b2->numsinkpads == 1);
-  fail_unless (GST_IS_GHOST_PAD (b2->sinkpads->data));
-  fail_unless (b2->numsrcpads == 1);
-  fail_unless (GST_IS_GHOST_PAD (b2->srcpads->data));
-  GST_UNLOCK (b2);
-
-  fail_unless (gst_element_set_state (b1,
-          GST_STATE_PLAYING) == GST_STATE_SUCCESS);
-  fail_unless (gst_element_set_state (b1, GST_STATE_NULL) == GST_STATE_SUCCESS);
-
-  gst_object_unref (GST_OBJECT (b1));
-}
 END_TEST Suite * gst_bin_suite (void)
 {
   Suite *s = suite_create ("GstBin");
@@ -119,7 +88,6 @@ END_TEST Suite * gst_bin_suite (void)
 
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_interface);
-  tcase_add_test (tc_chain, test_ghost_pads);
 
   return s;
 }
diff --git a/check/gst/gstghostpad.c b/check/gst/gstghostpad.c
new file mode 100644 (file)
index 0000000..44f910f
--- /dev/null
@@ -0,0 +1,120 @@
+/* GStreamer
+ * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gstghostpad.c: Unit test for GstGhostPad
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "../gstcheck.h"
+
+static void
+assert_gstrefcount (gpointer p, gint i)
+{
+  if (GST_OBJECT_REFCOUNT_VALUE (p) != i)
+    g_critical ("Expected refcount %d for %s, got %d", i, GST_OBJECT_NAME (p),
+        GST_OBJECT_REFCOUNT_VALUE (p));
+}
+
+START_TEST (test_ghost_pads)
+{
+  GstElement *b1, *b2, *src, *i1, *sink;
+  GstPad *gsink, *gsrc, *gisrc, *gisink, *isink, *isrc, *fsrc, *fsink;
+
+  b1 = gst_element_factory_make ("pipeline", NULL);
+  b2 = gst_element_factory_make ("bin", NULL);
+  src = gst_element_factory_make ("fakesrc", NULL);
+  g_object_set (src, "num-buffers", (int) 10, NULL);
+  i1 = gst_element_factory_make ("identity", NULL);
+  sink = gst_element_factory_make ("fakesink", NULL);
+
+  fail_unless (gst_bin_add (GST_BIN (b2), i1));
+  fail_unless (gst_bin_add (GST_BIN (b1), src));
+  fail_unless (gst_bin_add (GST_BIN (b1), b2));
+  fail_unless (gst_bin_add (GST_BIN (b1), sink));
+  fail_unless (gst_element_link_pads (src, NULL, i1, NULL));
+  fail_unless (gst_element_link_pads (i1, NULL, sink, NULL));
+  GST_LOCK (b2);
+  fail_unless (b2->numsinkpads == 1);
+  fail_unless (GST_IS_GHOST_PAD (b2->sinkpads->data));
+  fail_unless (b2->numsrcpads == 1);
+  fail_unless (GST_IS_GHOST_PAD (b2->srcpads->data));
+  GST_UNLOCK (b2);
+
+  fsrc = gst_element_get_pad (src, "src");
+  fail_unless (fsrc != NULL);
+  gsink = GST_PAD (gst_object_ref (GST_OBJECT (b2->sinkpads->data)));
+  fail_unless (gsink != NULL);
+  gsrc = GST_PAD (gst_object_ref (GST_OBJECT (b2->srcpads->data)));
+  fail_unless (gsrc != NULL);
+  fsink = gst_element_get_pad (sink, "sink");
+  fail_unless (fsink != NULL);
+
+  isink = gst_element_get_pad (i1, "sink");
+  fail_unless (isink != NULL);
+  isrc = gst_element_get_pad (i1, "src");
+  fail_unless (isrc != NULL);
+  gisrc = gst_pad_get_peer (isink);
+  fail_unless (gisrc != NULL);
+  gisink = gst_pad_get_peer (isrc);
+  fail_unless (gisink != NULL);
+
+  /* all objects above have one refcount owned by us as well */
+
+  assert_gstrefcount (fsrc, 3); /* parent and gisrc */
+  assert_gstrefcount (gsink, 2);        /* parent */
+  assert_gstrefcount (gsrc, 2); /* parent */
+  assert_gstrefcount (fsink, 3);        /* parent and gisink */
+
+  assert_gstrefcount (gisrc, 2);        /* parent */
+  assert_gstrefcount (isink, 3);        /* parent and gsink */
+  assert_gstrefcount (gisink, 2);       /* parent */
+  assert_gstrefcount (isrc, 3); /* parent and gsrc */
+
+  fail_unless (gst_element_set_state (b1,
+          GST_STATE_PLAYING) == GST_STATE_SUCCESS);
+
+  fail_unless (gst_element_set_state (b1, GST_STATE_NULL) == GST_STATE_SUCCESS);
+
+  gst_object_unref (GST_OBJECT (b1));
+}
+END_TEST Suite * gst_ghost_pad_suite (void)
+{
+  Suite *s = suite_create ("GstGhostPad");
+  TCase *tc_chain = tcase_create ("ghost pad tests");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_ghost_pads);
+
+  return s;
+}
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = gst_ghost_pad_suite ();
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_NORMAL);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}
index 4211aae..0d99dbc 100644 (file)
@@ -445,17 +445,6 @@ Sets the parent of an element.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_element_add_ghost_pad ##### -->
-<para>
-
-</para>
-
-@element: 
-@pad: 
-@name: 
-@Returns: 
-
-
 <!-- ##### FUNCTION gst_element_get_pad ##### -->
 <para>
 
index 10d99b3..0fdd2b2 100644 (file)
@@ -20,36 +20,20 @@ Pseudo link pads
 </para>
 
 
-<!-- ##### ARG GstGhostPad:real-pad ##### -->
+<!-- ##### ARG GstGhostPad:internal ##### -->
 <para>
 
 </para>
 
-<!-- ##### MACRO GST_GPAD_REALPAD ##### -->
-<para>
-Get the real pad of this ghost pad.
-</para>
-
-@pad: the real pad to query.
-
-
 <!-- ##### FUNCTION gst_ghost_pad_new ##### -->
 <para>
 
 </para>
 
 @name: 
-@pad
+@target
 @Returns: 
-
-
-<!-- ##### FUNCTION gst_ghost_pad_save_thyself ##### -->
-<para>
-
-</para>
-
+<!-- # Unused Parameters # -->
 @pad: 
-@parent: 
-@Returns: 
 
 
index d5a62d9..6509714 100644 (file)
@@ -62,58 +62,89 @@ Last reviewed on December 13th, 2002 (0.5.0.1)
 
 </para>
 
+@stream_rec_lock: 
+@task: 
+@preroll_lock: 
+@preroll_cond: 
+@block_cond: 
+@block_callback: 
+@block_data: 
+@caps: 
+@getcapsfunc: 
+@setcapsfunc: 
+@acceptcapsfunc: 
+@fixatecapsfunc: 
+@activatefunc: 
+@linkfunc: 
+@unlinkfunc: 
+@peer: 
+@sched_private: 
+@loopfunc: 
+@chainfunc: 
+@checkgetrangefunc: 
+@getrangefunc: 
+@eventfunc: 
+@mode: 
+@querytypefunc: 
+@queryfunc: 
+@intlinkfunc: 
+@bufferallocfunc: 
+@probedisp: 
 
-<!-- ##### STRUCT GstPadLink ##### -->
+<!-- ##### SIGNAL GstPad::linked ##### -->
 <para>
 
 </para>
 
+@gstpad: the object which received the signal.
+@arg1: 
 
-<!-- ##### MACRO GST_PAD_LINK_FAILED ##### -->
+<!-- ##### SIGNAL GstPad::request-link ##### -->
 <para>
-Macro to test if the given #GstPadLinkReturn value indicates a
-failed negotiation step (REFUSED/DELAYED).
-</para>
 
-@ret: the #GstPadLinkReturn value
+</para>
 
+@gstpad: the object which received the signal.
 
-<!-- ##### MACRO GST_PAD_LINK_SUCCESSFUL ##### -->
+<!-- ##### SIGNAL GstPad::unlinked ##### -->
 <para>
-Macro to test if the given #GstPadLinkReturn value indicates a
-successfull negotiation step (OK/DONE).
+
 </para>
 
-@ret: the #GstPadLinkReturn value
+@gstpad: the object which received the signal.
+@arg1: 
+
+<!-- ##### ARG GstPad:caps ##### -->
+<para>
 
+</para>
 
-<!-- ##### MACRO GST_PAD_QUERY_TYPE_FUNCTION ##### -->
+<!-- ##### ARG GstPad:direction ##### -->
 <para>
-A convenience macro to construct query type functions
+
 </para>
 
-@functionname: the name of the function
-@...: query types, 0 to mark the last element
+<!-- ##### ARG GstPad:template ##### -->
+<para>
 
+</para>
 
-<!-- ##### MACRO GST_PAD_FORMATS_FUNCTION ##### -->
+<!-- ##### MACRO GST_PAD_LINK_FAILED ##### -->
 <para>
-Convenience function to define an array of formats that can be used
-as #GstPadGetFormatsFunction.
+Macro to test if the given #GstPadLinkReturn value indicates a
+failed negotiation step (REFUSED/DELAYED).
 </para>
 
-@functionname: The name of the function
-@...: comma separated list of formats, 0 to mark the end
+@ret: the #GstPadLinkReturn value
 
 
-<!-- ##### MACRO GST_PAD_EVENT_MASK_FUNCTION ##### -->
+<!-- ##### MACRO GST_PAD_LINK_SUCCESSFUL ##### -->
 <para>
-Convenience function to define an array of event masks that can be used
-as #GstPadGetEventMaskFunction.
+Macro to test if the given #GstPadLinkReturn value indicates a
+successfull negotiation step (OK/DONE).
 </para>
 
-@functionname: The name of the function
-@...: comma separated list of event maks, { 0, } to mark the end
+@ret: the #GstPadLinkReturn value
 
 
 <!-- ##### USER_FUNCTION GstPadChainFunction ##### -->
@@ -215,6 +246,7 @@ be overridden.
 @offset: 
 @size: 
 @caps: 
+@buf: 
 @Returns: 
 
 
@@ -308,15 +340,6 @@ Gets the pad template that was used to create this pad.
 used.
 
 
-<!-- ##### MACRO GST_PAD_REALIZE ##### -->
-<para>
-Returns the real pad of this pad.
-</para>
-
-@pad: a #GstPad to realize.
-@Returns: the actual #GstPad.
-
-
 <!-- ##### MACRO GST_PAD_DIRECTION ##### -->
 <para>
 Gets the pad's direction.
@@ -397,37 +420,6 @@ Checks if the pad is a sink pad.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_pad_custom_new ##### -->
-<para>
-
-</para>
-
-@type: 
-@name: 
-@direction: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_pad_custom_new_from_template ##### -->
-<para>
-
-</para>
-
-@type: 
-@templ: 
-@name: 
-@Returns: 
-
-
-<!-- ##### MACRO gst_pad_set_name ##### -->
-<para>
-
-</para>
-
-@pad: 
-@name: 
-
-
 <!-- ##### MACRO gst_pad_get_name ##### -->
 <para>
 
@@ -485,25 +477,7 @@ Checks if the pad is a sink pad.
 @Returns: 
 
 
-<!-- ##### MACRO gst_pad_set_parent ##### -->
-<para>
-
-</para>
-
-@pad: 
-@parent: 
-
-
-<!-- ##### MACRO gst_pad_get_parent ##### -->
-<para>
-
-</para>
-
-@pad: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_pad_get_real_parent ##### -->
+<!-- ##### FUNCTION gst_pad_get_parent ##### -->
 <para>
 
 </para>
@@ -541,6 +515,7 @@ Checks if the pad is a sink pad.
 @offset: 
 @size: 
 @caps: 
+@buf: 
 @Returns: 
 
 
index 1c14bc1..1ff9a28 100644 (file)
@@ -98,14 +98,6 @@ template.
 @presence: 
 @static_caps: 
 
-<!-- ##### MACRO GST_IS_GHOST_PAD_FAST ##### -->
-<para>
-
-</para>
-
-@obj: 
-
-
 <!-- ##### MACRO GST_IS_PAD_FAST ##### -->
 <para>
 
index e4ba8d1..fea75a1 100644 (file)
@@ -88,6 +88,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
        gstevent.c              \
        gstfilter.c             \
        gstformat.c             \
+       gstghostpad.c           \
        $(GST_INDEX_SRC)        \
        gstinfo.c               \
        gstinterface.c          \
@@ -163,6 +164,7 @@ gst_headers =                       \
        gstevent.h              \
        gstfilter.h             \
        gstformat.h             \
+       gstghostpad.h           \
        gstindex.h              \
        gstinfo.h               \
        gstinterface.h          \
index c06c9a3..e714005 100644 (file)
@@ -241,7 +241,7 @@ gst_basesink_init (GstBaseSink * basesink, gpointer g_class)
   gst_element_add_pad (GST_ELEMENT (basesink), basesink->sinkpad);
 
   basesink->pad_mode = GST_ACTIVATE_NONE;
-  GST_RPAD_TASK (basesink->sinkpad) = NULL;
+  GST_PAD_TASK (basesink->sinkpad) = NULL;
   basesink->preroll_queue = g_queue_new ();
 
   GST_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
@@ -476,7 +476,7 @@ gst_basesink_finish_preroll (GstBaseSink * basesink, GstPad * pad,
   gst_basesink_preroll_queue_push (basesink, pad, buffer);
 
   GST_LOCK (pad);
-  flushing = GST_RPAD_IS_FLUSHING (pad);
+  flushing = GST_PAD_IS_FLUSHING (pad);
   GST_UNLOCK (pad);
   if (flushing)
     goto flushing;
index ecb6f9d..d0edfba 100644 (file)
@@ -64,7 +64,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
   }
 
   buffer = NULL;
-  ret = GST_RPAD_GETRANGEFUNC (src) (src, offset, size, &buffer);
+  ret = GST_PAD_GETRANGEFUNC (src) (src, offset, size, &buffer);
 
   if (find->buffer) {
     gst_buffer_unref (find->buffer);
index 63adfb0..a5e6ab8 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -581,8 +581,6 @@ init_post (void)
   _gst_query_initialize ();
   gst_object_get_type ();
   gst_pad_get_type ();
-  gst_real_pad_get_type ();
-  gst_ghost_pad_get_type ();
   gst_element_factory_get_type ();
   gst_element_get_type ();
   gst_scheduler_factory_get_type ();
index c7724ee..6545c54 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -38,6 +38,7 @@
 #include <gst/gstelement.h>
 #include <gst/gsterror.h>
 #include <gst/gstevent.h>
+#include <gst/gstghostpad.h>
 #include <gst/gstindex.h>
 #include <gst/gstinfo.h>
 #include <gst/gstinterface.h>
index 92b3326..4bafa09 100644 (file)
@@ -1037,9 +1037,9 @@ restart:
 
       peer = gst_pad_get_peer (pad);
       if (peer) {
-        GstObject *peer_elem;
+        GstElement *peer_elem;
 
-        peer_elem = gst_object_get_parent (GST_OBJECT_CAST (peer));
+        peer_elem = gst_pad_get_parent (peer);
 
         if (peer_elem) {
           GstObject *parent;
@@ -1060,7 +1060,7 @@ restart:
             gst_object_unref (GST_OBJECT_CAST (peer_elem));
           }
           if (parent) {
-            gst_object_unref (GST_OBJECT_CAST (parent));
+            gst_object_unref (parent);
           }
         }
         gst_object_unref (GST_OBJECT_CAST (peer));
index 4c531a3..decf647 100644 (file)
@@ -491,10 +491,7 @@ gst_element_add_pad (GstElement * element, GstPad * pad)
       element->numsinkpads++;
       break;
     default:
-      /* can happen for ghost pads */
-      g_warning ("adding pad %s:%s wothout direction",
-          GST_DEBUG_PAD_NAME (pad));
-      break;
+      goto no_direction;
   }
   element->pads = g_list_prepend (element->pads, pad);
   element->numpads++;
@@ -524,39 +521,16 @@ had_parent:
     g_free (pad_name);
     return FALSE;
   }
-}
-
-/**
- * gst_element_add_ghost_pad:
- * @element: a #GstElement to add the ghost pad to.
- * @pad: the #GstPad from which the new ghost pad will be created.
- * @name: the name of the new ghost pad, or NULL to assign a unique name
- * automatically.
- *
- * Creates a ghost pad from @pad, and adds it to @element via
- * gst_element_add_pad().
- *
- * Returns: the added ghost #GstPad, or NULL on error.
- *
- * MT safe.
- */
-GstPad *
-gst_element_add_ghost_pad (GstElement * element, GstPad * pad,
-    const gchar * name)
-{
-  GstPad *ghostpad;
-
-  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  ghostpad = gst_ghost_pad_new (name, pad);
-
-  if (!gst_element_add_pad (element, ghostpad)) {
-    gst_object_unref (GST_OBJECT (ghostpad));
-    ghostpad = NULL;
+no_direction:
+  {
+    GST_LOCK (pad);
+    g_critical
+        ("Trying to add pad %s to element %s, but it has no direction",
+        GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
+    GST_UNLOCK (pad);
+    GST_UNLOCK (element);
+    return FALSE;
   }
-
-  return ghostpad;
 }
 
 /**
@@ -576,6 +550,7 @@ gst_element_add_ghost_pad (GstElement * element, GstPad * pad,
 gboolean
 gst_element_remove_pad (GstElement * element, GstPad * pad)
 {
+  GstPad *peer;
   gchar *pad_name;
 
   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
@@ -594,24 +569,19 @@ gst_element_remove_pad (GstElement * element, GstPad * pad)
 
   g_free (pad_name);
 
-  /* FIXME, is this redundant with pad disposal? */
-  if (GST_IS_REAL_PAD (pad)) {
-    GstPad *peer = gst_pad_get_peer (pad);
-
-    /* unlink */
-    if (peer != NULL) {
-      /* window for MT unsafeness, someone else could unlink here
-       * and then we call unlink with wrong pads. The unlink
-       * function would catch this and safely return failed. */
-      if (GST_PAD_IS_SRC (pad))
-        gst_pad_unlink (pad, GST_PAD_CAST (peer));
-      else
-        gst_pad_unlink (GST_PAD_CAST (peer), pad);
+  peer = gst_pad_get_peer (pad);
 
-      gst_object_unref (GST_OBJECT (peer));
-    }
-  } else if (GST_IS_GHOST_PAD (pad)) {
-    g_object_set (pad, "real-pad", NULL, NULL);
+  /* unlink */
+  if (peer != NULL) {
+    /* window for MT unsafeness, someone else could unlink here
+     * and then we call unlink with wrong pads. The unlink
+     * function would catch this and safely return failed. */
+    if (GST_PAD_IS_SRC (pad))
+      gst_pad_unlink (pad, GST_PAD_CAST (peer));
+    else
+      gst_pad_unlink (GST_PAD_CAST (peer), pad);
+
+    gst_object_unref (GST_OBJECT (peer));
   }
 
   GST_LOCK (element);
@@ -626,7 +596,7 @@ gst_element_remove_pad (GstElement * element, GstPad * pad)
       element->numsinkpads--;
       break;
     default:
-      /* can happen for ghost pads */
+      g_critical ("Removing pad without direction???");
       break;
   }
   element->pads = g_list_remove (element->pads, pad);
@@ -1826,73 +1796,69 @@ restart:
   pads = element->pads;
   cookie = element->pads_cookie;
   for (; pads && result; pads = g_list_next (pads)) {
-    GstPad *pad = GST_PAD (pads->data);
+    GstPad *pad, *peer;
+    gboolean pad_loop, pad_get;
+    gboolean done = FALSE;
 
+    pad = GST_PAD (pads->data);
     gst_object_ref (GST_OBJECT (pad));
     GST_UNLOCK (element);
 
-    /* we only care about real pads */
-    if (GST_IS_REAL_PAD (pad)) {
-      GstRealPad *peer;
-      gboolean pad_loop, pad_get;
-      gboolean done = FALSE;
+    if (active) {
+      pad_get = GST_PAD_IS_SINK (pad) && gst_pad_check_pull_range (pad);
 
-      if (active) {
-        pad_get = GST_RPAD_IS_SINK (pad) && gst_pad_check_pull_range (pad);
+      /* see if the pad has a loop function and grab
+       * the peer */
+      GST_LOCK (pad);
+      pad_loop = GST_PAD_LOOPFUNC (pad) != NULL;
+      peer = GST_PAD_PEER (pad);
+      if (peer)
+        gst_object_ref (GST_OBJECT_CAST (peer));
+      GST_UNLOCK (pad);
 
-        /* see if the pad has a loop function and grab
-         * the peer */
-        GST_LOCK (pad);
-        pad_loop = GST_RPAD_LOOPFUNC (pad) != NULL;
-        peer = GST_RPAD_PEER (pad);
-        if (peer)
-          gst_object_ref (GST_OBJECT_CAST (peer));
-        GST_UNLOCK (pad);
+      GST_DEBUG ("pad %s:%s: get: %d, loop: %d",
+          GST_DEBUG_PAD_NAME (pad), pad_get, pad_loop);
 
-        GST_DEBUG ("pad %s:%s: get: %d, loop: %d",
-            GST_DEBUG_PAD_NAME (pad), pad_get, pad_loop);
+      if (peer) {
+        gboolean peer_loop, peer_get;
 
-        if (peer) {
-          gboolean peer_loop, peer_get;
-
-          /* see if the peer has a getrange function */
-          peer_get = GST_RPAD_IS_SINK (peer)
-              && gst_pad_check_pull_range (GST_PAD_CAST (peer));
-          /* see if the peer has a loop function */
-          peer_loop = GST_RPAD_LOOPFUNC (peer) != NULL;
-
-          GST_DEBUG ("peer %s:%s: get: %d, loop: %d",
-              GST_DEBUG_PAD_NAME (peer), peer_get, peer_loop);
-
-          /* If the pad is a sink with loop and the peer has a get function,
-           * we can activate the sinkpad,  FIXME, logic is reversed as
-           * check_pull_range() checks the peer of the given pad. */
-          if ((pad_get && pad_loop) || (peer_get && peer_loop)) {
-            GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
-                "activating pad %s in pull mode", GST_OBJECT_NAME (pad));
-
-            result &= gst_pad_set_active (pad, GST_ACTIVATE_PULL);
-            done = TRUE;
-          }
-          gst_object_unref (GST_OBJECT_CAST (peer));
-        }
+        /* see if the peer has a getrange function */
+        peer_get = GST_PAD_IS_SINK (peer)
+            && gst_pad_check_pull_range (GST_PAD_CAST (peer));
+        /* see if the peer has a loop function */
+        peer_loop = GST_PAD_LOOPFUNC (peer) != NULL;
+
+        GST_DEBUG ("peer %s:%s: get: %d, loop: %d",
+            GST_DEBUG_PAD_NAME (peer), peer_get, peer_loop);
 
-        if (!done) {
-          /* all other conditions are just push based pads */
+        /* If the pad is a sink with loop and the peer has a get function,
+         * we can activate the sinkpad,  FIXME, logic is reversed as
+         * check_pull_range() checks the peer of the given pad. */
+        if ((pad_get && pad_loop) || (peer_get && peer_loop)) {
           GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
-              "activating pad %s in push mode", GST_OBJECT_NAME (pad));
+              "activating pad %s in pull mode", GST_OBJECT_NAME (pad));
 
-          result &= gst_pad_set_active (pad, GST_ACTIVATE_PUSH);
+          result &= gst_pad_set_active (pad, GST_ACTIVATE_PULL);
+          done = TRUE;
         }
-      } else {
+        gst_object_unref (GST_OBJECT_CAST (peer));
+      }
+
+      if (!done) {
+        /* all other conditions are just push based pads */
         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
-            "deactivating pad %s", GST_OBJECT_NAME (pad));
+            "activating pad %s in push mode", GST_OBJECT_NAME (pad));
 
-        result &= gst_pad_set_active (pad, GST_ACTIVATE_NONE);
+        result &= gst_pad_set_active (pad, GST_ACTIVATE_PUSH);
       }
+    } else {
+      GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
+          "deactivating pad %s", GST_OBJECT_NAME (pad));
+
+      result &= gst_pad_set_active (pad, GST_ACTIVATE_NONE);
     }
-    gst_object_unref (GST_OBJECT_CAST (pad));
 
+    gst_object_unref (GST_OBJECT_CAST (pad));
     GST_LOCK (element);
     if (cookie != element->pads_cookie)
       goto restart;
index 289d21c..3b4f456 100644 (file)
@@ -291,7 +291,6 @@ GstScheduler*               gst_element_get_scheduler       (GstElement *element);
 /* pad management */
 gboolean               gst_element_add_pad             (GstElement *element, GstPad *pad);
 gboolean               gst_element_remove_pad          (GstElement *element, GstPad *pad);
-GstPad *               gst_element_add_ghost_pad       (GstElement *element, GstPad *pad, const gchar *name);
 void                   gst_element_no_more_pads        (GstElement *element);
 
 GstPad*                        gst_element_get_pad             (GstElement *element, const gchar *name);
diff --git a/gst/gstghostpad.c b/gst/gstghostpad.c
new file mode 100644 (file)
index 0000000..93404c8
--- /dev/null
@@ -0,0 +1,593 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *                    2005 Andy Wingo <wingo@pobox.com>
+ *
+ * gstghostpad.c: Proxy pads
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#include "gst_private.h"
+
+#include "gstghostpad.h"
+#include "gstelement.h"
+#include "gstbin.h"
+
+
+#define GST_TYPE_PROXY_PAD             (gst_proxy_pad_get_type ())
+#define GST_IS_PROXY_PAD(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PROXY_PAD))
+#define GST_IS_PROXY_PAD_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PROXY_PAD))
+#define GST_PROXY_PAD(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PROXY_PAD, GstProxyPad))
+#define GST_PROXY_PAD_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PROXY_PAD, GstProxyPadClass))
+#define GST_PROXY_PAD_TARGET(pad)      (GST_PROXY_PAD (pad)->target)
+
+
+typedef struct _GstProxyPad GstProxyPad;
+typedef struct _GstProxyPadClass GstProxyPadClass;
+
+
+enum
+{
+  PROXY_PROP_0,
+  PROXY_PROP_TARGET
+};
+
+struct _GstProxyPad
+{
+  GstPad pad;
+
+  GstPad *target;
+
+  GMutex *property_lock;
+
+  /*< private > */
+  gpointer _gst_reserved[1];
+};
+
+struct _GstProxyPadClass
+{
+  GstPadClass parent_class;
+
+  /*< private > */
+  gpointer _gst_reserved[1];
+};
+
+
+G_DEFINE_TYPE (GstProxyPad, gst_proxy_pad, GST_TYPE_PAD);
+
+
+static void gst_proxy_pad_dispose (GObject * object);
+static void gst_proxy_pad_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_proxy_pad_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void gst_proxy_pad_finalize (GObject * object);
+
+#ifndef GST_DISABLE_LOADSAVE
+static xmlNodePtr gst_proxy_pad_save_thyself (GstObject * object,
+    xmlNodePtr parent);
+#endif
+
+
+static void
+gst_proxy_pad_class_init (GstProxyPadClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_proxy_pad_dispose);
+  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_proxy_pad_finalize);
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_proxy_pad_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_proxy_pad_get_property);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROXY_PROP_TARGET,
+      g_param_spec_object ("target", "Target", "The proxy pad's target",
+          GST_TYPE_PAD, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+#ifndef GST_DISABLE_LOADSAVE
+  {
+    GstObjectClass *gstobject_class = (GstObjectClass *) klass;
+
+    gstobject_class->save_thyself =
+        GST_DEBUG_FUNCPTR (gst_proxy_pad_save_thyself);
+  }
+#endif
+}
+
+const GstQueryType *
+gst_proxy_pad_do_query_type (GstPad * pad)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, NULL);
+
+  return gst_pad_get_query_types (target);
+}
+
+static gboolean
+gst_proxy_pad_do_event (GstPad * pad, GstEvent * event)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, FALSE);
+
+  return gst_pad_send_event (target, event);
+}
+
+static gboolean
+gst_proxy_pad_do_query (GstPad * pad, GstQuery * query)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, FALSE);
+
+  return gst_pad_query (target, query);
+}
+
+static GList *
+gst_proxy_pad_do_internal_link (GstPad * pad)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, NULL);
+
+  return gst_pad_get_internal_links (target);
+}
+
+static GstFlowReturn
+gst_proxy_pad_do_bufferalloc (GstPad * pad, guint64 offset, guint size,
+    GstCaps * caps, GstBuffer ** buf)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, GST_FLOW_UNEXPECTED);
+
+  return target->bufferallocfunc (target, offset, size, caps, buf);
+}
+
+static gboolean
+gst_proxy_pad_do_activate (GstPad * pad, GstActivateMode mode)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, FALSE);
+
+  return gst_pad_set_active (target, mode);
+}
+
+static void
+gst_proxy_pad_do_loop (GstPad * pad)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_if_fail (target != NULL);
+
+  target->loopfunc (target);
+}
+
+static GstFlowReturn
+gst_proxy_pad_do_chain (GstPad * pad, GstBuffer * buffer)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, GST_FLOW_UNEXPECTED);
+
+  return target->chainfunc (target, buffer);
+}
+
+static GstFlowReturn
+gst_proxy_pad_do_getrange (GstPad * pad, guint64 offset, guint size,
+    GstBuffer ** buffer)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, GST_FLOW_UNEXPECTED);
+
+  return target->getrangefunc (target, offset, size, buffer);
+}
+
+static gboolean
+gst_proxy_pad_do_checkgetrange (GstPad * pad)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, FALSE);
+
+  return target->checkgetrangefunc (target);
+}
+
+static GstCaps *
+gst_proxy_pad_do_getcaps (GstPad * pad)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, NULL);
+
+  return target->getcapsfunc (target);
+}
+
+static gboolean
+gst_proxy_pad_do_acceptcaps (GstPad * pad, GstCaps * caps)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, FALSE);
+
+  return target->acceptcapsfunc (target, caps);
+}
+
+static GstCaps *
+gst_proxy_pad_do_fixatecaps (GstPad * pad, GstCaps * caps)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, NULL);
+
+  return target->fixatecapsfunc (target, caps);
+}
+
+static gboolean
+gst_proxy_pad_do_setcaps (GstPad * pad, GstCaps * caps)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_val_if_fail (target != NULL, FALSE);
+
+  return target->setcapsfunc (target, caps);
+}
+
+#define SETFUNC(member, kind) \
+  if (target->member) \
+    gst_pad_set_##kind##_function (pad, gst_proxy_pad_do_##kind)
+
+static void
+gst_proxy_pad_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstPad *pad = GST_PAD (object);
+
+  switch (prop_id) {
+    case PROXY_PROP_TARGET:{
+      GstPad *target;
+
+      target = GST_PAD_CAST (gst_object_ref
+          (GST_OBJECT_CAST (g_value_get_object (value))));
+      GST_PROXY_PAD_TARGET (object) = target;
+
+      /* really, all these should have default implementations so I can set them
+       * in the _init() instead of here */
+      SETFUNC (querytypefunc, query_type);
+      SETFUNC (eventfunc, event);
+      SETFUNC (queryfunc, query);
+      SETFUNC (intlinkfunc, internal_link);
+      SETFUNC (activatefunc, activate);
+      SETFUNC (loopfunc, loop);
+      SETFUNC (getcapsfunc, getcaps);
+      SETFUNC (acceptcapsfunc, acceptcaps);
+      SETFUNC (fixatecapsfunc, fixatecaps);
+      SETFUNC (setcapsfunc, setcaps);
+
+      if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
+        SETFUNC (bufferallocfunc, bufferalloc);
+        SETFUNC (chainfunc, chain);
+      } else {
+        SETFUNC (getrangefunc, getrange);
+        SETFUNC (checkgetrangefunc, checkgetrange);
+      }
+
+      break;
+    }
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_proxy_pad_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  switch (prop_id) {
+    case PROXY_PROP_TARGET:
+      g_value_set_object (value, GST_PROXY_PAD_TARGET (object));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_proxy_pad_init (GstProxyPad * pad)
+{
+  pad->property_lock = g_mutex_new ();
+}
+
+static void
+gst_proxy_pad_dispose (GObject * object)
+{
+  GstPad *pad = GST_PAD (object);
+
+  if (GST_PROXY_PAD_TARGET (pad)) {
+    gst_object_replace ((GstObject **) & GST_PROXY_PAD_TARGET (pad), NULL);
+  }
+
+  G_OBJECT_CLASS (gst_proxy_pad_parent_class)->dispose (object);
+}
+
+static void
+gst_proxy_pad_finalize (GObject * object)
+{
+  GstProxyPad *pad = GST_PROXY_PAD (object);
+
+  g_mutex_free (pad->property_lock);
+  pad->property_lock = NULL;
+
+  G_OBJECT_CLASS (gst_proxy_pad_parent_class)->finalize (object);
+}
+
+#ifndef GST_DISABLE_LOADSAVE
+/**
+ * gst_proxy_pad_save_thyself:
+ * @pad: a ghost #GstPad to save.
+ * @parent: the parent #xmlNodePtr to save the description in.
+ *
+ * Saves the ghost pad into an xml representation.
+ *
+ * Returns: the #xmlNodePtr representation of the pad.
+ */
+static xmlNodePtr
+gst_proxy_pad_save_thyself (GstObject * object, xmlNodePtr parent)
+{
+  xmlNodePtr self;
+
+  g_return_val_if_fail (GST_IS_PROXY_PAD (object), NULL);
+
+  self = xmlNewChild (parent, NULL, (xmlChar *) "ghostpad", NULL);
+  xmlNewChild (self, NULL, (xmlChar *) "name",
+      (xmlChar *) GST_OBJECT_NAME (object));
+  xmlNewChild (self, NULL, (xmlChar *) "parent",
+      (xmlChar *) GST_OBJECT_NAME (GST_OBJECT_PARENT (object)));
+
+  /* FIXME FIXME FIXME! */
+
+  return self;
+}
+#endif /* GST_DISABLE_LOADSAVE */
+
+
+/***********************************************************************
+ * Ghost pads, implemented as a pair of proxy pads (sort of)
+ */
+
+
+enum
+{
+  GHOST_PROP_0,
+  GHOST_PROP_INTERNAL
+};
+
+struct _GstGhostPad
+{
+  GstProxyPad pad;
+
+  GstPad *internal;
+
+  /*< private > */
+  gpointer _gst_reserved[1];
+};
+
+struct _GstGhostPadClass
+{
+  GstProxyPadClass parent_class;
+
+  /*< private > */
+  gpointer _gst_reserved[1];
+};
+
+
+G_DEFINE_TYPE (GstGhostPad, gst_ghost_pad, GST_TYPE_PROXY_PAD);
+
+
+static void gst_ghost_pad_dispose (GObject * object);
+static void gst_ghost_pad_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_ghost_pad_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+
+/* Work around g_logv's use of G_GNUC_PRINTF because gcc chokes on %P, which we
+ * use for GST_PTR_FORMAT. */
+static void
+gst_critical (const gchar * format, ...)
+{
+  va_list args;
+
+  va_start (args, format);
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, format, args);
+  va_end (args);
+}
+
+static void
+gst_ghost_pad_class_init (GstGhostPadClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_get_property);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), GHOST_PROP_INTERNAL,
+      g_param_spec_object ("internal", "Internal",
+          "The ghost pad's internal pad", GST_TYPE_PAD, G_PARAM_READWRITE));
+}
+
+static GstPadLinkReturn
+gst_ghost_pad_do_link (GstPad * pad, GstPad * peer)
+{
+  GstPad *internal, *target;
+
+  target = GST_PROXY_PAD_TARGET (pad);
+  g_return_val_if_fail (target != NULL, GST_PAD_LINK_NOSCHED);
+
+  /* proxy the peer into the bin */
+  internal = g_object_new (GST_TYPE_PROXY_PAD,
+      "name", NULL,
+      "direction", GST_PAD_DIRECTION (peer),
+      "template", GST_PAD_PAD_TEMPLATE (peer), "target", peer, NULL);
+  g_object_set (pad, "internal", internal, NULL);
+
+  if ((GST_PAD_IS_SRC (internal) &&
+          gst_pad_link (internal, target) == GST_PAD_LINK_OK) ||
+      (GST_PAD_IS_SINK (internal) &&
+          (gst_pad_link (target, internal) == GST_PAD_LINK_OK))) {
+    gst_pad_set_active (internal, GST_PAD_ACTIVATE_MODE (pad));
+    return GST_PAD_LINK_OK;
+  } else {
+    g_object_set (pad, "internal", NULL, NULL);
+    return GST_PAD_LINK_REFUSED;
+  }
+}
+
+static void
+gst_ghost_pad_do_unlink (GstPad * pad)
+{
+  GstPad *target = GST_PROXY_PAD_TARGET (pad);
+
+  g_return_if_fail (target != NULL);
+
+  if (target->unlinkfunc)
+    target->unlinkfunc (target);
+
+  /* doesn't work with the object locks in the properties dispatcher... */
+  /* g_object_set (pad, "internal", NULL, NULL); */
+}
+
+static void
+gst_ghost_pad_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstGhostPad *pad = GST_GHOST_PAD (object);
+
+  switch (prop_id) {
+    case GHOST_PROP_INTERNAL:{
+      GstPad *internal;
+
+      g_mutex_lock (GST_PROXY_PAD (pad)->property_lock);
+
+      if (pad->internal) {
+        GstPad *intpeer;
+
+        intpeer = gst_pad_get_peer (pad->internal);
+        if (intpeer) {
+          if (GST_PAD_IS_SRC (pad->internal)) {
+            gst_pad_unlink (pad->internal, intpeer);
+          } else {
+            gst_pad_unlink (intpeer, pad->internal);
+          }
+          gst_object_unref (GST_OBJECT (intpeer));
+        }
+
+        /* delete me, only here for testing... */
+        if (GST_OBJECT_REFCOUNT_VALUE (pad->internal) != 1) {
+          gst_critical ("Refcounting problem: %" GST_PTR_FORMAT, pad->internal);
+        }
+
+        /* should dispose it */
+        gst_object_unparent (GST_OBJECT_CAST (pad->internal));
+      }
+
+      internal = g_value_get_object (value);    /* no extra refcount... */
+
+      if (internal) {
+        if (!gst_object_set_parent (GST_OBJECT_CAST (internal),
+                GST_OBJECT_CAST (pad))) {
+          gst_critical ("Could not set internal pad %" GST_PTR_FORMAT,
+              internal);
+          g_mutex_unlock (GST_PROXY_PAD (pad)->property_lock);
+          return;
+        }
+        /* a ref was taken by set_parent */
+      }
+
+      pad->internal = internal;
+
+      g_mutex_unlock (GST_PROXY_PAD (pad)->property_lock);
+
+      break;
+    }
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_ghost_pad_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  switch (prop_id) {
+    case GHOST_PROP_INTERNAL:
+      g_value_set_object (value, GST_GHOST_PAD (object)->internal);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_ghost_pad_init (GstGhostPad * pad)
+{
+  /* noop */
+}
+
+static void
+gst_ghost_pad_dispose (GObject * object)
+{
+  g_object_set (object, "internal", NULL, NULL);
+
+  G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
+}
+
+/**
+ * gst_ghost_pad_new:
+ * @name: the name of the new pad, or NULL to assign a default name.
+ * @target: the pad to ghost.
+ *
+ * Will ref the target.
+ *
+ * Returns: a new #GstPad, or NULL in case of an error.
+ */
+GstPad *
+gst_ghost_pad_new (const gchar * name, GstPad * target)
+{
+  GstPad *ret;
+
+  g_return_val_if_fail (GST_IS_PAD (target), NULL);
+  g_return_val_if_fail (!GST_PAD_IS_LINKED (target), NULL);
+
+  ret = g_object_new (GST_TYPE_GHOST_PAD,
+      "name", name,
+      "direction", GST_PAD_DIRECTION (target),
+      "template", GST_PAD_PAD_TEMPLATE (target), "target", target, NULL);
+
+  gst_pad_set_link_function (ret, gst_ghost_pad_do_link);
+  gst_pad_set_unlink_function (ret, gst_ghost_pad_do_unlink);
+
+  return ret;
+}
diff --git a/gst/gstghostpad.h b/gst/gstghostpad.h
new file mode 100644 (file)
index 0000000..51f2f84
--- /dev/null
@@ -0,0 +1,53 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *                    2005 Andy Wingo <wingo@pobox.com>
+ *
+ * gstghostpad.h: Proxy pads
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_GHOST_PAD_H__
+#define __GST_GHOST_PAD_H__
+
+
+#include <gst/gstpad.h>
+
+
+G_BEGIN_DECLS
+
+
+#define GST_TYPE_GHOST_PAD             (gst_ghost_pad_get_type ())
+#define GST_IS_GHOST_PAD(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GHOST_PAD))
+#define GST_IS_GHOST_PAD_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD))
+#define GST_GHOST_PAD(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad))
+#define GST_GHOST_PAD_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass))
+
+
+typedef struct _GstGhostPad GstGhostPad;
+typedef struct _GstGhostPadClass GstGhostPadClass;
+
+
+GType           gst_ghost_pad_get_type         (void);
+GstPad*                 gst_ghost_pad_new              (const gchar *name, GstPad *target);
+
+
+G_END_DECLS
+
+
+#endif /* __GST_GHOST_PAD_H__ */
index ab19c49..c80decd 100644 (file)
@@ -160,7 +160,7 @@ gst_object_class_init (GstObjectClass * klass)
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NAME,
       g_param_spec_string ("name", "Name", "The name of the object",
-          NULL, G_PARAM_READWRITE));
+          NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
   gst_object_signals[PARENT_SET] =
       g_signal_new ("parent-set", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
@@ -213,7 +213,6 @@ gst_object_init (GTypeInstance * instance, gpointer g_class)
   GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p new", object);
   gst_atomic_int_set (&object->refcount, 1);
   PATCH_REFCOUNT (object);
-  gst_object_set_name_default (object, G_OBJECT_CLASS_NAME (g_class));
 
   object->flags = 0;
   GST_FLAG_SET (object, GST_OBJECT_FLOATING);
index 8ff7d6d..5e42440 100644 (file)
@@ -23,6 +23,7 @@
 #include "gst_private.h"
 
 #include "gstpad.h"
+#include "gstenumtypes.h"
 #include "gstmarshal.h"
 #include "gstutils.h"
 #include "gstelement.h"
@@ -47,19 +48,6 @@ GST_DEBUG_CATEGORY_STATIC (debug_dataflow);
 }G_STMT_END
 #define GST_CAT_DEFAULT GST_CAT_PADS
 
-/* realize and pad and grab the lock of the realized pad. */
-#define GST_PAD_REALIZE_AND_LOCK(pad, realpad, lost_ghostpad)  \
-  GST_LOCK (pad);                                              \
-  realpad = GST_PAD_REALIZE (pad);                             \
-  if (G_UNLIKELY (realpad == NULL)) {                          \
-    GST_UNLOCK (pad);                                          \
-    goto lost_ghostpad;                                                \
-  }                                                            \
-  if (G_UNLIKELY (pad != GST_PAD_CAST (realpad))) {            \
-    GST_LOCK (realpad);                                                \
-    GST_UNLOCK (pad);                                          \
-  }
-
 enum
 {
   TEMPL_PAD_CREATED,
@@ -70,20 +58,45 @@ enum
 static GstObject *padtemplate_parent_class = NULL;
 static guint gst_pad_template_signals[TEMPL_LAST_SIGNAL] = { 0 };
 
+/* Pad signals and args */
+enum
+{
+  PAD_LINKED,
+  PAD_UNLINKED,
+  PAD_REQUEST_LINK,
+  /* FILL ME */
+  PAD_LAST_SIGNAL
+};
+
+enum
+{
+  PAD_PROP_0,
+  PAD_PROP_CAPS,
+  PAD_PROP_DIRECTION,
+  PAD_PROP_TEMPLATE,
+  /* FILL ME */
+};
+
 GType _gst_pad_type = 0;
 
-/***** Start with the base GstPad class *****/
 static void gst_pad_class_init (GstPadClass * klass);
 static void gst_pad_init (GstPad * pad);
 static void gst_pad_dispose (GObject * object);
+static void gst_pad_finalize (GObject * object);
+static void gst_pad_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_pad_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
 
+static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad);
 static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
 
 #ifndef GST_DISABLE_LOADSAVE
 static xmlNodePtr gst_pad_save_thyself (GstObject * object, xmlNodePtr parent);
 #endif
 
-static GstObject *pad_parent_class = NULL;
+static GstObjectClass *pad_parent_class = NULL;
+static guint gst_pad_signals[PAD_LAST_SIGNAL] = { 0 };
 
 GType
 gst_pad_get_type (void)
@@ -111,116 +124,43 @@ gst_pad_class_init (GstPadClass * klass)
 {
   GObjectClass *gobject_class;
 
-  gobject_class = (GObjectClass *) klass;
-
-  pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
-
-  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
-}
-
-static void
-gst_pad_init (GstPad * pad)
-{
-  /* all structs are initialized to NULL by glib */
-}
-static void
-gst_pad_dispose (GObject * object)
-{
-  GstPad *pad = GST_PAD_CAST (object);
-
-  gst_pad_set_pad_template (pad, NULL);
-  /* FIXME, we have links to many other things like caps
-   * and the peer pad... */
-
-  G_OBJECT_CLASS (pad_parent_class)->dispose (object);
-}
-
-
-
-/***** Then do the Real Pad *****/
-/* Pad signals and args */
-enum
-{
-  REAL_LINKED,
-  REAL_UNLINKED,
-  REAL_REQUEST_LINK,
-  /* FILL ME */
-  REAL_LAST_SIGNAL
-};
-
-enum
-{
-  REAL_ARG_0,
-  REAL_ARG_CAPS,
-  /* FILL ME */
-};
-
-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 void gst_real_pad_finalize (GObject * object);
-
-static void gst_real_pad_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_real_pad_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-static GstCaps *gst_real_pad_get_caps_unlocked (GstRealPad * realpad);
-
-GType _gst_real_pad_type = 0;
-
-static GstPad *real_pad_parent_class = NULL;
-static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
-
-GType
-gst_real_pad_get_type (void)
-{
-  if (!_gst_real_pad_type) {
-    static const GTypeInfo pad_info = {
-      sizeof (GstRealPadClass), NULL, NULL,
-      (GClassInitFunc) gst_real_pad_class_init, NULL, NULL,
-      sizeof (GstRealPad),
-      0,
-      (GInstanceInitFunc) gst_real_pad_init, NULL
-    };
 
-    _gst_real_pad_type = g_type_register_static (GST_TYPE_PAD, "GstRealPad",
-        &pad_info, 0);
-  }
-  return _gst_real_pad_type;
-}
-
-static void
-gst_real_pad_class_init (GstRealPadClass * klass)
-{
-  GObjectClass *gobject_class;
   GstObjectClass *gstobject_class;
 
   gobject_class = (GObjectClass *) klass;
   gstobject_class = (GstObjectClass *) klass;
 
-  real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
+  pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
 
-  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
-  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_real_pad_finalize);
-  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
-  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
+  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
+  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pad_finalize);
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pad_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pad_get_property);
 
-  gst_real_pad_signals[REAL_LINKED] =
+  gst_pad_signals[PAD_LINKED] =
       g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
+      G_STRUCT_OFFSET (GstPadClass, linked), NULL, NULL,
       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
-  gst_real_pad_signals[REAL_UNLINKED] =
+  gst_pad_signals[PAD_UNLINKED] =
       g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL,
+      G_STRUCT_OFFSET (GstPadClass, unlinked), NULL, NULL,
       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
-  gst_real_pad_signals[REAL_REQUEST_LINK] =
+  gst_pad_signals[PAD_REQUEST_LINK] =
       g_signal_new ("request_link", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRealPadClass, request_link), NULL,
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPadClass, request_link), NULL,
       NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 0);
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_CAPS,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PAD_PROP_CAPS,
       g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
           GST_TYPE_CAPS, G_PARAM_READABLE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PAD_PROP_DIRECTION,
+      g_param_spec_enum ("direction", "Direction", "The direction of the pad",
+          GST_TYPE_PAD_DIRECTION, GST_PAD_UNKNOWN,
+          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PAD_PROP_TEMPLATE,
+      g_param_spec_object ("template", "Template",
+          "The GstPadTemplate of this pad", GST_TYPE_PAD_TEMPLATE,
+          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 #ifndef GST_DISABLE_LOADSAVE
   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
@@ -229,14 +169,13 @@ gst_real_pad_class_init (GstRealPadClass * klass)
 }
 
 static void
-gst_real_pad_init (GstRealPad * pad)
+gst_pad_init (GstPad * pad)
 {
   pad->direction = GST_PAD_UNKNOWN;
   pad->peer = NULL;
 
   pad->chainfunc = NULL;
 
-  pad->ghostpads = NULL;
   pad->caps = NULL;
 
   pad->linkfunc = NULL;
@@ -247,7 +186,7 @@ gst_real_pad_init (GstRealPad * pad)
   pad->queryfunc = gst_pad_query_default;
   pad->intlinkfunc = gst_pad_get_internal_links_default;
 
-  GST_RPAD_UNSET_FLUSHING (pad);
+  GST_PAD_UNSET_FLUSHING (pad);
 
   pad->preroll_lock = g_mutex_new ();
   pad->preroll_cond = g_cond_new ();
@@ -259,12 +198,75 @@ gst_real_pad_init (GstRealPad * pad)
 }
 
 static void
-gst_real_pad_set_property (GObject * object, guint prop_id,
+gst_pad_dispose (GObject * object)
+{
+  GstPad *pad = GST_PAD (object);
+
+  gst_pad_set_pad_template (pad, NULL);
+  /* FIXME, we have links to many other things like caps
+   * and the peer pad... */
+
+  /* No linked pad can ever be disposed.
+   * It has to have a parent to be linked 
+   * and a parent would hold a reference */
+  /* FIXME: what about if g_object_dispose is explicitly called on the pad? Is
+     that legal? otherwise we could assert GST_OBJECT_PARENT (pad) == NULL as
+     well... */
+  g_assert (GST_PAD_PEER (pad) == NULL);
+
+  GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s",
+      GST_DEBUG_PAD_NAME (pad));
+
+  /* clear the caps */
+  gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
+
+  if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
+    GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
+        GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
+
+    gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
+  }
+
+  G_OBJECT_CLASS (pad_parent_class)->dispose (object);
+}
+
+static void
+gst_pad_finalize (GObject * object)
+{
+  GstPad *pad = GST_PAD (object);
+
+  if (pad->stream_rec_lock) {
+    g_static_rec_mutex_free (pad->stream_rec_lock);
+    pad->stream_rec_lock = NULL;
+  }
+  if (pad->preroll_lock) {
+    g_mutex_free (pad->preroll_lock);
+    g_cond_free (pad->preroll_cond);
+    pad->preroll_lock = NULL;
+    pad->preroll_cond = NULL;
+  }
+  if (pad->block_cond) {
+    g_cond_free (pad->block_cond);
+    pad->block_cond = NULL;
+  }
+
+  G_OBJECT_CLASS (pad_parent_class)->finalize (object);
+}
+
+static void
+gst_pad_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
   g_return_if_fail (GST_IS_PAD (object));
 
   switch (prop_id) {
+    case PAD_PROP_DIRECTION:
+      GST_PAD_DIRECTION (object) = g_value_get_enum (value);
+      break;
+    case PAD_PROP_TEMPLATE:
+      gst_pad_set_pad_template (GST_PAD_CAST (object),
+          (GstPadTemplate *) g_value_dup_object (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -272,14 +274,20 @@ gst_real_pad_set_property (GObject * object, guint prop_id,
 }
 
 static void
-gst_real_pad_get_property (GObject * object, guint prop_id,
+gst_pad_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec)
 {
   g_return_if_fail (GST_IS_PAD (object));
 
   switch (prop_id) {
-    case REAL_ARG_CAPS:
-      g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object)));
+    case PAD_PROP_CAPS:
+      g_value_set_boxed (value, GST_PAD_CAPS (object));
+      break;
+    case PAD_PROP_DIRECTION:
+      g_value_set_enum (value, GST_PAD_DIRECTION (object));
+      break;
+    case PAD_PROP_TEMPLATE:
+      g_value_set_object (value, GST_PAD_TEMPLATE (object));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -287,41 +295,12 @@ gst_real_pad_get_property (GObject * object, guint prop_id,
   }
 }
 
-/* FIXME-0.9: Replace these custom functions with proper inheritance via _init
-   functions and object properties. update: probably later in the cycle. */
-/**
- * gst_pad_custom_new:
- * @type: the #Gtype of the pad.
- * @name: the name of the new pad.
- * @direction: the #GstPadDirection of the pad.
- *
- * Creates a new pad with the given name and type in the given direction.
- * If name is NULL, a guaranteed unique name (across all pads) 
- * will be assigned. 
- * This function makes a copy of the name so you can safely free the name.
- *
- * Returns: a new #GstPad, or NULL in case of an error.
- *
- * MT safe.
- */
-GstPad *
-gst_pad_custom_new (GType type, const gchar * name, GstPadDirection direction)
-{
-  GstRealPad *pad;
-
-  pad = g_object_new (type, NULL);
-  gst_object_set_name (GST_OBJECT (pad), name);
-  GST_RPAD_DIRECTION (pad) = direction;
-
-  return GST_PAD_CAST (pad);
-}
-
 /**
  * gst_pad_new:
  * @name: the name of the new pad.
  * @direction: the #GstPadDirection of the pad.
  *
- * Creates a new real pad with the given name in the given direction.
+ * Creates a new pad with the given name in the given direction.
  * If name is NULL, a guaranteed unique name (across all pads) 
  * will be assigned.
  * This function makes a copy of the name so you can safely free the name.
@@ -333,16 +312,16 @@ gst_pad_custom_new (GType type, const gchar * name, GstPadDirection direction)
 GstPad *
 gst_pad_new (const gchar * name, GstPadDirection direction)
 {
-  return gst_pad_custom_new (gst_real_pad_get_type (), name, direction);
+  return g_object_new (GST_TYPE_PAD,
+      "name", name, "direction", direction, NULL);
 }
 
 /**
- * gst_pad_custom_new_from_template:
- * @type: the custom #GType of the pad.
- * @templ: the #GstPadTemplate to instantiate from.
- * @name: the name of the new pad.
+ * gst_pad_new_from_template:
+ * @templ: the pad template to use
+ * @name: the name of the element
  *
- * Creates a new custom pad with the given name from the given template.
+ * Creates a new pad with the given name from the given template.
  * If name is NULL, a guaranteed unique name (across all pads) 
  * will be assigned.
  * This function makes a copy of the name so you can safely free the name.
@@ -350,36 +329,41 @@ gst_pad_new (const gchar * name, GstPadDirection direction)
  * Returns: a new #GstPad, or NULL in case of an error.
  */
 GstPad *
-gst_pad_custom_new_from_template (GType type, GstPadTemplate * templ,
-    const gchar * name)
+gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
 {
-  GstPad *pad;
-
   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
 
-  pad = gst_pad_custom_new (type, name, templ->direction);
-  gst_pad_set_pad_template (pad, templ);
-
-  return pad;
+  return g_object_new (GST_TYPE_PAD,
+      "name", name, "direction", templ->direction, "template", templ, NULL);
 }
 
 /**
- * gst_pad_new_from_template:
- * @templ: the pad template to use
- * @name: the name of the element
+ * gst_pad_get_parent:
+ * @pad: a pad
  *
- * Creates a new real pad with the given name from the given template.
- * If name is NULL, a guaranteed unique name (across all pads) 
- * will be assigned.
- * This function makes a copy of the name so you can safely free the name.
+ * Gets the parent of @pad, cast to a #GstElement. If a @pad has no parent or
+ * its parent is not an element, return NULL.
  *
- * Returns: a new #GstPad, or NULL in case of an error.
+ * Returns: The parent of the pad. The caller has a reference on the parent, so
+ * unref when you're finished with it.
+ *
+ * MT safe.
  */
-GstPad *
-gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
+GstElement *
+gst_pad_get_parent (GstPad * pad)
 {
-  return gst_pad_custom_new_from_template (gst_real_pad_get_type (),
-      templ, name);
+  GstObject *p;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+
+  p = gst_object_get_parent (GST_OBJECT_CAST (pad));
+
+  if (p && !GST_IS_ELEMENT (p)) {
+    gst_object_unref (p);
+    p = NULL;
+  }
+
+  return GST_ELEMENT_CAST (p);
 }
 
 /**
@@ -398,23 +382,16 @@ GstPadDirection
 gst_pad_get_direction (GstPad * pad)
 {
   GstPadDirection result;
-  GstRealPad *realpad;
 
   /* PAD_UNKNOWN is a little silly but we need some sort of
    * error return value */
   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
-  result = GST_RPAD_DIRECTION (realpad);
-  GST_UNLOCK (realpad);
+  GST_LOCK (pad);
+  result = GST_PAD_DIRECTION (pad);
+  GST_UNLOCK (pad);
 
   return result;
-
-  /* errors */
-lost_ghostpad:
-  {
-    return GST_PAD_UNKNOWN;
-  }
 }
 
 /**
@@ -437,17 +414,16 @@ lost_ghostpad:
 gboolean
 gst_pad_set_active (GstPad * pad, GstActivateMode mode)
 {
-  GstRealPad *realpad;
   GstActivateMode old;
   GstPadActivateFunction activatefunc;
   gboolean active, oldactive;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
   active = GST_PAD_MODE_ACTIVATE (mode);
-  old = GST_RPAD_ACTIVATE_MODE (realpad);
+  old = GST_PAD_ACTIVATE_MODE (pad);
   oldactive = GST_PAD_MODE_ACTIVATE (old);
 
   /* if nothing changed, we can just exit */
@@ -463,16 +439,16 @@ gst_pad_set_active (GstPad * pad, GstActivateMode mode)
   /* make sure data is disallowed when going inactive */
   if (!active) {
     GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s",
-        GST_DEBUG_PAD_NAME (realpad));
-    GST_RPAD_SET_FLUSHING (realpad);
+        GST_DEBUG_PAD_NAME (pad));
+    GST_PAD_SET_FLUSHING (pad);
     /* unlock blocked pads so element can resume and stop */
-    GST_PAD_BLOCK_SIGNAL (realpad);
+    GST_PAD_BLOCK_SIGNAL (pad);
   }
 
   if (active) {
-    if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SRC) {
+    if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
       if (mode == GST_ACTIVATE_PULL) {
-        if (!realpad->getrangefunc)
+        if (!pad->getrangefunc)
           goto wrong_mode;
       } else {
         /* we can push if driven by a chain or loop on the sink pad.
@@ -483,43 +459,43 @@ gst_pad_set_active (GstPad * pad, GstActivateMode mode)
       if (mode == GST_ACTIVATE_PULL) {
         /* the src can drive us with getrange */
       } else {
-        if (!realpad->chainfunc)
+        if (!pad->chainfunc)
           goto wrong_mode;
       }
     }
   }
 
-  activatefunc = realpad->activatefunc;
+  activatefunc = pad->activatefunc;
   if (activatefunc) {
     gboolean result;
 
     GST_CAT_DEBUG (GST_CAT_PADS,
         "calling activate function on pad %s:%s with mode %d",
-        GST_DEBUG_PAD_NAME (realpad), mode);
+        GST_DEBUG_PAD_NAME (pad), mode);
 
     /* unlock so element can sync */
-    GST_UNLOCK (realpad);
-    result = activatefunc (GST_PAD_CAST (realpad), mode);
+    GST_UNLOCK (pad);
+    result = activatefunc (pad, mode);
     /* and lock again */
-    GST_LOCK (realpad);
+    GST_LOCK (pad);
     if (result == FALSE)
       goto activate_error;
   }
   /* store the mode */
-  GST_RPAD_ACTIVATE_MODE (realpad) = mode;
+  GST_PAD_ACTIVATE_MODE (pad) = mode;
 
   /* when going to active allow data passing now */
   if (active) {
     GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s in mode %d",
-        GST_DEBUG_PAD_NAME (realpad), mode);
-    GST_RPAD_UNSET_FLUSHING (realpad);
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad), mode);
+    GST_PAD_UNSET_FLUSHING (pad);
+    GST_UNLOCK (pad);
   } else {
-    GST_UNLOCK (realpad);
+    GST_UNLOCK (pad);
 
     /* and make streaming finish */
-    GST_STREAM_LOCK (realpad);
-    GST_STREAM_UNLOCK (realpad);
+    GST_STREAM_LOCK (pad);
+    GST_STREAM_UNLOCK (pad);
   }
   return TRUE;
 
@@ -527,29 +503,25 @@ was_ok:
   {
     GST_CAT_DEBUG (GST_CAT_PADS,
         "pad %s:%s was active, old %d, new %d",
-        GST_DEBUG_PAD_NAME (realpad), old, mode);
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad), old, mode);
+    GST_UNLOCK (pad);
     return TRUE;
   }
   /* errors */
-lost_ghostpad:
-  {
-    return FALSE;
-  }
 wrong_mode:
   {
     GST_CAT_DEBUG (GST_CAT_PADS,
         "pad %s:%s lacks functions to be active in mode %d",
-        GST_DEBUG_PAD_NAME (realpad), mode);
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad), mode);
+    GST_UNLOCK (pad);
     return FALSE;
   }
 activate_error:
   {
     GST_CAT_DEBUG (GST_CAT_PADS,
         "activate function returned FALSE for pad %s:%s",
-        GST_DEBUG_PAD_NAME (realpad));
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad));
+    GST_UNLOCK (pad);
     return FALSE;
   }
 }
@@ -604,20 +576,14 @@ gboolean
 gst_pad_is_active (GstPad * pad)
 {
   gboolean result = FALSE;
-  GstRealPad *realpad;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
-  result = GST_PAD_MODE_ACTIVATE (GST_RPAD_ACTIVATE_MODE (realpad));
-  GST_UNLOCK (realpad);
+  GST_LOCK (pad);
+  result = GST_PAD_MODE_ACTIVATE (GST_PAD_ACTIVATE_MODE (pad));
+  GST_UNLOCK (pad);
 
   return result;
-
-lost_ghostpad:
-  {
-    return FALSE;
-  }
 }
 
 /**
@@ -648,60 +614,55 @@ gst_pad_set_blocked_async (GstPad * pad, gboolean blocked,
     GstPadBlockCallback callback, gpointer user_data)
 {
   gboolean was_blocked;
-  GstRealPad *realpad;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
-  was_blocked = GST_RPAD_IS_BLOCKED (realpad);
+  was_blocked = GST_PAD_IS_BLOCKED (pad);
 
   if (G_UNLIKELY (was_blocked == blocked))
     goto had_right_state;
 
   if (blocked) {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "blocking pad %s:%s",
-        GST_DEBUG_PAD_NAME (realpad));
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocking pad %s:%s",
+        GST_DEBUG_PAD_NAME (pad));
 
-    GST_FLAG_SET (realpad, GST_PAD_BLOCKED);
-    realpad->block_callback = callback;
-    realpad->block_data = user_data;
+    GST_FLAG_SET (pad, GST_PAD_BLOCKED);
+    pad->block_callback = callback;
+    pad->block_data = user_data;
     if (!callback) {
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "waiting for block");
-      GST_PAD_BLOCK_WAIT (realpad);
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "blocked");
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for block");
+      GST_PAD_BLOCK_WAIT (pad);
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocked");
     }
   } else {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "unblocking pad %s:%s",
-        GST_DEBUG_PAD_NAME (realpad));
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocking pad %s:%s",
+        GST_DEBUG_PAD_NAME (pad));
 
-    GST_FLAG_UNSET (realpad, GST_PAD_BLOCKED);
+    GST_FLAG_UNSET (pad, GST_PAD_BLOCKED);
 
-    realpad->block_callback = callback;
-    realpad->block_data = user_data;
+    pad->block_callback = callback;
+    pad->block_data = user_data;
 
     if (callback) {
-      GST_PAD_BLOCK_SIGNAL (realpad);
+      GST_PAD_BLOCK_SIGNAL (pad);
     } else {
-      GST_PAD_BLOCK_SIGNAL (realpad);
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "waiting for unblock");
-      GST_PAD_BLOCK_WAIT (realpad);
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad, "unblocked");
+      GST_PAD_BLOCK_SIGNAL (pad);
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for unblock");
+      GST_PAD_BLOCK_WAIT (pad);
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocked");
     }
   }
-  GST_UNLOCK (realpad);
+  GST_UNLOCK (pad);
 
   return TRUE;
 
-lost_ghostpad:
-  {
-    return FALSE;
-  }
 had_right_state:
   {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, realpad,
-        "pad %s:%s was in right state", GST_DEBUG_PAD_NAME (realpad));
-    GST_UNLOCK (realpad);
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+        "pad %s:%s was in right state", GST_DEBUG_PAD_NAME (pad));
+    GST_UNLOCK (pad);
     return FALSE;
   }
 }
@@ -743,25 +704,19 @@ gboolean
 gst_pad_is_blocked (GstPad * pad)
 {
   gboolean result = FALSE;
-  GstRealPad *realpad;
 
   g_return_val_if_fail (GST_IS_PAD (pad), result);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
-  result = GST_FLAG_IS_SET (realpad, GST_PAD_BLOCKED);
-  GST_UNLOCK (realpad);
+  GST_LOCK (pad);
+  result = GST_FLAG_IS_SET (pad, GST_PAD_BLOCKED);
+  GST_UNLOCK (pad);
 
   return result;
-
-lost_ghostpad:
-  {
-    return FALSE;
-  }
 }
 
 /**
  * gst_pad_set_activate_function:
- * @pad: a real sink #GstPad.
+ * @pad: a sink #GstPad.
  * @chain: the #GstPadActivateFunction to set.
  *
  * Sets the given activate function for the pad. The activate function is called to
@@ -770,16 +725,16 @@ lost_ghostpad:
 void
 gst_pad_set_activate_function (GstPad * pad, GstPadActivateFunction activate)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_ACTIVATEFUNC (pad) = activate;
+  GST_PAD_ACTIVATEFUNC (pad) = activate;
   GST_CAT_DEBUG (GST_CAT_PADS, "activatefunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (activate));
 }
 
 /**
  * gst_pad_set_loop_function:
- * @pad: a real sink #GstPad.
+ * @pad: a sink #GstPad.
  * @chain: the #GstPadLoopFunction to set.
  *
  * Sets the given loop function for the pad. The loop function is called 
@@ -788,16 +743,16 @@ gst_pad_set_activate_function (GstPad * pad, GstPadActivateFunction activate)
 void
 gst_pad_set_loop_function (GstPad * pad, GstPadLoopFunction loop)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_LOOPFUNC (pad) = loop;
+  GST_PAD_LOOPFUNC (pad) = loop;
   GST_CAT_DEBUG (GST_CAT_PADS, "loopfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (loop));
 }
 
 /**
  * gst_pad_set_chain_function:
- * @pad: a real sink #GstPad.
+ * @pad: a sink #GstPad.
  * @chain: the #GstPadChainFunction to set.
  *
  * Sets the given chain function for the pad. The chain function is called to
@@ -806,17 +761,17 @@ gst_pad_set_loop_function (GstPad * pad, GstPadLoopFunction loop)
 void
 gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
-  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK);
 
-  GST_RPAD_CHAINFUNC (pad) = chain;
+  GST_PAD_CHAINFUNC (pad) = chain;
   GST_CAT_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain));
 }
 
 /**
  * gst_pad_set_getrange_function:
- * @pad: a real source #GstPad.
+ * @pad: a source #GstPad.
  * @get: the #GstPadGetRangeFunction to set.
  *
  * Sets the given getrange function for the pad. The getrange function is called to
@@ -826,10 +781,10 @@ gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
 void
 gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
-  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
 
-  GST_RPAD_GETRANGEFUNC (pad) = get;
+  GST_PAD_GETRANGEFUNC (pad) = get;
 
   GST_CAT_DEBUG (GST_CAT_PADS, "getrangefunc for %s:%s  set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
@@ -837,7 +792,7 @@ gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
 
 /**
  * gst_pad_set_checkgetrange_function:
- * @pad: a real source #GstPad.
+ * @pad: a source #GstPad.
  * @check: the #GstPadCheckGetRangeFunction to set.
  *
  * Sets the given checkgetrange function for the pad. Implement this function on
@@ -847,10 +802,10 @@ void
 gst_pad_set_checkgetrange_function (GstPad * pad,
     GstPadCheckGetRangeFunction check)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
-  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
 
-  GST_RPAD_CHECKGETRANGEFUNC (pad) = check;
+  GST_PAD_CHECKGETRANGEFUNC (pad) = check;
 
   GST_CAT_DEBUG (GST_CAT_PADS, "checkgetrangefunc for %s:%s  set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (check));
@@ -858,7 +813,7 @@ gst_pad_set_checkgetrange_function (GstPad * pad,
 
 /**
  * gst_pad_set_event_function:
- * @pad: a real source #GstPad.
+ * @pad: a source #GstPad.
  * @event: the #GstPadEventFunction to set.
  *
  * Sets the given event handler for the pad.
@@ -866,9 +821,9 @@ gst_pad_set_checkgetrange_function (GstPad * pad,
 void
 gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_EVENTFUNC (pad) = event;
+  GST_PAD_EVENTFUNC (pad) = event;
 
   GST_CAT_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s  set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event));
@@ -876,7 +831,7 @@ gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event)
 
 /**
  * gst_pad_set_query_function:
- * @pad: a real #GstPad of either direction.
+ * @pad: a #GstPad of either direction.
  * @query: the #GstPadQueryFunction to set.
  *
  * Set the given query function for the pad.
@@ -884,9 +839,9 @@ gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event)
 void
 gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_QUERYFUNC (pad) = query;
+  GST_PAD_QUERYFUNC (pad) = query;
 
   GST_CAT_DEBUG (GST_CAT_PADS, "queryfunc for %s:%s  set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
@@ -894,7 +849,7 @@ gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
 
 /**
  * gst_pad_set_query_type_function:
- * @pad: a real #GstPad of either direction.
+ * @pad: a #GstPad of either direction.
  * @type_func: the #GstPadQueryTypeFunction to set.
  *
  * Set the given query type function for the pad.
@@ -903,9 +858,9 @@ void
 gst_pad_set_query_type_function (GstPad * pad,
     GstPadQueryTypeFunction type_func)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_QUERYTYPEFUNC (pad) = type_func;
+  GST_PAD_QUERYTYPEFUNC (pad) = type_func;
 
   GST_CAT_DEBUG (GST_CAT_PADS, "querytypefunc for %s:%s  set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (type_func));
@@ -923,19 +878,14 @@ gst_pad_set_query_type_function (GstPad * pad,
 const GstQueryType *
 gst_pad_get_query_types (GstPad * pad)
 {
-  GstRealPad *rpad;
   GstPadQueryTypeFunction func;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  rpad = GST_PAD_REALIZE (pad);
-
-  g_return_val_if_fail (rpad, NULL);
-
-  if (G_UNLIKELY ((func = GST_RPAD_QUERYTYPEFUNC (rpad)) == NULL))
+  if (G_UNLIKELY ((func = GST_PAD_QUERYTYPEFUNC (pad)) == NULL))
     goto no_func;
 
-  return func (GST_PAD_CAST (rpad));
+  return func (pad);
 
 no_func:
   {
@@ -976,7 +926,7 @@ gst_pad_get_query_types_default (GstPad * pad)
 
 /**
  * gst_pad_set_internal_link_function:
- * @pad: a real #GstPad of either direction.
+ * @pad: a #GstPad of either direction.
  * @intlink: the #GstPadIntLinkFunction to set.
  *
  * Sets the given internal link function for the pad.
@@ -984,16 +934,16 @@ gst_pad_get_query_types_default (GstPad * pad)
 void
 gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_INTLINKFUNC (pad) = intlink;
+  GST_PAD_INTLINKFUNC (pad) = intlink;
   GST_CAT_DEBUG (GST_CAT_PADS, "internal link for %s:%s  set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intlink));
 }
 
 /**
  * gst_pad_set_link_function:
- * @pad: a real #GstPad.
+ * @pad: a #GstPad.
  * @link: the #GstPadLinkFunction to set.
  * 
  * Sets the given link function for the pad. It will be called when the pad is
@@ -1009,16 +959,16 @@ gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink)
 void
 gst_pad_set_link_function (GstPad * pad, GstPadLinkFunction link)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_LINKFUNC (pad) = link;
+  GST_PAD_LINKFUNC (pad) = link;
   GST_CAT_DEBUG (GST_CAT_PADS, "linkfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (link));
 }
 
 /**
  * gst_pad_set_unlink_function:
- * @pad: a real #GstPad.
+ * @pad: a #GstPad.
  * @unlink: the #GstPadUnlinkFunction to set.
  *
  * Sets the given unlink function for the pad. It will be called
@@ -1027,16 +977,16 @@ gst_pad_set_link_function (GstPad * pad, GstPadLinkFunction link)
 void
 gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_UNLINKFUNC (pad) = unlink;
+  GST_PAD_UNLINKFUNC (pad) = unlink;
   GST_CAT_DEBUG (GST_CAT_PADS, "unlinkfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (unlink));
 }
 
 /**
  * gst_pad_set_getcaps_function:
- * @pad: a real #GstPad.
+ * @pad: a #GstPad.
  * @getcaps: the #GstPadGetCapsFunction to set.
  * 
  * Sets the given getcaps function for the pad. @getcaps should return the
@@ -1063,16 +1013,16 @@ gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
 void
 gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_GETCAPSFUNC (pad) = getcaps;
+  GST_PAD_GETCAPSFUNC (pad) = getcaps;
   GST_CAT_DEBUG (GST_CAT_PADS, "getcapsfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
 }
 
 /**
  * gst_pad_set_acceptcaps_function:
- * @pad: a real #GstPad.
+ * @pad: a #GstPad.
  * @acceptcaps: the #GstPadAcceptCapsFunction to set.
  *
  * Sets the given acceptcaps function for the pad.  The acceptcaps function
@@ -1082,16 +1032,16 @@ void
 gst_pad_set_acceptcaps_function (GstPad * pad,
     GstPadAcceptCapsFunction acceptcaps)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_ACCEPTCAPSFUNC (pad) = acceptcaps;
+  GST_PAD_ACCEPTCAPSFUNC (pad) = acceptcaps;
   GST_CAT_DEBUG (GST_CAT_PADS, "acceptcapsfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (acceptcaps));
 }
 
 /**
  * gst_pad_set_fixatecaps_function:
- * @pad: a real #GstPad.
+ * @pad: a #GstPad.
  * @fixatecaps: the #GstPadFixateCapsFunction to set.
  *
  * Sets the given fixatecaps function for the pad.  The fixatecaps function
@@ -1102,16 +1052,16 @@ void
 gst_pad_set_fixatecaps_function (GstPad * pad,
     GstPadFixateCapsFunction fixatecaps)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_FIXATECAPSFUNC (pad) = fixatecaps;
+  GST_PAD_FIXATECAPSFUNC (pad) = fixatecaps;
   GST_CAT_DEBUG (GST_CAT_PADS, "fixatecapsfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (fixatecaps));
 }
 
 /**
  * gst_pad_set_setcaps_function:
- * @pad: a real #GstPad.
+ * @pad: a #GstPad.
  * @setcaps: the #GstPadSetCapsFunction to set.
  *
  * Sets the given setcaps function for the pad.  The setcaps function
@@ -1123,16 +1073,16 @@ gst_pad_set_fixatecaps_function (GstPad * pad,
 void
 gst_pad_set_setcaps_function (GstPad * pad, GstPadSetCapsFunction setcaps)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_RPAD_SETCAPSFUNC (pad) = setcaps;
+  GST_PAD_SETCAPSFUNC (pad) = setcaps;
   GST_CAT_DEBUG (GST_CAT_PADS, "setcapsfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (setcaps));
 }
 
 /**
  * gst_pad_set_bufferalloc_function:
- * @pad: a real sink #GstPad.
+ * @pad: a sink #GstPad.
  * @bufalloc: the #GstPadBufferAllocFunction to set.
  *
  * Sets the given bufferalloc function for the pad. Note that the
@@ -1142,10 +1092,10 @@ void
 gst_pad_set_bufferalloc_function (GstPad * pad,
     GstPadBufferAllocFunction bufalloc)
 {
-  g_return_if_fail (GST_IS_REAL_PAD (pad));
+  g_return_if_fail (GST_IS_PAD (pad));
   g_return_if_fail (GST_PAD_IS_SINK (pad));
 
-  GST_RPAD_BUFFERALLOCFUNC (pad) = bufalloc;
+  GST_PAD_BUFFERALLOCFUNC (pad) = bufalloc;
   GST_CAT_DEBUG (GST_CAT_PADS, "bufferallocfunc for %s:%s set to %s",
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (bufalloc));
 }
@@ -1166,8 +1116,6 @@ gst_pad_set_bufferalloc_function (GstPad * pad,
 gboolean
 gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
 {
-  GstRealPad *realsrc, *realsink;
-
   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
 
@@ -1175,73 +1123,62 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
       GST_DEBUG_PAD_NAME (srcpad), srcpad,
       GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
 
-  GST_PAD_REALIZE_AND_LOCK (srcpad, realsrc, lost_src_ghostpad);
+  GST_LOCK (srcpad);
 
-  if (G_UNLIKELY (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC))
+  if (G_UNLIKELY (GST_PAD_DIRECTION (srcpad) != GST_PAD_SRC))
     goto not_srcpad;
 
-  GST_PAD_REALIZE_AND_LOCK (sinkpad, realsink, lost_sink_ghostpad);
+  GST_LOCK (sinkpad);
 
-  if (G_UNLIKELY (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK))
+  if (G_UNLIKELY (GST_PAD_DIRECTION (sinkpad) != GST_PAD_SINK))
     goto not_sinkpad;
 
-  if (G_UNLIKELY (GST_RPAD_PEER (realsrc) != realsink))
+  if (G_UNLIKELY (GST_PAD_PEER (srcpad) != sinkpad))
     goto not_linked_together;
 
-  if (GST_RPAD_UNLINKFUNC (realsrc)) {
-    GST_RPAD_UNLINKFUNC (realsrc) (GST_PAD_CAST (realsrc));
+  if (GST_PAD_UNLINKFUNC (srcpad)) {
+    GST_PAD_UNLINKFUNC (srcpad) (srcpad);
   }
-  if (GST_RPAD_UNLINKFUNC (realsink)) {
-    GST_RPAD_UNLINKFUNC (realsink) (GST_PAD_CAST (realsink));
+  if (GST_PAD_UNLINKFUNC (sinkpad)) {
+    GST_PAD_UNLINKFUNC (sinkpad) (sinkpad);
   }
 
   /* first clear peers */
-  GST_RPAD_PEER (realsrc) = NULL;
-  GST_RPAD_PEER (realsink) = NULL;
+  GST_PAD_PEER (srcpad) = NULL;
+  GST_PAD_PEER (sinkpad) = NULL;
 
-  GST_UNLOCK (realsink);
-  GST_UNLOCK (realsrc);
+  GST_UNLOCK (sinkpad);
+  GST_UNLOCK (srcpad);
 
   /* fire off a signal to each of the pads telling them 
    * that they've been unlinked */
-  g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_UNLINKED],
-      0, realsink);
-  g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_UNLINKED],
-      0, realsrc);
+  g_signal_emit (G_OBJECT (srcpad), gst_pad_signals[PAD_UNLINKED], 0, sinkpad);
+  g_signal_emit (G_OBJECT (sinkpad), gst_pad_signals[PAD_UNLINKED], 0, srcpad);
 
   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
-      GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
+      GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
 
   return TRUE;
 
-lost_src_ghostpad:
-  {
-    return FALSE;
-  }
 not_srcpad:
   {
-    g_critical ("pad %s is not a source pad", GST_PAD_NAME (realsrc));
-    GST_UNLOCK (realsrc);
-    return FALSE;
-  }
-lost_sink_ghostpad:
-  {
-    GST_UNLOCK (realsrc);
+    g_critical ("pad %s is not a source pad", GST_PAD_NAME (srcpad));
+    GST_UNLOCK (srcpad);
     return FALSE;
   }
 not_sinkpad:
   {
-    g_critical ("pad %s is not a sink pad", GST_PAD_NAME (realsink));
-    GST_UNLOCK (realsink);
-    GST_UNLOCK (realsrc);
+    g_critical ("pad %s is not a sink pad", GST_PAD_NAME (sinkpad));
+    GST_UNLOCK (sinkpad);
+    GST_UNLOCK (srcpad);
     return FALSE;
   }
 not_linked_together:
   {
     /* we do not emit a warning in this case because unlinking cannot
      * be made MT safe.*/
-    GST_UNLOCK (realsink);
-    GST_UNLOCK (realsrc);
+    GST_UNLOCK (sinkpad);
+    GST_UNLOCK (srcpad);
     return FALSE;
   }
 }
@@ -1260,29 +1197,24 @@ gboolean
 gst_pad_is_linked (GstPad * pad)
 {
   gboolean result;
-  GstRealPad *realpad;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
-  result = (GST_PAD_PEER (realpad) != NULL);
-  GST_UNLOCK (realpad);
-  return result;
+  GST_LOCK (pad);
+  result = (GST_PAD_PEER (pad) != NULL);
+  GST_UNLOCK (pad);
 
-lost_ghostpad:
-  {
-    return FALSE;
-  }
+  return result;
 }
 
 static gboolean
-gst_pad_link_check_compatible_unlocked (GstRealPad * src, GstRealPad * sink)
+gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink)
 {
   GstCaps *srccaps;
   GstCaps *sinkcaps;
 
-  srccaps = gst_real_pad_get_caps_unlocked (src);
-  sinkcaps = gst_real_pad_get_caps_unlocked (sink);
+  srccaps = gst_pad_get_caps_unlocked (src);
+  sinkcaps = gst_pad_get_caps_unlocked (sink);
   GST_CAT_DEBUG (GST_CAT_CAPS, "got caps %p and %p", srccaps, sinkcaps);
 
   if (srccaps && sinkcaps) {
@@ -1302,10 +1234,8 @@ gst_pad_link_check_compatible_unlocked (GstRealPad * src, GstRealPad * sink)
 
 /* FIXME leftover from an attempt at refactoring... */
 static GstPadLinkReturn
-gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad,
-    GstRealPad ** outrealsrc, GstRealPad ** outrealsink)
+gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad)
 {
-  GstRealPad *realsrc, *realsink;
 
   /* generic checks */
   g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
@@ -1314,33 +1244,24 @@ gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad,
   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
 
-  /* now we need to deal with the real/ghost stuff */
-  GST_PAD_REALIZE_AND_LOCK (srcpad, realsrc, lost_src_ghostpad);
+  GST_LOCK (srcpad);
 
-  if (G_UNLIKELY (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC))
+  if (G_UNLIKELY (GST_PAD_DIRECTION (srcpad) != GST_PAD_SRC))
     goto not_srcpad;
 
-  if (G_UNLIKELY (GST_RPAD_PEER (realsrc) != NULL))
+  if (G_UNLIKELY (GST_PAD_PEER (srcpad) != NULL))
     goto src_was_linked;
 
-  GST_PAD_REALIZE_AND_LOCK (sinkpad, realsink, lost_sink_ghostpad);
+  GST_LOCK (sinkpad);
 
-  if (G_UNLIKELY (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK))
+  if (G_UNLIKELY (GST_PAD_DIRECTION (sinkpad) != GST_PAD_SINK))
     goto not_sinkpad;
 
-  if (G_UNLIKELY (GST_RPAD_PEER (realsink) != NULL))
+  if (G_UNLIKELY (GST_PAD_PEER (sinkpad) != NULL))
     goto sink_was_linked;
 
-  if ((GST_PAD_CAST (realsrc) != srcpad)
-      || (GST_PAD_CAST (realsink) != sinkpad)) {
-    GST_CAT_INFO (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
-        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
-  }
-  *outrealsrc = realsrc;
-  *outrealsink = realsink;
-
   /* check pad caps for non-empty intersection */
-  if (!gst_pad_link_check_compatible_unlocked (realsrc, realsink)) {
+  if (!gst_pad_link_check_compatible_unlocked (srcpad, sinkpad)) {
     goto no_format;
   }
 
@@ -1348,53 +1269,43 @@ gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad,
 
   return GST_PAD_LINK_OK;
 
-lost_src_ghostpad:
-  {
-    return GST_PAD_LINK_REFUSED;
-  }
 not_srcpad:
   {
-    g_critical ("pad %s is not a source pad", GST_PAD_NAME (realsrc));
-    GST_UNLOCK (realsrc);
+    g_critical ("pad %s is not a source pad", GST_PAD_NAME (srcpad));
+    GST_UNLOCK (srcpad);
     return GST_PAD_LINK_WRONG_DIRECTION;
   }
 src_was_linked:
   {
     GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was linked",
-        GST_DEBUG_PAD_NAME (realsrc));
+        GST_DEBUG_PAD_NAME (srcpad));
     /* we do not emit a warning in this case because unlinking cannot
      * be made MT safe.*/
-    GST_UNLOCK (realsrc);
+    GST_UNLOCK (srcpad);
     return GST_PAD_LINK_WAS_LINKED;
   }
-lost_sink_ghostpad:
-  {
-    GST_DEBUG ("lost sink ghostpad");
-    GST_UNLOCK (realsrc);
-    return GST_PAD_LINK_REFUSED;
-  }
 not_sinkpad:
   {
-    g_critical ("pad %s is not a sink pad", GST_PAD_NAME (realsink));
-    GST_UNLOCK (realsink);
-    GST_UNLOCK (realsrc);
+    g_critical ("pad %s is not a sink pad", GST_PAD_NAME (sinkpad));
+    GST_UNLOCK (sinkpad);
+    GST_UNLOCK (srcpad);
     return GST_PAD_LINK_WRONG_DIRECTION;
   }
 sink_was_linked:
   {
     GST_CAT_INFO (GST_CAT_PADS, "sink %s:%s was linked",
-        GST_DEBUG_PAD_NAME (realsink));
+        GST_DEBUG_PAD_NAME (sinkpad));
     /* we do not emit a warning in this case because unlinking cannot
      * be made MT safe.*/
-    GST_UNLOCK (realsink);
-    GST_UNLOCK (realsrc);
+    GST_UNLOCK (sinkpad);
+    GST_UNLOCK (srcpad);
     return GST_PAD_LINK_WAS_LINKED;
   }
 no_format:
   {
     GST_CAT_INFO (GST_CAT_PADS, "caps are incompatible");
-    GST_UNLOCK (realsink);
-    GST_UNLOCK (realsrc);
+    GST_UNLOCK (sinkpad);
+    GST_UNLOCK (srcpad);
     return GST_PAD_LINK_NOFORMAT;
   }
 }
@@ -1414,58 +1325,52 @@ no_format:
 GstPadLinkReturn
 gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
 {
-  GstRealPad *realsrc, *realsink;
   GstPadLinkReturn result;
 
-  result = gst_pad_link_prepare (srcpad, sinkpad, &realsrc, &realsink);
+  result = gst_pad_link_prepare (srcpad, sinkpad);
 
   if (result != GST_PAD_LINK_OK)
     goto prepare_failed;
 
-  GST_UNLOCK (realsink);
-  GST_UNLOCK (realsrc);
+  GST_UNLOCK (sinkpad);
+  GST_UNLOCK (srcpad);
 
   /* FIXME released the locks here, concurrent thread might link
    * something else. */
-  if (GST_RPAD_LINKFUNC (realsrc)) {
+  if (GST_PAD_LINKFUNC (srcpad)) {
     /* this one will call the peer link function */
-    result =
-        GST_RPAD_LINKFUNC (realsrc) (GST_PAD_CAST (realsrc),
-        GST_PAD_CAST (realsink));
-  } else if (GST_RPAD_LINKFUNC (realsink)) {
+    result = GST_PAD_LINKFUNC (srcpad) (srcpad, sinkpad);
+  } else if (GST_PAD_LINKFUNC (sinkpad)) {
     /* if no source link function, we need to call the sink link
      * function ourselves. */
-    result =
-        GST_RPAD_LINKFUNC (realsink) (GST_PAD_CAST (realsink),
-        GST_PAD_CAST (realsrc));
+    result = GST_PAD_LINKFUNC (sinkpad) (sinkpad, srcpad);
   } else {
     result = GST_PAD_LINK_OK;
   }
 
-  GST_LOCK (realsrc);
-  GST_LOCK (realsink);
+  GST_LOCK (srcpad);
+  GST_LOCK (sinkpad);
+
   if (result == GST_PAD_LINK_OK) {
-    GST_RPAD_PEER (realsrc) = GST_REAL_PAD (realsink);
-    GST_RPAD_PEER (realsink) = GST_REAL_PAD (realsrc);
+    GST_PAD_PEER (srcpad) = sinkpad;
+    GST_PAD_PEER (sinkpad) = srcpad;
 
-    GST_UNLOCK (realsink);
-    GST_UNLOCK (realsrc);
+    GST_UNLOCK (sinkpad);
+    GST_UNLOCK (srcpad);
 
     /* fire off a signal to each of the pads telling them 
      * that they've been linked */
-    g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_LINKED],
-        0, realsink);
-    g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_LINKED],
-        0, realsrc);
+    g_signal_emit (G_OBJECT (srcpad), gst_pad_signals[PAD_LINKED], 0, sinkpad);
+    g_signal_emit (G_OBJECT (sinkpad), gst_pad_signals[PAD_LINKED], 0, srcpad);
 
     GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
-        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
+        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
   } else {
     GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed",
-        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
+        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
 
-    GST_UNLOCK (realsink);
-    GST_UNLOCK (realsrc);
+    GST_UNLOCK (sinkpad);
+    GST_UNLOCK (srcpad);
   }
   return result;
 
@@ -1511,109 +1416,43 @@ gst_pad_get_pad_template (GstPad * pad)
 }
 
 
-/**
- * gst_pad_get_real_parent:
- * @pad: a #GstPad to get the real parent of.
- *
- * Gets the real parent object of this pad. If the pad
- * is a ghost pad, the actual owner of the real pad is
- * returned, as opposed to #gst_pad_get_parent().
- * Unref the object after use.
- *
- * Returns: the parent #GstElement. unref after usage.
- *
- * MT safe.
- */
-GstElement *
-gst_pad_get_real_parent (GstPad * pad)
-{
-  GstRealPad *realpad;
-  GstElement *element;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
-  element = GST_PAD_PARENT (realpad);
-  if (element)
-    gst_object_ref (GST_OBJECT_CAST (element));
-  GST_UNLOCK (realpad);
-
-  return element;
-
-lost_ghostpad:
-  {
-    return NULL;
-  }
-}
-
-/* FIXME not MT safe */
-static void
-gst_pad_add_ghost_pad (GstPad * pad, GstPad * ghostpad)
-{
-  GstRealPad *realpad;
-
-  /* if we're ghosting a ghost pad, drill down to find the real pad */
-  realpad = (GstRealPad *) pad;
-  while (GST_IS_GHOST_PAD (realpad))
-    realpad = GST_GPAD_REALPAD (realpad);
-  g_return_if_fail (GST_IS_REAL_PAD (realpad));
-
-  /* will ref the pad template */
-  GST_GPAD_REALPAD (ghostpad) = realpad;
-  realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
-  gst_pad_set_pad_template (GST_PAD (ghostpad), GST_PAD_PAD_TEMPLATE (pad));
-}
-
-static void
-gst_pad_remove_ghost_pad (GstPad * pad, GstPad * ghostpad)
-{
-  GstRealPad *realpad;
-
-  realpad = GST_PAD_REALIZE (pad);
-  g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad);
-
-  gst_pad_set_pad_template (GST_PAD (ghostpad), NULL);
-  realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
-  GST_GPAD_REALPAD (ghostpad) = NULL;
-}
-
 /* should be called with the pad LOCK held */
 static GstCaps *
-gst_real_pad_get_caps_unlocked (GstRealPad * realpad)
+gst_pad_get_caps_unlocked (GstPad * pad)
 {
   GstCaps *result = NULL;
 
   GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
-      GST_DEBUG_PAD_NAME (realpad), realpad);
+      GST_DEBUG_PAD_NAME (pad), pad);
 
-  if (GST_RPAD_GETCAPSFUNC (realpad)) {
+  if (GST_PAD_GETCAPSFUNC (pad)) {
     GST_CAT_DEBUG (GST_CAT_CAPS, "dispatching to pad getcaps function");
 
-    GST_FLAG_SET (realpad, GST_PAD_IN_GETCAPS);
-    GST_UNLOCK (realpad);
-    result = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad));
-    GST_LOCK (realpad);
-    GST_FLAG_UNSET (realpad, GST_PAD_IN_GETCAPS);
+    GST_FLAG_SET (pad, GST_PAD_IN_GETCAPS);
+    GST_UNLOCK (pad);
+    result = GST_PAD_GETCAPSFUNC (pad) (pad);
+    GST_LOCK (pad);
+    GST_FLAG_UNSET (pad, GST_PAD_IN_GETCAPS);
 
     if (result == NULL) {
       g_critical ("pad %s:%s returned NULL caps from getcaps function",
-          GST_DEBUG_PAD_NAME (realpad));
+          GST_DEBUG_PAD_NAME (pad));
     } else {
 #ifndef G_DISABLE_ASSERT
       /* check that the returned caps are a real subset of the template caps */
-      if (GST_PAD_PAD_TEMPLATE (realpad)) {
+      if (GST_PAD_PAD_TEMPLATE (pad)) {
         const GstCaps *templ_caps =
-            GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (realpad));
+            GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
         if (!gst_caps_is_subset (result, templ_caps)) {
           GstCaps *temp;
 
-          GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, realpad,
+          GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, pad,
               "pad returned caps %" GST_PTR_FORMAT
               " which are not a real subset of its template caps %"
               GST_PTR_FORMAT, result, templ_caps);
           g_warning
               ("pad %s:%s returned caps that are not a real subset of its template caps",
-              GST_DEBUG_PAD_NAME (realpad));
+              GST_DEBUG_PAD_NAME (pad));
           temp = gst_caps_intersect (templ_caps, result);
           gst_caps_unref (result);
           result = temp;
@@ -1623,8 +1462,8 @@ gst_real_pad_get_caps_unlocked (GstRealPad * realpad)
       goto done;
     }
   }
-  if (GST_PAD_PAD_TEMPLATE (realpad)) {
-    GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad);
+  if (GST_PAD_PAD_TEMPLATE (pad)) {
+    GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
 
     result = GST_PAD_TEMPLATE_CAPS (templ);
     GST_CAT_DEBUG (GST_CAT_CAPS,
@@ -1634,8 +1473,8 @@ gst_real_pad_get_caps_unlocked (GstRealPad * realpad)
     result = gst_caps_ref (result);
     goto done;
   }
-  if (GST_RPAD_CAPS (realpad)) {
-    result = GST_RPAD_CAPS (realpad);
+  if (GST_PAD_CAPS (pad)) {
+    result = GST_PAD_CAPS (pad);
 
     GST_CAT_DEBUG (GST_CAT_CAPS,
         "using pad caps %p %" GST_PTR_FORMAT, result, result);
@@ -1665,36 +1504,30 @@ done:
 GstCaps *
 gst_pad_get_caps (GstPad * pad)
 {
-  GstRealPad *realpad;
   GstCaps *result = NULL;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  /* now we need to deal with the real/ghost stuff */
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
   GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
-      GST_DEBUG_PAD_NAME (realpad), realpad);
+      GST_DEBUG_PAD_NAME (pad), pad);
 
-  if (G_UNLIKELY (GST_RPAD_IS_IN_GETCAPS (realpad)))
+  if (G_UNLIKELY (GST_PAD_IS_IN_GETCAPS (pad)))
     goto was_dispatching;
 
-  result = gst_real_pad_get_caps_unlocked (realpad);
-  GST_UNLOCK (realpad);
+  result = gst_pad_get_caps_unlocked (pad);
+  GST_UNLOCK (pad);
 
   return result;
 
-lost_ghostpad:
-  {
-    return NULL;
-  }
 was_dispatching:
   {
     GST_CAT_DEBUG (GST_CAT_CAPS,
-        "pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (realpad));
+        "pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (pad));
     g_warning ("pad %s:%s recursively called getcaps!",
-        GST_DEBUG_PAD_NAME (realpad));
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad));
+    GST_UNLOCK (pad);
     return NULL;
   }
 }
@@ -1712,49 +1545,44 @@ was_dispatching:
 GstCaps *
 gst_pad_peer_get_caps (GstPad * pad)
 {
-  GstRealPad *realpad, *peerpad;
+  GstPad *peerpad;
   GstCaps *result = NULL;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  /* now we need to deal with the real/ghost stuff */
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
   GST_CAT_DEBUG (GST_CAT_CAPS, "get peer caps of %s:%s (%p)",
-      GST_DEBUG_PAD_NAME (realpad), realpad);
+      GST_DEBUG_PAD_NAME (pad), pad);
 
-  peerpad = GST_RPAD_PEER (realpad);
+  peerpad = GST_PAD_PEER (pad);
   if (G_UNLIKELY (peerpad == NULL))
     goto no_peer;
 
-  if (G_UNLIKELY (GST_RPAD_IS_IN_GETCAPS (peerpad)))
+  if (G_UNLIKELY (GST_PAD_IS_IN_GETCAPS (peerpad)))
     goto was_dispatching;
 
   gst_object_ref (GST_OBJECT_CAST (peerpad));
-  GST_UNLOCK (realpad);
+  GST_UNLOCK (pad);
 
-  result = gst_pad_get_caps (GST_PAD_CAST (peerpad));
+  result = gst_pad_get_caps (peerpad);
 
-  gst_object_unref (GST_OBJECT_CAST (peerpad));
+  gst_object_unref (GST_OBJECT (peerpad));
 
   return result;
 
-lost_ghostpad:
-  {
-    return NULL;
-  }
 no_peer:
   {
-    GST_UNLOCK (realpad);
+    GST_UNLOCK (pad);
     return NULL;
   }
 was_dispatching:
   {
     GST_CAT_DEBUG (GST_CAT_CAPS,
-        "pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (realpad));
+        "pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (pad));
     g_warning ("pad %s:%s recursively called getcaps!",
-        GST_DEBUG_PAD_NAME (realpad));
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad));
+    GST_UNLOCK (pad);
     return NULL;
   }
 }
@@ -1785,41 +1613,34 @@ gst_pad_fixate_caps (GstPad * pad, GstCaps * caps)
 gboolean
 gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
 {
-  GstRealPad *realpad;
   gboolean result;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
-  /* now we need to deal with the real/ghost stuff */
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
   GST_CAT_DEBUG (GST_CAT_CAPS, "pad accept caps of %s:%s (%p)",
-      GST_DEBUG_PAD_NAME (realpad), realpad);
+      GST_DEBUG_PAD_NAME (pad), pad);
 
-  if (GST_RPAD_ACCEPTCAPSFUNC (pad)) {
+  if (GST_PAD_ACCEPTCAPSFUNC (pad)) {
     /* we can call the function */
-    result = GST_RPAD_ACCEPTCAPSFUNC (realpad) (pad, caps);
+    result = GST_PAD_ACCEPTCAPSFUNC (pad) (pad, caps);
   } else {
     /* else see get the caps and see if it intersects to something
      * not empty */
     GstCaps *intersect;
     GstCaps *allowed;
 
-    allowed = gst_real_pad_get_caps_unlocked (realpad);
+    allowed = gst_pad_get_caps_unlocked (pad);
     intersect = gst_caps_intersect (allowed, caps);
     if (gst_caps_is_empty (intersect))
       result = FALSE;
     else
       result = TRUE;
   }
-  GST_UNLOCK (realpad);
+  GST_UNLOCK (pad);
 
   return result;
-
-lost_ghostpad:
-  {
-    return FALSE;
-  }
 }
 
 /**
@@ -1833,33 +1654,28 @@ lost_ghostpad:
 gboolean
 gst_pad_peer_accept_caps (GstPad * pad, GstCaps * caps)
 {
-  GstRealPad *realpad, *peerpad;
+  GstPad *peerpad;
   gboolean result;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
-  /* now we need to deal with the real/ghost stuff */
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
   GST_CAT_DEBUG (GST_CAT_CAPS, "peer accept caps of %s:%s (%p)",
-      GST_DEBUG_PAD_NAME (realpad), realpad);
+      GST_DEBUG_PAD_NAME (pad), pad);
 
-  peerpad = GST_RPAD_PEER (realpad);
+  peerpad = GST_PAD_PEER (pad);
   if (G_UNLIKELY (peerpad == NULL))
     goto no_peer;
 
-  result = gst_pad_accept_caps (GST_PAD_CAST (peerpad), caps);
-  GST_UNLOCK (realpad);
+  result = gst_pad_accept_caps (peerpad, caps);
+  GST_UNLOCK (pad);
 
   return result;
 
-lost_ghostpad:
-  {
-    return FALSE;
-  }
 no_peer:
   {
-    GST_UNLOCK (realpad);
+    GST_UNLOCK (pad);
     return TRUE;
   }
 }
@@ -1885,14 +1701,14 @@ gst_pad_set_caps (GstPad * pad, GstCaps * caps)
 {
   GstPadSetCapsFunction setcaps;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
+  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
   GST_LOCK (pad);
-  setcaps = GST_RPAD_SETCAPSFUNC (pad);
+  setcaps = GST_PAD_SETCAPSFUNC (pad);
 
   /* call setcaps function to configure the pad */
   if (setcaps != NULL) {
-    if (!GST_RPAD_IS_IN_SETCAPS (pad)) {
+    if (!GST_PAD_IS_IN_SETCAPS (pad)) {
       GST_FLAG_SET (pad, GST_PAD_IN_SETCAPS);
       GST_UNLOCK (pad);
       if (!setcaps (pad, caps))
@@ -1905,8 +1721,8 @@ gst_pad_set_caps (GstPad * pad, GstCaps * caps)
     }
   }
 
-  if (GST_RPAD_CAPS (pad))
-    gst_caps_unref (GST_RPAD_CAPS (pad));
+  if (GST_PAD_CAPS (pad))
+    gst_caps_unref (GST_PAD_CAPS (pad));
 
   if (caps)
     caps = gst_caps_ref (caps);
@@ -1938,8 +1754,8 @@ gst_pad_configure_sink (GstPad * pad, GstCaps * caps)
   GstPadSetCapsFunction setcaps;
   gboolean res;
 
-  acceptcaps = GST_RPAD_ACCEPTCAPSFUNC (pad);
-  setcaps = GST_RPAD_SETCAPSFUNC (pad);
+  acceptcaps = GST_PAD_ACCEPTCAPSFUNC (pad);
+  setcaps = GST_PAD_SETCAPSFUNC (pad);
 
   /* See if pad accepts the caps, by calling acceptcaps, only
    * needed if no setcaps function */
@@ -1968,8 +1784,8 @@ gst_pad_configure_src (GstPad * pad, GstCaps * caps)
   GstPadSetCapsFunction setcaps;
   gboolean res;
 
-  acceptcaps = GST_RPAD_ACCEPTCAPSFUNC (pad);
-  setcaps = GST_RPAD_SETCAPSFUNC (pad);
+  acceptcaps = GST_PAD_ACCEPTCAPSFUNC (pad);
+  setcaps = GST_PAD_SETCAPSFUNC (pad);
 
   /* See if pad accepts the caps, by calling acceptcaps, only
    * needed if no setcaps function */
@@ -2028,67 +1844,17 @@ gst_pad_get_pad_template_caps (GstPad * pad)
 GstPad *
 gst_pad_get_peer (GstPad * pad)
 {
-  GstRealPad *realpad;
-  GstRealPad *result;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
-  result = GST_RPAD_PEER (realpad);
-  if (result)
-    gst_object_ref (GST_OBJECT_CAST (result));
-  GST_UNLOCK (realpad);
-
-  return GST_PAD_CAST (result);
-
-lost_ghostpad:
-  {
-    return NULL;
-  }
-}
-
-/**
- * gst_pad_realize:
- * @pad: a #GstPad to realize
- *
- * If the pad is a #GstRealPad, it is simply returned, else
- * the #GstGhostPad will be dereffed to the real pad.
- *
- * After this function you always receive the real pad of
- * the provided pad.
- *
- * This function unrefs the input pad and refs the result so
- * that you can write constructs like:
- *
- *   pad = gst_pad_realize(pad)
- *
- * without having to unref the old pad.
- *
- * Returns: the real #GstPad or NULL when an old reference to a
- * ghostpad is used.
- *
- * MT safe.
- */
-GstPad *
-gst_pad_realize (GstPad * pad)
-{
-  GstRealPad *result;
+  GstPad *result;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
   GST_LOCK (pad);
-  result = GST_PAD_REALIZE (pad);
-  if (result && pad != GST_PAD_CAST (result)) {
-    gst_object_ref (GST_OBJECT_CAST (result));
-    GST_UNLOCK (pad);
-    /* no other thread could dispose this since we
-     * hold at least one ref */
-    gst_object_unref (GST_OBJECT_CAST (pad));
-  } else {
-    GST_UNLOCK (pad);
-  }
+  result = GST_PAD_PEER (pad);
+  if (result)
+    gst_object_ref (GST_OBJECT (result));
+  GST_UNLOCK (pad);
 
-  return GST_PAD_CAST (result);
+  return result;
 }
 
 /**
@@ -2111,23 +1877,23 @@ gst_pad_get_allowed_caps (GstPad * srcpad)
   GstCaps *mycaps;
   GstCaps *caps;
   GstCaps *peercaps;
-  GstRealPad *realpad, *peer;
+  GstPad *peer;
 
   g_return_val_if_fail (GST_IS_PAD (srcpad), NULL);
 
-  GST_PAD_REALIZE_AND_LOCK (srcpad, realpad, lost_ghostpad);
+  GST_LOCK (srcpad);
 
-  if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
+  if (G_UNLIKELY ((peer = GST_PAD_PEER (srcpad)) == NULL))
     goto no_peer;
 
   GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting allowed caps",
-      GST_DEBUG_PAD_NAME (realpad));
+      GST_DEBUG_PAD_NAME (srcpad));
 
   gst_object_ref (GST_OBJECT_CAST (peer));
-  GST_UNLOCK (realpad);
-  mycaps = gst_pad_get_caps (GST_PAD_CAST (realpad));
+  GST_UNLOCK (srcpad);
+  mycaps = gst_pad_get_caps (srcpad);
 
-  peercaps = gst_pad_get_caps (GST_PAD_CAST (peer));
+  peercaps = gst_pad_get_caps (peer);
   gst_object_unref (GST_OBJECT_CAST (peer));
 
   caps = gst_caps_intersect (mycaps, peercaps);
@@ -2138,16 +1904,11 @@ gst_pad_get_allowed_caps (GstPad * srcpad)
 
   return caps;
 
-lost_ghostpad:
-  {
-    GST_UNLOCK (srcpad);
-    return NULL;
-  }
 no_peer:
   {
     GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
-        GST_DEBUG_PAD_NAME (realpad));
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (srcpad));
+    GST_UNLOCK (srcpad);
 
     return NULL;
   }
@@ -2174,19 +1935,19 @@ GstCaps *
 gst_pad_get_negotiated_caps (GstPad * pad)
 {
   GstCaps *caps;
-  GstRealPad *realpad, *peer;
+  GstPad *peer;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
-  if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
+  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto no_peer;
 
   GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting negotiated caps",
-      GST_DEBUG_PAD_NAME (realpad));
+      GST_DEBUG_PAD_NAME (pad));
 
-  caps = GST_RPAD_CAPS (realpad);
+  caps = GST_PAD_CAPS (pad);
   if (caps)
     gst_caps_ref (caps);
   GST_UNLOCK (pad);
@@ -2195,16 +1956,11 @@ gst_pad_get_negotiated_caps (GstPad * pad)
 
   return caps;
 
-lost_ghostpad:
-  {
-    GST_UNLOCK (pad);
-    return NULL;
-  }
 no_peer:
   {
     GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
-        GST_DEBUG_PAD_NAME (realpad));
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad));
+    GST_UNLOCK (pad);
 
     return NULL;
   }
@@ -2219,8 +1975,8 @@ no_peer:
  * @buf: a newly allocated buffer
  *
  * Allocates a new, empty buffer optimized to push to pad @pad.  This
- * function only works if @pad is a source pad and a GST_REAL_PAD and
- * has a peer. 
+ * function only works if @pad is a source pad and has a peer. 
+ *
  * You need to check the caps of the buffer after performing this 
  * function and renegotiate to the format if needed.
  *
@@ -2238,17 +1994,17 @@ GstFlowReturn
 gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps,
     GstBuffer ** buf)
 {
-  GstRealPad *peer;
+  GstPad *peer;
   GstFlowReturn ret;
   GstPadBufferAllocFunction bufferallocfunc;
   gboolean caps_changed;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
   g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
 
   GST_LOCK (pad);
-  if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
+  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto no_peer;
 
   gst_object_ref (GST_OBJECT_CAST (peer));
@@ -2259,7 +2015,7 @@ gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps,
 
   GST_LOCK (peer);
   /* when the peer is flushing we cannot give a buffer */
-  if (G_UNLIKELY (GST_RPAD_IS_FLUSHING (peer)))
+  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (peer)))
     goto flushing;
 
   GST_CAT_DEBUG (GST_CAT_PADS,
@@ -2268,7 +2024,7 @@ gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps,
       &bufferallocfunc, GST_DEBUG_PAD_NAME (peer));
   GST_UNLOCK (peer);
 
-  ret = bufferallocfunc (GST_PAD_CAST (peer), offset, size, caps, buf);
+  ret = bufferallocfunc (peer, offset, size, caps, buf);
 
   if (G_UNLIKELY (ret != GST_FLOW_OK))
     goto peer_error;
@@ -2280,11 +2036,11 @@ do_caps:
 
   /* FIXME, move capnego this into a base class? */
   caps = GST_BUFFER_CAPS (*buf);
-  caps_changed = caps && caps != GST_RPAD_CAPS (pad);
+  caps_changed = caps && caps != GST_PAD_CAPS (pad);
   /* we got a new datatype on the pad, see if it can handle it */
   if (G_UNLIKELY (caps_changed)) {
     GST_DEBUG ("caps changed to %" GST_PTR_FORMAT, caps);
-    if (G_UNLIKELY (!gst_pad_configure_src (GST_PAD_CAST (pad), caps)))
+    if (G_UNLIKELY (!gst_pad_configure_src (pad, caps)))
       goto not_negotiated;
   }
   return ret;
@@ -2356,18 +2112,16 @@ gst_pad_get_internal_links_default (GstPad * pad)
   GstElement *parent;
   GList *parent_pads;
   GstPadDirection direction;
-  GstRealPad *rpad;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  rpad = GST_PAD_REALIZE (pad);
-  direction = rpad->direction;
+  direction = pad->direction;
 
-  parent = GST_PAD_PARENT (rpad);
+  parent = GST_PAD_PARENT (pad);
   parent_pads = parent->pads;
 
   while (parent_pads) {
-    GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data);
+    GstPad *parent_pad = GST_PAD_CAST (parent_pads->data);
 
     if (parent_pad->direction != direction) {
       res = g_list_prepend (res, parent_pad);
@@ -2395,14 +2149,11 @@ GList *
 gst_pad_get_internal_links (GstPad * pad)
 {
   GList *res = NULL;
-  GstRealPad *rpad;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  rpad = GST_PAD_REALIZE (pad);
-
-  if (GST_RPAD_INTLINKFUNC (rpad))
-    res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD_CAST (rpad));
+  if (GST_PAD_INTLINKFUNC (pad))
+    res = GST_PAD_INTLINKFUNC (pad) (pad);
 
   return res;
 }
@@ -2477,11 +2228,9 @@ gst_pad_event_default (GstPad * pad, GstEvent * event)
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_EOS:
     {
-      GstRealPad *rpad = GST_PAD_REALIZE (pad);
-
-      if (GST_RPAD_TASK (rpad)) {
-        GST_DEBUG_OBJECT (rpad, "pausing task because of eos");
-        gst_pad_pause_task (GST_PAD_CAST (rpad));
+      if (GST_PAD_TASK (pad)) {
+        GST_DEBUG_OBJECT (pad, "pausing task because of eos");
+        gst_pad_pause_task (pad);
       }
     }
     default:
@@ -2517,11 +2266,11 @@ gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
   orig = int_pads = gst_pad_get_internal_links (pad);
 
   while (int_pads) {
-    GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data);
-    GstRealPad *int_peer = GST_RPAD_PEER (int_rpad);
+    GstPad *int_pad = GST_PAD_CAST (int_pads->data);
+    GstPad *int_peer = GST_PAD_PEER (int_pad);
 
     if (int_peer) {
-      res = dispatch (GST_PAD_CAST (int_peer), data);
+      res = dispatch (int_peer, data);
       if (res)
         break;
     }
@@ -2551,22 +2300,17 @@ gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
 gboolean
 gst_pad_query (GstPad * pad, GstQuery * query)
 {
-  GstRealPad *rpad;
   GstPadQueryFunction func;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
 
-  rpad = GST_PAD_REALIZE (pad);
-
-  g_return_val_if_fail (rpad, FALSE);
-
   GST_DEBUG ("sending query %p to pad %s:%s", query, GST_DEBUG_PAD_NAME (pad));
 
-  if ((func = GST_RPAD_QUERYFUNC (rpad)) == NULL)
+  if ((func = GST_PAD_QUERYFUNC (pad)) == NULL)
     goto no_func;
 
-  return func (GST_PAD_CAST (rpad), query);
+  return func (pad, query);
 
 no_func:
   {
@@ -2592,93 +2336,6 @@ gst_pad_query_default (GstPad * pad, GstQuery * query)
   }
 }
 
-static void
-gst_real_pad_dispose (GObject * object)
-{
-  GstPad *pad;
-  GstRealPad *rpad;
-
-  pad = GST_PAD_CAST (object);
-  rpad = GST_REAL_PAD (object);
-
-  /* No linked pad can ever be disposed.
-   * It has to have a parent to be linked 
-   * and a parent would hold a reference */
-  /* FIXME: what about if g_object_dispose is explicitly called on the pad? Is
-     that legal? otherwise we could assert GST_OBJECT_PARENT (pad) == NULL as
-     well... */
-  g_assert (GST_PAD_PEER (pad) == NULL);
-
-  GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s",
-      GST_DEBUG_PAD_NAME (pad));
-
-  /* we destroy the ghostpads, because they are nothing without the real pad */
-  if (rpad->ghostpads) {
-    GList *orig, *ghostpads;
-
-    orig = ghostpads = g_list_copy (rpad->ghostpads);
-
-    while (ghostpads) {
-      GstPad *ghostpad = GST_PAD_CAST (ghostpads->data);
-
-      if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))) {
-        GstElement *parent = GST_ELEMENT (GST_OBJECT_PARENT (ghostpad));
-
-        GST_CAT_DEBUG (GST_CAT_REFCOUNTING,
-            "removing ghost pad from element '%s'", GST_OBJECT_NAME (parent));
-        gst_element_remove_pad (parent, ghostpad);
-      } else {
-        /* handle the case where we have some floating ghost pad that was never
-           added to an element */
-        g_object_set (ghostpad, "real-pad", NULL, NULL);
-      }
-      ghostpads = g_list_next (ghostpads);
-    }
-    g_list_free (orig);
-    /* as the ghost pads are removed, they remove themselves from ->ghostpads.
-       So it should be empty now. Let's assert that. */
-    g_assert (rpad->ghostpads == NULL);
-  }
-
-  /* clear the caps */
-  gst_caps_replace (&GST_RPAD_CAPS (pad), NULL);
-
-  if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
-    GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
-        GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
-
-    gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
-  }
-
-  G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
-}
-
-static void
-gst_real_pad_finalize (GObject * object)
-{
-  GstRealPad *rpad;
-
-  rpad = GST_REAL_PAD (object);
-
-  if (rpad->stream_rec_lock) {
-    g_static_rec_mutex_free (rpad->stream_rec_lock);
-    rpad->stream_rec_lock = NULL;
-  }
-  if (rpad->preroll_lock) {
-    g_mutex_free (rpad->preroll_lock);
-    g_cond_free (rpad->preroll_cond);
-    rpad->preroll_lock = NULL;
-    rpad->preroll_cond = NULL;
-  }
-  if (rpad->block_cond) {
-    g_cond_free (rpad->block_cond);
-    rpad->block_cond = NULL;
-  }
-
-  G_OBJECT_CLASS (real_pad_parent_class)->finalize (object);
-}
-
-
 #ifndef GST_DISABLE_LOADSAVE
 /* FIXME: why isn't this on a GstElement ? */
 /**
@@ -2763,19 +2420,19 @@ cleanup:
 static xmlNodePtr
 gst_pad_save_thyself (GstObject * object, xmlNodePtr parent)
 {
-  GstRealPad *realpad;
+  GstPad *pad;
   GstPad *peer;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
+  g_return_val_if_fail (GST_IS_PAD (object), NULL);
 
-  realpad = GST_REAL_PAD (object);
+  pad = GST_PAD (object);
 
   xmlNewChild (parent, NULL, (xmlChar *) "name",
-      (xmlChar *) GST_PAD_NAME (realpad));
-  if (GST_RPAD_PEER (realpad) != NULL) {
+      (xmlChar *) GST_PAD_NAME (pad));
+  if (GST_PAD_PEER (pad) != NULL) {
     gchar *content;
 
-    peer = GST_PAD_CAST (GST_RPAD_PEER (realpad));
+    peer = GST_PAD_PEER (pad);
     /* first check to see if the peer's parent's parent is the same */
     /* we just save it off */
     content = g_strdup_printf ("%s.%s",
@@ -2788,6 +2445,7 @@ gst_pad_save_thyself (GstObject * object, xmlNodePtr parent)
   return parent;
 }
 
+#if 0
 /**
  * gst_ghost_pad_save_thyself:
  * @pad: a ghost #GstPad to save.
@@ -2813,6 +2471,7 @@ gst_ghost_pad_save_thyself (GstPad * pad, xmlNodePtr parent)
 
   return self;
 }
+#endif /* 0 */
 #endif /* GST_DISABLE_LOADSAVE */
 
 /* 
@@ -2821,7 +2480,7 @@ gst_ghost_pad_save_thyself (GstPad * pad, xmlNodePtr parent)
  * MT safe.
  */
 static void
-handle_pad_block (GstRealPad * pad)
+handle_pad_block (GstPad * pad)
 {
   GstPadBlockCallback callback;
   gpointer user_data;
@@ -2836,13 +2495,13 @@ handle_pad_block (GstRealPad * pad)
   if (callback) {
     user_data = pad->block_data;
     GST_UNLOCK (pad);
-    callback (GST_PAD_CAST (pad), TRUE, user_data);
+    callback (pad, TRUE, user_data);
     GST_LOCK (pad);
   } else {
     GST_PAD_BLOCK_SIGNAL (pad);
   }
 
-  while (GST_RPAD_IS_BLOCKED (pad))
+  while (GST_PAD_IS_BLOCKED (pad))
     GST_PAD_BLOCK_WAIT (pad);
 
   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got unblocked");
@@ -2851,7 +2510,7 @@ handle_pad_block (GstRealPad * pad)
   if (callback) {
     user_data = pad->block_data;
     GST_UNLOCK (pad);
-    callback (GST_PAD_CAST (pad), FALSE, user_data);
+    callback (pad, FALSE, user_data);
     GST_LOCK (pad);
   } else {
     GST_PAD_BLOCK_SIGNAL (pad);
@@ -2869,7 +2528,7 @@ handle_pad_block (GstRealPad * pad)
  * @pad: a sink #GstPad.
  * @buffer: the #GstBuffer to send.
  *
- * Chain a buffer to @pad. The pad has to be a GstRealPad.
+ * Chain a buffer to @pad.
  *
  * Returns: a #GstFlowReturn from the pad.
  *
@@ -2883,8 +2542,8 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
   GstPadChainFunction chainfunc;
   GstFlowReturn ret;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK,
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK,
       GST_FLOW_ERROR);
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
@@ -2892,11 +2551,11 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
   GST_STREAM_LOCK (pad);
 
   GST_LOCK (pad);
-  if (G_UNLIKELY (GST_RPAD_IS_FLUSHING (pad)))
+  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
     goto flushing;
 
   caps = GST_BUFFER_CAPS (buffer);
-  caps_changed = caps && caps != GST_RPAD_CAPS (pad);
+  caps_changed = caps && caps != GST_PAD_CAPS (pad);
   GST_UNLOCK (pad);
 
   /* we got a new datatype on the pad, see if it can handle it */
@@ -2911,7 +2570,7 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
    * the data to the wrong function. This is not really a
    * problem since functions are assigned at creation time
    * and don't change that often... */
-  if (G_UNLIKELY ((chainfunc = GST_RPAD_CHAINFUNC (pad)) == NULL))
+  if (G_UNLIKELY ((chainfunc = GST_PAD_CHAINFUNC (pad)) == NULL))
     goto no_function;
 
   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
@@ -2968,26 +2627,25 @@ no_function:
 GstFlowReturn
 gst_pad_push (GstPad * pad, GstBuffer * buffer)
 {
-  GstRealPad *peer;
+  GstPad *peer;
   GstFlowReturn ret;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC,
-      GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC, GST_FLOW_ERROR);
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
 
   GST_LOCK (pad);
-  while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad)))
-    handle_pad_block (GST_REAL_PAD_CAST (pad));
+  while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
+    handle_pad_block (pad);
 
-  if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
+  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto not_linked;
 
   gst_object_ref (GST_OBJECT_CAST (peer));
   GST_UNLOCK (pad);
 
-  ret = gst_pad_chain (GST_PAD_CAST (peer), buffer);
+  ret = gst_pad_chain (peer, buffer);
 
   gst_object_unref (GST_OBJECT_CAST (peer));
 
@@ -3006,7 +2664,7 @@ not_linked:
 
 /**
  * gst_pad_check_pull_range:
- * @pad: a sink #GstRealPad.
+ * @pad: a sink #GstPad.
  *
  * Checks if a #gst_pad_pull_range() can be performed on the peer
  * source pad. This function is used by plugins that want to check
@@ -3023,17 +2681,17 @@ not_linked:
 gboolean
 gst_pad_check_pull_range (GstPad * pad)
 {
-  GstRealPad *peer;
+  GstPad *peer;
   gboolean ret;
   GstPadCheckGetRangeFunction checkgetrangefunc;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
+  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
   GST_LOCK (pad);
-  if (GST_RPAD_DIRECTION (pad) != GST_PAD_SINK)
+  if (GST_PAD_DIRECTION (pad) != GST_PAD_SINK)
     goto wrong_direction;
 
-  if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
+  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto not_connected;
 
   gst_object_ref (GST_OBJECT_CAST (peer));
@@ -3041,13 +2699,13 @@ gst_pad_check_pull_range (GstPad * pad)
 
   /* see note in above function */
   if (G_LIKELY ((checkgetrangefunc = peer->checkgetrangefunc) == NULL)) {
-    ret = GST_RPAD_GETRANGEFUNC (peer) != NULL;
+    ret = GST_PAD_GETRANGEFUNC (peer) != NULL;
   } else {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
         "calling checkgetrangefunc %s of peer pad %s:%s",
         GST_DEBUG_FUNCPTR_NAME (checkgetrangefunc), GST_DEBUG_PAD_NAME (peer));
 
-    ret = checkgetrangefunc (GST_PAD_CAST (peer));
+    ret = checkgetrangefunc (peer);
   }
 
   gst_object_unref (GST_OBJECT_CAST (peer));
@@ -3089,19 +2747,18 @@ gst_pad_get_range (GstPad * pad, guint64 offset, guint size,
   GstFlowReturn ret;
   GstPadGetRangeFunction getrangefunc;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC,
-      GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC, GST_FLOW_ERROR);
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
 
   GST_STREAM_LOCK (pad);
 
   GST_LOCK (pad);
-  if (G_UNLIKELY (GST_RPAD_IS_FLUSHING (pad)))
+  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
     goto flushing;
   GST_UNLOCK (pad);
 
-  if (G_UNLIKELY ((getrangefunc = GST_RPAD_GETRANGEFUNC (pad)) == NULL))
+  if (G_UNLIKELY ((getrangefunc = GST_PAD_GETRANGEFUNC (pad)) == NULL))
     goto no_function;
 
   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
@@ -3153,26 +2810,26 @@ GstFlowReturn
 gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
     GstBuffer ** buffer)
 {
-  GstRealPad *peer;
+  GstPad *peer;
   GstFlowReturn ret;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK,
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK,
       GST_FLOW_ERROR);
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
 
   GST_LOCK (pad);
 
-  while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad)))
-    handle_pad_block (GST_REAL_PAD_CAST (pad));
+  while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
+    handle_pad_block (pad);
 
-  if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
+  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto not_connected;
 
   gst_object_ref (GST_OBJECT_CAST (peer));
   GST_UNLOCK (pad);
 
-  ret = gst_pad_get_range (GST_PAD_CAST (peer), offset, size, buffer);
+  ret = gst_pad_get_range (peer, offset, size, buffer);
 
   gst_object_unref (GST_OBJECT_CAST (peer));
 
@@ -3204,21 +2861,21 @@ not_connected:
 gboolean
 gst_pad_push_event (GstPad * pad, GstEvent * event)
 {
-  GstRealPad *peerpad;
+  GstPad *peerpad;
   gboolean result;
 
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
+  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
   GST_LOCK (pad);
-  peerpad = GST_RPAD_PEER (pad);
+  peerpad = GST_PAD_PEER (pad);
   if (peerpad == NULL)
     goto not_linked;
 
   gst_object_ref (GST_OBJECT_CAST (peerpad));
   GST_UNLOCK (pad);
 
-  result = gst_pad_send_event (GST_PAD_CAST (peerpad), event);
+  result = gst_pad_send_event (peerpad, event);
 
   gst_object_unref (GST_OBJECT_CAST (peerpad));
 
@@ -3247,70 +2904,63 @@ gboolean
 gst_pad_send_event (GstPad * pad, GstEvent * event)
 {
   gboolean result = FALSE;
-  GstRealPad *realpad;
   GstPadEventFunction eventfunc;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
-  GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
+  GST_LOCK (pad);
 
   if (GST_EVENT_SRC (event) == NULL)
-    GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT_CAST (realpad));
+    GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (pad));
 
   GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %d on pad %s:%s",
-      GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (realpad));
+      GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH:
       GST_CAT_DEBUG (GST_CAT_EVENT, "have flush event");
       if (GST_EVENT_FLUSH_DONE (event)) {
-        GST_RPAD_UNSET_FLUSHING (realpad);
+        GST_PAD_UNSET_FLUSHING (pad);
         GST_CAT_DEBUG (GST_CAT_EVENT, "cleared flush flag");
       } else {
         /* can't even accept a flush begin event when flushing */
-        if (GST_RPAD_IS_FLUSHING (realpad))
+        if (GST_PAD_IS_FLUSHING (pad))
           goto flushing;
-        GST_RPAD_SET_FLUSHING (realpad);
+        GST_PAD_SET_FLUSHING (pad);
         GST_CAT_DEBUG (GST_CAT_EVENT, "set flush flag");
       }
       break;
     default:
-      if (GST_RPAD_IS_FLUSHING (realpad))
+      if (GST_PAD_IS_FLUSHING (pad))
         goto flushing;
       break;
   }
 
-  if ((eventfunc = GST_RPAD_EVENTFUNC (realpad)) == NULL)
+  if ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL)
     goto no_function;
 
-  gst_object_ref (GST_OBJECT_CAST (realpad));
-  GST_UNLOCK (realpad);
+  gst_object_ref (GST_OBJECT_CAST (pad));
+  GST_UNLOCK (pad);
 
-  result = eventfunc (GST_PAD_CAST (realpad), event);
+  result = eventfunc (GST_PAD_CAST (pad), event);
 
-  gst_object_unref (GST_OBJECT_CAST (realpad));
+  gst_object_unref (GST_OBJECT_CAST (pad));
 
   return result;
 
   /* ERROR handling */
-lost_ghostpad:
-  {
-    GST_CAT_DEBUG (GST_CAT_EVENT, "lost ghostpad");
-    gst_event_unref (event);
-    return FALSE;
-  }
 no_function:
   {
     g_warning ("pad %s:%s has no event handler, file a bug.",
-        GST_DEBUG_PAD_NAME (realpad));
-    GST_UNLOCK (realpad);
+        GST_DEBUG_PAD_NAME (pad));
+    GST_UNLOCK (pad);
     gst_event_unref (event);
     return FALSE;
   }
 flushing:
   {
-    GST_UNLOCK (realpad);
+    GST_UNLOCK (pad);
     GST_CAT_DEBUG (GST_CAT_EVENT, "received event on flushing pad");
     gst_event_unref (event);
     return FALSE;
@@ -3577,12 +3227,12 @@ gst_pad_start_task (GstPad * pad, GstTaskFunction func, gpointer data)
   if (sched == NULL)
     goto no_sched;
 
-  task = GST_RPAD_TASK (pad);
+  task = GST_PAD_TASK (pad);
   if (task == NULL) {
     task = gst_scheduler_create_task (sched, func, data);
     gst_task_set_lock (task, GST_STREAM_GET_LOCK (pad));
 
-    GST_RPAD_TASK (pad) = task;
+    GST_PAD_TASK (pad) = task;
   }
   GST_UNLOCK (pad);
 
@@ -3613,7 +3263,7 @@ gst_pad_pause_task (GstPad * pad)
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
   GST_LOCK (pad);
-  task = GST_RPAD_TASK (pad);
+  task = GST_PAD_TASK (pad);
   if (task == NULL)
     goto no_task;
   gst_task_pause (task);
@@ -3639,10 +3289,10 @@ gst_pad_stop_task (GstPad * pad)
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
   GST_LOCK (pad);
-  task = GST_RPAD_TASK (pad);
+  task = GST_PAD_TASK (pad);
   if (task == NULL)
     goto no_task;
-  GST_RPAD_TASK (pad) = NULL;
+  GST_PAD_TASK (pad) = NULL;
   GST_UNLOCK (pad);
 
   gst_task_stop (task);
@@ -3660,145 +3310,3 @@ no_task:
     return TRUE;
   }
 }
-
-
-/***** ghost pads *****/
-GType _gst_ghost_pad_type = 0;
-
-static void gst_ghost_pad_class_init (GstGhostPadClass * klass);
-static void gst_ghost_pad_init (GstGhostPad * pad);
-static void gst_ghost_pad_dispose (GObject * object);
-static void gst_ghost_pad_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-static void gst_ghost_pad_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-
-static GstPad *ghost_pad_parent_class = NULL;
-
-/* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
-enum
-{
-  GPAD_ARG_0,
-  GPAD_ARG_REAL_PAD
-      /* fill me */
-};
-
-GType
-gst_ghost_pad_get_type (void)
-{
-  if (!_gst_ghost_pad_type) {
-    static const GTypeInfo pad_info = {
-      sizeof (GstGhostPadClass), NULL, NULL,
-      (GClassInitFunc) gst_ghost_pad_class_init, NULL, NULL,
-      sizeof (GstGhostPad),
-      0,
-      (GInstanceInitFunc) gst_ghost_pad_init,
-      NULL
-    };
-
-    _gst_ghost_pad_type = g_type_register_static (GST_TYPE_PAD, "GstGhostPad",
-        &pad_info, 0);
-  }
-  return _gst_ghost_pad_type;
-}
-
-static void
-gst_ghost_pad_class_init (GstGhostPadClass * klass)
-{
-  GObjectClass *gobject_class;
-
-  gobject_class = (GObjectClass *) klass;
-
-  ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
-
-  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
-  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_set_property);
-  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_get_property);
-
-  g_object_class_install_property (gobject_class, GPAD_ARG_REAL_PAD,
-      g_param_spec_object ("real-pad", "Real pad",
-          "The real pad for the ghost pad", GST_TYPE_PAD, G_PARAM_READWRITE));
-}
-
-static void
-gst_ghost_pad_init (GstGhostPad * pad)
-{
-  /* zeroed by glib */
-}
-
-static void
-gst_ghost_pad_dispose (GObject * object)
-{
-  g_object_set (object, "real-pad", NULL, NULL);
-
-  G_OBJECT_CLASS (ghost_pad_parent_class)->dispose (object);
-}
-
-static void
-gst_ghost_pad_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstPad *ghostpad = (GstPad *) object;
-  GstPad *oldrealpad = (GstPad *) GST_GPAD_REALPAD (ghostpad);
-  GstPad *realpad = NULL;
-
-  switch (prop_id) {
-    case GPAD_ARG_REAL_PAD:
-      realpad = g_value_get_object (value);
-
-      if (oldrealpad) {
-        if (realpad == oldrealpad)
-          return;
-        else
-          gst_pad_remove_ghost_pad (oldrealpad, ghostpad);
-      }
-
-      if (realpad)
-        gst_pad_add_ghost_pad (realpad, ghostpad);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_ghost_pad_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  switch (prop_id) {
-    case GPAD_ARG_REAL_PAD:
-      g_value_set_object (value, GST_GPAD_REALPAD (object));
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-/**
- * gst_ghost_pad_new:
- * @name: the name of the new ghost pad.
- * @pad: the #GstPad to create a ghost pad for.
- *
- * Creates a new ghost pad associated with @pad, and named @name. If @name is
- * %NULL, a guaranteed unique name (across all ghost pads) will be assigned.
- *
- * Returns: a new ghost #GstPad, or %NULL in case of an error.
- */
-GstPad *
-gst_ghost_pad_new (const gchar * name, GstPad * pad)
-{
-  GstPad *gpad;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  gpad = g_object_new (GST_TYPE_GHOST_PAD, "name", name, "real-pad", pad, NULL);
-
-  GST_CAT_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\" for pad %s:%s",
-      GST_OBJECT_NAME (gpad), GST_DEBUG_PAD_NAME (pad));
-
-  return gpad;
-}
index ba37118..32cba9e 100644 (file)
 G_BEGIN_DECLS
 
 GST_EXPORT GType _gst_pad_type;
-GST_EXPORT GType _gst_real_pad_type;
-GST_EXPORT GType _gst_ghost_pad_type;
 
 /*
  * Pad base class
  */
 #define GST_TYPE_PAD                   (_gst_pad_type)
 #define GST_IS_PAD(obj)                        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PAD))
-#define GST_IS_PAD_FAST(obj)           (G_OBJECT_TYPE(obj) == GST_TYPE_REAL_PAD || \
-                                        G_OBJECT_TYPE(obj) == GST_TYPE_GHOST_PAD)
+#define GST_IS_PAD_FAST(obj)           (G_OBJECT_TYPE(obj) == GST_TYPE_PAD) /* necessary? */
 #define GST_IS_PAD_CLASS(klass)                (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PAD))
 #define GST_PAD(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PAD, GstPad))
 #define GST_PAD_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD, GstPadClass))
 #define GST_PAD_CAST(obj)              ((GstPad*)(obj))
 
-/* 
- * Real Pads
- */
-#define GST_TYPE_REAL_PAD              (_gst_real_pad_type)
-#define GST_IS_REAL_PAD(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_REAL_PAD))
-#define GST_IS_REAL_PAD_FAST(obj)      (G_OBJECT_TYPE(obj) == GST_TYPE_REAL_PAD)
-#define GST_IS_REAL_PAD_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_REAL_PAD))
-#define GST_REAL_PAD(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_REAL_PAD, GstRealPad))
-#define GST_REAL_PAD_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_REAL_PAD, GstRealPadClass))
-#define GST_REAL_PAD_CAST(obj)         ((GstRealPad*)(obj))
-
-/*
- * Ghost Pads
- */
-#define GST_TYPE_GHOST_PAD             (_gst_ghost_pad_type)
-#define GST_IS_GHOST_PAD(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GHOST_PAD))
-#define GST_IS_GHOST_PAD_FAST(obj)     (G_OBJECT_TYPE(obj) == GST_TYPE_GHOST_PAD)
-#define GST_IS_GHOST_PAD_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD))
-#define GST_GHOST_PAD(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad))
-#define GST_GHOST_PAD_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass))
-#define GST_GHOST_PAD_CAST(obj)                ((GstGhostPad*)(obj))
-
 
-/*typedef struct _GstPad GstPad; */
+/* why are these in gsttypes, again? */
+/*typedef struct _GstPad GstPad;*/
 /*typedef struct _GstPadClass GstPadClass;*/
-typedef struct _GstRealPad GstRealPad;
-typedef struct _GstRealPadClass GstRealPadClass;
-typedef struct _GstGhostPad GstGhostPad;
-typedef struct _GstGhostPadClass GstGhostPadClass;
 /*typedef struct _GstPadTemplate GstPadTemplate;*/
 /*typedef struct _GstPadTemplateClass GstPadTemplateClass;*/
 typedef struct _GstStaticPadTemplate GstStaticPadTemplate;
-typedef struct _GstPadLink GstPadLink;
 
 typedef enum {
   GST_PAD_LINK_NOSCHED          = -5,  /* pads cannot cooperate in scheduling */
@@ -119,17 +90,6 @@ typedef enum {
 
 #define GST_PAD_MODE_ACTIVATE(mode) ((mode) != GST_ACTIVATE_NONE)
 
-/* convenience functions */
-#ifdef G_HAVE_ISO_VARARGS
-#define GST_PAD_QUERY_TYPE_FUNCTION(functionname, ...)  GST_QUERY_TYPE_FUNCTION (GstPad *, functionname, __VA_ARGS__);
-#define GST_PAD_FORMATS_FUNCTION(functionname, ...)    GST_FORMATS_FUNCTION (GstPad *, functionname, __VA_ARGS__);
-#define GST_PAD_EVENT_MASK_FUNCTION(functionname, ...) GST_EVENT_MASK_FUNCTION (GstPad *, functionname, __VA_ARGS__);
-#elif defined(G_HAVE_GNUC_VARARGS)
-#define GST_PAD_QUERY_TYPE_FUNCTION(functionname, a...) GST_QUERY_TYPE_FUNCTION (GstPad *, functionname, a);
-#define GST_PAD_FORMATS_FUNCTION(functionname, a...)   GST_FORMATS_FUNCTION (GstPad *, functionname, a);
-#define GST_PAD_EVENT_MASK_FUNCTION(functionname, a...) GST_EVENT_MASK_FUNCTION (GstPad *, functionname, a);
-#endif
-
  
 /* pad states */
 typedef gboolean               (*GstPadActivateFunction)       (GstPad *pad, GstActivateMode mode);
@@ -189,18 +149,6 @@ struct _GstPad {
 
   GstPadTemplate       *padtemplate;   /* the template for this pad */
 
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstPadClass {
-  GstObjectClass parent_class;
-
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstRealPad {
-  GstPad                        pad;
-
   /* direction cannot change after creating the pad */
   GstPadDirection               direction;
 
@@ -230,7 +178,7 @@ struct _GstRealPad {
   /* pad link */
   GstPadLinkFunction            linkfunc;
   GstPadUnlinkFunction                  unlinkfunc;
-  GstRealPad                   *peer;
+  GstPad                       *peer;
 
   gpointer                      sched_private;
 
@@ -243,10 +191,6 @@ struct _GstRealPad {
 
   GstActivateMode               mode;
 
-  /* ghostpads */
-  GList                        *ghostpads;
-  guint32                       ghostpads_cookie;
-
   /* generic query method */
   GstPadQueryTypeFunction       querytypefunc;
   GstPadQueryFunction           queryfunc;
@@ -262,8 +206,8 @@ struct _GstRealPad {
   gpointer _gst_reserved[GST_PADDING];
 };
 
-struct _GstRealPadClass {
-  GstPadClass  parent_class;
+struct _GstPadClass {
+  GstObjectClass       parent_class;
 
   /* signal callbacks */
   void         (*linked)               (GstPad *pad, GstPad *peer);
@@ -274,20 +218,6 @@ struct _GstRealPadClass {
   gpointer _gst_reserved[GST_PADDING];
 };
 
-struct _GstGhostPad {
-  GstPad pad;
-
-  GstRealPad *realpad;
-
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstGhostPadClass {
-  GstPadClass parent_class;
-
-  gpointer _gst_reserved[GST_PADDING];
-};
-
 
 /***** helper macros *****/
 /* GstPad */
@@ -295,87 +225,65 @@ struct _GstGhostPadClass {
 #define GST_PAD_PARENT(pad)            (GST_ELEMENT_CAST(GST_OBJECT_PARENT(pad)))
 #define GST_PAD_ELEMENT_PRIVATE(pad)   (GST_PAD_CAST(pad)->element_private)
 #define GST_PAD_PAD_TEMPLATE(pad)      (GST_PAD_CAST(pad)->padtemplate)
-
-/* GstRealPad */
-#define GST_RPAD_DIRECTION(pad)                (GST_REAL_PAD_CAST(pad)->direction)
-#define GST_RPAD_TASK(pad)             (GST_REAL_PAD_CAST(pad)->task)
-#define GST_RPAD_ACTIVATEFUNC(pad)     (GST_REAL_PAD_CAST(pad)->activatefunc)
-#define GST_RPAD_LOOPFUNC(pad)         (GST_REAL_PAD_CAST(pad)->loopfunc)
-#define GST_RPAD_CHAINFUNC(pad)                (GST_REAL_PAD_CAST(pad)->chainfunc)
-#define GST_RPAD_CHECKGETRANGEFUNC(pad)        (GST_REAL_PAD_CAST(pad)->checkgetrangefunc)
-#define GST_RPAD_GETRANGEFUNC(pad)     (GST_REAL_PAD_CAST(pad)->getrangefunc)
-#define GST_RPAD_EVENTFUNC(pad)                (GST_REAL_PAD_CAST(pad)->eventfunc)
-#define GST_RPAD_ACTIVATE_MODE(pad)    (GST_REAL_PAD_CAST(pad)->mode)
-#define GST_RPAD_QUERYTYPEFUNC(pad)    (GST_REAL_PAD_CAST(pad)->querytypefunc)
-#define GST_RPAD_QUERYFUNC(pad)                (GST_REAL_PAD_CAST(pad)->queryfunc)
-#define GST_RPAD_INTLINKFUNC(pad)      (GST_REAL_PAD_CAST(pad)->intlinkfunc)
-
-#define GST_RPAD_PEER(pad)             (GST_REAL_PAD_CAST(pad)->peer)
-#define GST_RPAD_LINKFUNC(pad)         (GST_REAL_PAD_CAST(pad)->linkfunc)
-#define GST_RPAD_UNLINKFUNC(pad)       (GST_REAL_PAD_CAST(pad)->unlinkfunc)
-
-#define GST_RPAD_CAPS(pad)             (GST_REAL_PAD_CAST(pad)->caps)
-#define GST_RPAD_GETCAPSFUNC(pad)      (GST_REAL_PAD_CAST(pad)->getcapsfunc)
-#define GST_RPAD_SETCAPSFUNC(pad)      (GST_REAL_PAD_CAST(pad)->setcapsfunc)
-#define GST_RPAD_ACCEPTCAPSFUNC(pad)   (GST_REAL_PAD_CAST(pad)->acceptcapsfunc)
-#define GST_RPAD_FIXATECAPSFUNC(pad)   (GST_REAL_PAD_CAST(pad)->fixatecapsfunc)
-
-#define GST_RPAD_BUFFERALLOCFUNC(pad)  (GST_REAL_PAD_CAST(pad)->bufferallocfunc)
-
-#define GST_RPAD_IS_LINKED(pad)                (GST_RPAD_PEER(pad) != NULL)
-#define GST_RPAD_IS_BLOCKED(pad)       (GST_FLAG_IS_SET (pad, GST_PAD_BLOCKED))
-#define GST_RPAD_IS_FLUSHING(pad)      (GST_FLAG_IS_SET (pad, GST_PAD_FLUSHING))
-#define GST_RPAD_IS_IN_GETCAPS(pad)    (GST_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS))
-#define GST_RPAD_IS_IN_SETCAPS(pad)    (GST_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS))
-#define GST_RPAD_IS_USABLE(pad)                (GST_RPAD_IS_LINKED (pad) && \
-                                        !GST_RPAD_IS_FLUSHING(pad) && !GST_RPAD_IS_FLUSHING(GST_RPAD_PEER (pad)))
-#define GST_RPAD_IS_SRC(pad)           (GST_RPAD_DIRECTION(pad) == GST_PAD_SRC)
-#define GST_RPAD_IS_SINK(pad)          (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK)
-
-#define GST_RPAD_SET_FLUSHING(pad)     (GST_FLAG_SET (pad, GST_PAD_FLUSHING))
-#define GST_RPAD_UNSET_FLUSHING(pad)   (GST_FLAG_UNSET (pad, GST_PAD_FLUSHING))
-
-#define GST_STREAM_GET_LOCK(pad)        (GST_PAD_REALIZE(pad)->stream_rec_lock)
+#define GST_PAD_DIRECTION(pad)         (GST_PAD_CAST(pad)->direction)
+#define GST_PAD_TASK(pad)              (GST_PAD_CAST(pad)->task)
+#define GST_PAD_ACTIVATE_MODE(pad)     (GST_PAD_CAST(pad)->mode)
+
+#define GST_PAD_ACTIVATEFUNC(pad)      (GST_PAD_CAST(pad)->activatefunc)
+#define GST_PAD_LOOPFUNC(pad)          (GST_PAD_CAST(pad)->loopfunc)
+#define GST_PAD_CHAINFUNC(pad)         (GST_PAD_CAST(pad)->chainfunc)
+#define GST_PAD_CHECKGETRANGEFUNC(pad) (GST_PAD_CAST(pad)->checkgetrangefunc)
+#define GST_PAD_GETRANGEFUNC(pad)      (GST_PAD_CAST(pad)->getrangefunc)
+#define GST_PAD_EVENTFUNC(pad)         (GST_PAD_CAST(pad)->eventfunc)
+#define GST_PAD_QUERYTYPEFUNC(pad)     (GST_PAD_CAST(pad)->querytypefunc)
+#define GST_PAD_QUERYFUNC(pad)         (GST_PAD_CAST(pad)->queryfunc)
+#define GST_PAD_INTLINKFUNC(pad)       (GST_PAD_CAST(pad)->intlinkfunc)
+
+#define GST_PAD_PEER(pad)              (GST_PAD_CAST(pad)->peer)
+#define GST_PAD_LINKFUNC(pad)          (GST_PAD_CAST(pad)->linkfunc)
+#define GST_PAD_UNLINKFUNC(pad)                (GST_PAD_CAST(pad)->unlinkfunc)
+
+#define GST_PAD_CAPS(pad)              (GST_PAD_CAST(pad)->caps)
+#define GST_PAD_GETCAPSFUNC(pad)       (GST_PAD_CAST(pad)->getcapsfunc)
+#define GST_PAD_SETCAPSFUNC(pad)       (GST_PAD_CAST(pad)->setcapsfunc)
+#define GST_PAD_ACCEPTCAPSFUNC(pad)    (GST_PAD_CAST(pad)->acceptcapsfunc)
+#define GST_PAD_FIXATECAPSFUNC(pad)    (GST_PAD_CAST(pad)->fixatecapsfunc)
+
+#define GST_PAD_BUFFERALLOCFUNC(pad)   (GST_PAD_CAST(pad)->bufferallocfunc)
+
+#define GST_PAD_IS_LINKED(pad)         (GST_PAD_PEER(pad) != NULL)
+#define GST_PAD_IS_BLOCKED(pad)        (GST_FLAG_IS_SET (pad, GST_PAD_BLOCKED))
+#define GST_PAD_IS_FLUSHING(pad)       (GST_FLAG_IS_SET (pad, GST_PAD_FLUSHING))
+#define GST_PAD_IS_IN_GETCAPS(pad)     (GST_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS))
+#define GST_PAD_IS_IN_SETCAPS(pad)     (GST_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS))
+#define GST_PAD_IS_USABLE(pad)         (GST_PAD_IS_LINKED (pad) && \
+                                        !GST_PAD_IS_FLUSHING(pad) && !GST_PAD_IS_FLUSHING(GST_PAD_PEER (pad)))
+#define GST_PAD_IS_SRC(pad)            (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
+#define GST_PAD_IS_SINK(pad)           (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
+
+#define GST_PAD_SET_FLUSHING(pad)      (GST_FLAG_SET (pad, GST_PAD_FLUSHING))
+#define GST_PAD_UNSET_FLUSHING(pad)    (GST_FLAG_UNSET (pad, GST_PAD_FLUSHING))
+
+#define GST_STREAM_GET_LOCK(pad)        (GST_PAD_CAST(pad)->stream_rec_lock)
 #define GST_STREAM_LOCK(pad)            (g_static_rec_mutex_lock(GST_STREAM_GET_LOCK(pad)))
 #define GST_STREAM_TRYLOCK(pad)         (g_static_rec_mutex_trylock(GST_STREAM_GET_LOCK(pad)))
 #define GST_STREAM_UNLOCK(pad)          (g_static_rec_mutex_unlock(GST_STREAM_GET_LOCK(pad)))
 
-#define GST_PREROLL_GET_LOCK(pad)       (GST_PAD_REALIZE(pad)->preroll_lock)
+#define GST_PREROLL_GET_LOCK(pad)       (GST_PAD_CAST(pad)->preroll_lock)
 #define GST_PREROLL_LOCK(pad)           (g_mutex_lock(GST_PREROLL_GET_LOCK(pad)))
 #define GST_PREROLL_TRYLOCK(pad)        (g_mutex_trylock(GST_PREROLL_GET_LOCK(pad)))
 #define GST_PREROLL_UNLOCK(pad)         (g_mutex_unlock(GST_PREROLL_GET_LOCK(pad)))
-#define GST_PREROLL_GET_COND(pad)       (GST_PAD_REALIZE(pad)->preroll_cond)
+#define GST_PREROLL_GET_COND(pad)       (GST_PAD_CAST(pad)->preroll_cond)
 #define GST_PREROLL_WAIT(pad)           g_cond_wait (GST_PREROLL_GET_COND (pad), GST_PREROLL_GET_LOCK (pad))
 #define GST_PREROLL_TIMED_WAIT(pad, timeval) g_cond_timed_wait (GST_PREROLL_GET_COND (pad), GST_PREROLL_GET_LOCK (pad),\
                                             timeval)
 #define GST_PREROLL_SIGNAL(pad)         g_cond_signal (GST_PREROLL_GET_COND (pad));
 #define GST_PREROLL_BROADCAST(pad)      g_cond_broadcast (GST_PREROLL_GET_COND (pad));
 
-#define GST_PAD_BLOCK_GET_COND(pad)     (GST_PAD_REALIZE(pad)->block_cond)
+#define GST_PAD_BLOCK_GET_COND(pad)     (GST_PAD_CAST(pad)->block_cond)
 #define GST_PAD_BLOCK_WAIT(pad)         (g_cond_wait(GST_PAD_BLOCK_GET_COND (pad), GST_GET_LOCK (pad)))
 #define GST_PAD_BLOCK_SIGNAL(pad)       (g_cond_signal(GST_PAD_BLOCK_GET_COND (pad)))
 
-/* GstGhostPad */
-#define GST_GPAD_REALPAD(pad)          (((GstGhostPad *)(pad))->realpad)
-
-/* Generic, be VERY carefull with these macros as the ghostpad could be lost */
-#define GST_PAD_REALIZE(pad)           (GST_IS_REAL_PAD(pad) ? ((GstRealPad *)(pad)) : GST_GPAD_REALPAD(pad))
-#define GST_PAD_DIRECTION(pad)         GST_RPAD_DIRECTION(GST_PAD_REALIZE(pad))
-#define GST_PAD_CAPS(pad)              GST_RPAD_CAPS(GST_PAD_REALIZE (pad))
-#define GST_PAD_PEER(pad)              GST_PAD_CAST(GST_RPAD_PEER(GST_PAD_REALIZE(pad)))
-
-#define GST_PAD_TASK(pad)              GST_RPAD_TASK(pad)
-
-/* Some check functions (unused?) */
-#define GST_PAD_IS_LINKED(pad)         (GST_RPAD_IS_LINKED(GST_PAD_REALIZE(pad)))
-#define GST_PAD_IS_BLOCKED(pad)                (GST_RPAD_IS_BLOCKED(GST_PAD_REALIZE(pad)))
-#define GST_PAD_IS_FLUSHING(pad)       (GST_RPAD_IS_FLUSHING(GST_PAD_REALIZE(pad)))
-#define GST_PAD_IS_IN_GETCAPS(pad)     (GST_RPAD_IS_IN_GETCAPS(GST_PAD_REALIZE(pad)))
-#define GST_PAD_IS_IN_SETCAPS(pad)     (GST_RPAD_IS_IN_SETCAPS(GST_PAD_REALIZE(pad)))
-#define GST_PAD_IS_USABLE(pad)         (GST_RPAD_IS_USABLE(GST_PAD_REALIZE(pad)))
-#define GST_PAD_IS_SRC(pad)            (GST_RPAD_IS_SRC(GST_PAD_REALIZE(pad)))
-#define GST_PAD_IS_SINK(pad)           (GST_RPAD_IS_SINK(GST_PAD_REALIZE(pad)))
-
 /***** PadTemplate *****/
 #define GST_TYPE_PAD_TEMPLATE          (gst_pad_template_get_type ())
 #define GST_PAD_TEMPLATE(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PAD_TEMPLATE,GstPadTemplate))
@@ -439,21 +347,13 @@ struct _GstStaticPadTemplate {
 
 
 GType                  gst_pad_get_type                        (void);
-GType                  gst_real_pad_get_type                   (void);
-GType                  gst_ghost_pad_get_type                  (void);
 
 /* creating pads */
 GstPad*                        gst_pad_new                             (const gchar *name, GstPadDirection direction);
 GstPad*                        gst_pad_new_from_template               (GstPadTemplate *templ, const gchar *name);
-GstPad*                        gst_pad_custom_new                      (GType type, const gchar *name, GstPadDirection direction);
-GstPad*                        gst_pad_custom_new_from_template        (GType type, GstPadTemplate *templ, const gchar *name);
-
-#define                 gst_pad_get_name(pad)                  gst_object_get_name(GST_OBJECT(pad))
-#define                 gst_pad_set_name(pad,name)             gst_object_set_name(GST_OBJECT(pad),name)
-#define                 gst_pad_get_parent(pad)                GST_ELEMENT(gst_object_get_parent(GST_OBJECT(pad)))
-#define                 gst_pad_set_parent(pad,parent)         gst_object_set_parent(GST_OBJECT(pad),parent)
-GstElement*            gst_pad_get_real_parent                 (GstPad *pad);
 
+#define gst_pad_get_name(pad) gst_object_get_name (GST_OBJECT_CAST (pad))
+GstElement*            gst_pad_get_parent                      (GstPad *pad);
 
 GstPadDirection                gst_pad_get_direction                   (GstPad *pad);
 
@@ -491,7 +391,6 @@ gboolean            gst_pad_unlink                          (GstPad *srcpad, GstPad *sinkpad);
 gboolean               gst_pad_is_linked                       (GstPad *pad);
 
 GstPad*                        gst_pad_get_peer                        (GstPad *pad);
-GstPad*                        gst_pad_realize                         (GstPad *pad);
 
 /* capsnego functions */
 void                   gst_pad_set_getcaps_function            (GstPad *pad, GstPadGetCapsFunction getcaps);
@@ -554,20 +453,16 @@ gboolean          gst_pad_query_default                   (GstPad *pad, GstQuery *query);
 gboolean               gst_pad_dispatcher                      (GstPad *pad, GstPadDispatcherFunction dispatch,
                                                                 gpointer data);
 /* probes */
-#define                        gst_pad_add_probe(pad, probe) \
-                       (gst_probe_dispatcher_add_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe))
-#define                        gst_pad_remove_probe(pad, probe) \
-                       (gst_probe_dispatcher_remove_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe))
+#define                        gst_pad_add_probe(pad, probe) \
+                       (gst_probe_dispatcher_add_probe (&(GST_PAD_CAST (pad)->probedisp), probe))
+#define                        gst_pad_remove_probe(pad, probe) \
+                       (gst_probe_dispatcher_remove_probe (&(GST_PAD_CAST (pad)->probedisp), probe))
 
 #ifndef GST_DISABLE_LOADSAVE
 void                   gst_pad_load_and_link                   (xmlNodePtr self, GstObject *parent);
 #endif
 
 
-/* ghostpads */
-GstPad*                        gst_ghost_pad_new                       (const gchar *name, GstPad *pad);
-
-
 /* templates and factories */
 GType                  gst_pad_template_get_type               (void);
 
@@ -579,11 +474,6 @@ GstPadTemplate *   gst_static_pad_template_get             (GstStaticPadTemplate *
 GstCaps*               gst_static_pad_template_get_caps        (GstStaticPadTemplate *templ);
 GstCaps*               gst_pad_template_get_caps               (GstPadTemplate *templ);
 
-#ifndef GST_DISABLE_LOADSAVE
-xmlNodePtr              gst_ghost_pad_save_thyself             (GstPad *pad,
-                                                                xmlNodePtr parent);
-#endif
-
 
 G_END_DECLS
 
index 187e7c5..babe991 100644 (file)
@@ -405,8 +405,8 @@ gst_queue_link_src (GstPad * pad, GstPad * peer)
   GstPadLinkReturn result = GST_PAD_LINK_OK;
 
   /* FIXME, see if we need to push or get pulled */
-  if (GST_RPAD_LINKFUNC (peer))
-    result = GST_RPAD_LINKFUNC (peer) (peer, pad);
+  if (GST_PAD_LINKFUNC (peer))
+    result = GST_PAD_LINKFUNC (peer) (peer, pad);
 
   return result;
 }
@@ -733,11 +733,11 @@ restart:
     result = gst_pad_push (pad, GST_BUFFER (data));
     GST_QUEUE_MUTEX_LOCK;
     if (result != GST_FLOW_OK) {
-      gst_task_pause (GST_RPAD_TASK (queue->srcpad));
+      gst_task_pause (GST_PAD_TASK (queue->srcpad));
     }
   } else {
     if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) {
-      gst_task_pause (GST_RPAD_TASK (queue->srcpad));
+      gst_task_pause (GST_PAD_TASK (queue->srcpad));
       restart = FALSE;
     }
     GST_QUEUE_MUTEX_UNLOCK;
index be1b064..6dfc102 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include "gst_private.h"
+#include "gstghostpad.h"
 #include "gstutils.h"
 #include "gsturitype.h"
 #include "gstinfo.h"
@@ -301,11 +302,9 @@ string_append_indent (GString * str, gint count)
 void
 gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
 {
-  GstRealPad *realpad;
   GstCaps *caps;
 
-  realpad = GST_PAD_REALIZE (pad);
-  caps = realpad->caps;
+  caps = pad->caps;
 
   if (!caps) {
     string_append_indent (buf, indent);
@@ -606,10 +605,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
       "finding pad in %s compatible with %s:%s",
       GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad));
 
-  /* let's use the real pad */
-  pad = (GstPad *) GST_PAD_REALIZE (pad);
-  g_return_val_if_fail (pad != NULL, NULL);
-  g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
+  g_return_val_if_fail (GST_PAD_PEER (pad) == NULL, NULL);
 
   done = FALSE;
   /* try to get an existing unlinked pad */
@@ -808,19 +804,8 @@ ghost_up (GstElement * e, GstPad * pad)
   static gint ghost_pad_index = 0;
   GstPad *gpad;
   gchar *name;
-  GList *gpads;
   GstObject *parent = GST_OBJECT_PARENT (e);
 
-  /* Check if the pad already has a ghost on the element */
-  for (gpads = g_list_first (GST_PAD_REALIZE (pad)->ghostpads); gpads != NULL;
-      gpads = g_list_next (gpads)) {
-    if (GST_OBJECT_PARENT (GST_PAD (gpads->data)) == parent) {
-      GST_DEBUG ("Found existing ghost pad of %s on element %s\n",
-          GST_OBJECT_NAME (pad), GST_OBJECT_NAME (parent));
-      return GST_PAD (gpads->data);
-    }
-  }
-
   name = g_strdup_printf ("ghost%d", ghost_pad_index++);
   gpad = gst_ghost_pad_new (name, pad);
   g_free (name);
@@ -982,7 +967,7 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
   } else {
     GST_LOCK (src);
     srcpads = GST_ELEMENT_PADS (src);
-    srcpad = srcpads ? (GstPad *) GST_PAD_REALIZE (srcpads->data) : NULL;
+    srcpad = srcpads ? GST_PAD_CAST (srcpads->data) : NULL;
     if (srcpad)
       gst_object_ref (GST_OBJECT (srcpad));
     GST_UNLOCK (src);
@@ -1011,7 +996,7 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
   } else {
     GST_LOCK (dest);
     destpads = GST_ELEMENT_PADS (dest);
-    destpad = destpads ? (GstPad *) GST_PAD_REALIZE (destpads->data) : NULL;
+    destpad = destpads ? GST_PAD_CAST (destpads->data) : NULL;
     if (destpad)
       gst_object_ref (GST_OBJECT (destpad));
     GST_UNLOCK (dest);
@@ -1045,7 +1030,6 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
           gst_object_ref (GST_OBJECT (temp));
         } else {
           temp = gst_element_get_compatible_pad (dest, srcpad, NULL);
-          gst_object_ref (GST_OBJECT (temp));
         }
 
         if (temp && pad_link_maybe_ghosting (srcpad, temp)) {
@@ -1057,13 +1041,17 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
           gst_object_unref (GST_OBJECT (temp));
           return TRUE;
         }
+
+        if (temp) {
+          gst_object_unref (GST_OBJECT (temp));
+        }
       }
       /* find a better way for this mess */
       if (srcpads) {
         srcpads = g_list_next (srcpads);
         if (srcpads) {
           gst_object_unref (GST_OBJECT (srcpad));
-          srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
+          srcpad = GST_PAD_CAST (srcpads->data);
           gst_object_ref (GST_OBJECT (srcpad));
         }
       }
@@ -1099,12 +1087,15 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
             gst_object_unref (GST_OBJECT (srcpad));
           return TRUE;
         }
+        if (temp) {
+          gst_object_unref (GST_OBJECT (temp));
+        }
       }
       if (destpads) {
         destpads = g_list_next (destpads);
         if (destpads) {
           gst_object_unref (GST_OBJECT (destpad));
-          destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
+          destpad = GST_PAD_CAST (destpads->data);
           gst_object_ref (GST_OBJECT (destpad));
         }
       }
@@ -1315,8 +1306,7 @@ gst_element_unlink (GstElement * src, GstElement * dest)
       {
         GstPad *pad = GST_PAD_CAST (data);
 
-        /* we only care about real src pads */
-        if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) {
+        if (GST_PAD_IS_SRC (pad)) {
           GstPad *peerpad = gst_pad_get_peer (pad);
 
           /* see if the pad is connected and is really a pad
@@ -1411,65 +1401,50 @@ gst_element_query_convert (GstElement * element, GstFormat src_format,
 gboolean
 gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
 {
-  GstRealPad *realsrc, *realsink;
-
   /* FIXME This function is gross.  It's almost a direct copy of
    * gst_pad_link_filtered().  Any decent programmer would attempt
    * to merge the two functions, which I will do some day. --ds
    */
 
   /* generic checks */
-  g_return_val_if_fail (srcpad != NULL, FALSE);
   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
-  g_return_val_if_fail (sinkpad != NULL, FALSE);
   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
 
   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
 
-  /* now we need to deal with the real/ghost stuff */
-  realsrc = GST_PAD_REALIZE (srcpad);
-  realsink = GST_PAD_REALIZE (sinkpad);
-
-  if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
-    GST_CAT_INFO (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
-        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
-  }
   /* FIXME: shouldn't we convert this to g_return_val_if_fail? */
-  if (GST_RPAD_PEER (realsrc) != NULL) {
-    GST_CAT_INFO (GST_CAT_PADS, "Real source pad %s:%s has a peer, failed",
-        GST_DEBUG_PAD_NAME (realsrc));
+  if (GST_PAD_PEER (srcpad) != NULL) {
+    GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed",
+        GST_DEBUG_PAD_NAME (srcpad));
     return FALSE;
   }
-  if (GST_RPAD_PEER (realsink) != NULL) {
-    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has a peer, failed",
-        GST_DEBUG_PAD_NAME (realsink));
+  if (GST_PAD_PEER (sinkpad) != NULL) {
+    GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed",
+        GST_DEBUG_PAD_NAME (sinkpad));
     return FALSE;
   }
-  if (!GST_PAD_IS_SRC (realsrc)) {
-    GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s is not source pad, failed",
-        GST_DEBUG_PAD_NAME (realsrc));
+  if (!GST_PAD_IS_SRC (srcpad)) {
+    GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed",
+        GST_DEBUG_PAD_NAME (srcpad));
     return FALSE;
   }
-  if (!GST_PAD_IS_SINK (realsink)) {
-    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s is not sink pad, failed",
-        GST_DEBUG_PAD_NAME (realsink));
+  if (!GST_PAD_IS_SINK (sinkpad)) {
+    GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed",
+        GST_DEBUG_PAD_NAME (sinkpad));
     return FALSE;
   }
-  if (GST_PAD_PARENT (realsrc) == NULL) {
-    GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
-        GST_DEBUG_PAD_NAME (realsrc));
+  if (GST_PAD_PARENT (srcpad) == NULL) {
+    GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed",
+        GST_DEBUG_PAD_NAME (srcpad));
     return FALSE;
   }
-  if (GST_PAD_PARENT (realsink) == NULL) {
-    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has no parent, failed",
-        GST_DEBUG_PAD_NAME (realsrc));
+  if (GST_PAD_PARENT (sinkpad) == NULL) {
+    GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed",
+        GST_DEBUG_PAD_NAME (srcpad));
     return FALSE;
   }
 
-  g_return_val_if_fail (realsrc != NULL, GST_PAD_LINK_REFUSED);
-  g_return_val_if_fail (realsink != NULL, GST_PAD_LINK_REFUSED);
-
   return TRUE;
 }
 
@@ -1502,14 +1477,11 @@ GstCaps *
 gst_pad_get_fixed_caps_func (GstPad * pad)
 {
   GstCaps *result;
-  GstRealPad *realpad;
-
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL);
 
-  realpad = GST_REAL_PAD_CAST (pad);
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  if (GST_RPAD_CAPS (realpad)) {
-    result = GST_RPAD_CAPS (realpad);
+  if (GST_PAD_CAPS (pad)) {
+    result = GST_PAD_CAPS (pad);
 
     GST_CAT_DEBUG (GST_CAT_CAPS,
         "using pad caps %p %" GST_PTR_FORMAT, result, result);
@@ -1517,8 +1489,8 @@ gst_pad_get_fixed_caps_func (GstPad * pad)
     result = gst_caps_ref (result);
     goto done;
   }
-  if (GST_PAD_PAD_TEMPLATE (realpad)) {
-    GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad);
+  if (GST_PAD_PAD_TEMPLATE (pad)) {
+    GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
 
     result = GST_PAD_TEMPLATE_CAPS (templ);
     GST_CAT_DEBUG (GST_CAT_CAPS,
index a7f003f..1e5562d 100644 (file)
@@ -313,7 +313,6 @@ gst_parse_element_lock (GstElement *element, gboolean lock)
       {
         GstPad *pad = GST_PAD_CAST (data);
 
-       pad = gst_pad_realize (pad);
         if (GST_PAD_IS_SINK (pad) && GST_PAD_PEER (pad) &&
             !gst_element_is_locked_state (GST_PAD_PARENT (GST_PAD_PEER (pad)))) {
           unlocked_peer = TRUE;
@@ -355,7 +354,7 @@ gst_parse_element_lock (GstElement *element, gboolean lock)
   /* check if there are other pads to (un)lock */
   walk = (GList *) element->pads;
   for  (; walk; walk = walk->next) {
-    pad = (GstPad *) GST_PAD_REALIZE (walk->data);
+    pad = GST_PAD_CAST (walk->data);
     if (GST_PAD_IS_SRC (pad) && GST_PAD_PEER (pad)) {
       GstElement *next = GST_ELEMENT (GST_OBJECT_PARENT (GST_PAD_PEER (pad)));
       if (gst_element_is_locked_state (next) != lock)
index c06c9a3..e714005 100644 (file)
@@ -241,7 +241,7 @@ gst_basesink_init (GstBaseSink * basesink, gpointer g_class)
   gst_element_add_pad (GST_ELEMENT (basesink), basesink->sinkpad);
 
   basesink->pad_mode = GST_ACTIVATE_NONE;
-  GST_RPAD_TASK (basesink->sinkpad) = NULL;
+  GST_PAD_TASK (basesink->sinkpad) = NULL;
   basesink->preroll_queue = g_queue_new ();
 
   GST_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
@@ -476,7 +476,7 @@ gst_basesink_finish_preroll (GstBaseSink * basesink, GstPad * pad,
   gst_basesink_preroll_queue_push (basesink, pad, buffer);
 
   GST_LOCK (pad);
-  flushing = GST_RPAD_IS_FLUSHING (pad);
+  flushing = GST_PAD_IS_FLUSHING (pad);
   GST_UNLOCK (pad);
   if (flushing)
     goto flushing;
index ecb6f9d..d0edfba 100644 (file)
@@ -64,7 +64,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
   }
 
   buffer = NULL;
-  ret = GST_RPAD_GETRANGEFUNC (src) (src, offset, size, &buffer);
+  ret = GST_PAD_GETRANGEFUNC (src) (src, offset, size, &buffer);
 
   if (find->buffer) {
     gst_buffer_unref (find->buffer);
index 187e7c5..babe991 100644 (file)
@@ -405,8 +405,8 @@ gst_queue_link_src (GstPad * pad, GstPad * peer)
   GstPadLinkReturn result = GST_PAD_LINK_OK;
 
   /* FIXME, see if we need to push or get pulled */
-  if (GST_RPAD_LINKFUNC (peer))
-    result = GST_RPAD_LINKFUNC (peer) (peer, pad);
+  if (GST_PAD_LINKFUNC (peer))
+    result = GST_PAD_LINKFUNC (peer) (peer, pad);
 
   return result;
 }
@@ -733,11 +733,11 @@ restart:
     result = gst_pad_push (pad, GST_BUFFER (data));
     GST_QUEUE_MUTEX_LOCK;
     if (result != GST_FLOW_OK) {
-      gst_task_pause (GST_RPAD_TASK (queue->srcpad));
+      gst_task_pause (GST_PAD_TASK (queue->srcpad));
     }
   } else {
     if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) {
-      gst_task_pause (GST_RPAD_TASK (queue->srcpad));
+      gst_task_pause (GST_PAD_TASK (queue->srcpad));
       restart = FALSE;
     }
     GST_QUEUE_MUTEX_UNLOCK;
index 592308b..6df71a4 100644 (file)
@@ -27,6 +27,7 @@ TESTS = $(top_builddir)/tools/gst-register    \
         gst/gstbuffer                          \
         gst/gstbus                             \
        gst/gstcaps                             \
+       gst/gstghostpad                         \
        gst/gstiterator                         \
        gst/gstmessage                          \
        gst/gstobject                           \
index 9057279..abd93bf 100644 (file)
@@ -81,37 +81,6 @@ START_TEST (test_interface)
 
   gst_object_unref (GST_OBJECT (bin));
 }
-
-END_TEST
-START_TEST (test_ghost_pads)
-{
-  GstElement *b1, *b2, *src, *i1, *sink;
-
-  b1 = gst_element_factory_make ("pipeline", NULL);
-  b2 = gst_element_factory_make ("bin", NULL);
-  src = gst_element_factory_make ("fakesrc", NULL);
-  i1 = gst_element_factory_make ("identity", NULL);
-  sink = gst_element_factory_make ("fakesink", NULL);
-
-  fail_unless (gst_bin_add (GST_BIN (b2), i1));
-  fail_unless (gst_bin_add (GST_BIN (b1), src));
-  fail_unless (gst_bin_add (GST_BIN (b1), b2));
-  fail_unless (gst_bin_add (GST_BIN (b1), sink));
-  fail_unless (gst_element_link_pads (src, NULL, i1, NULL));
-  fail_unless (gst_element_link_pads (i1, NULL, sink, NULL));
-  GST_LOCK (b2);
-  fail_unless (b2->numsinkpads == 1);
-  fail_unless (GST_IS_GHOST_PAD (b2->sinkpads->data));
-  fail_unless (b2->numsrcpads == 1);
-  fail_unless (GST_IS_GHOST_PAD (b2->srcpads->data));
-  GST_UNLOCK (b2);
-
-  fail_unless (gst_element_set_state (b1,
-          GST_STATE_PLAYING) == GST_STATE_SUCCESS);
-  fail_unless (gst_element_set_state (b1, GST_STATE_NULL) == GST_STATE_SUCCESS);
-
-  gst_object_unref (GST_OBJECT (b1));
-}
 END_TEST Suite * gst_bin_suite (void)
 {
   Suite *s = suite_create ("GstBin");
@@ -119,7 +88,6 @@ END_TEST Suite * gst_bin_suite (void)
 
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_interface);
-  tcase_add_test (tc_chain, test_ghost_pads);
 
   return s;
 }
diff --git a/tests/check/gst/gstghostpad.c b/tests/check/gst/gstghostpad.c
new file mode 100644 (file)
index 0000000..44f910f
--- /dev/null
@@ -0,0 +1,120 @@
+/* GStreamer
+ * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gstghostpad.c: Unit test for GstGhostPad
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "../gstcheck.h"
+
+static void
+assert_gstrefcount (gpointer p, gint i)
+{
+  if (GST_OBJECT_REFCOUNT_VALUE (p) != i)
+    g_critical ("Expected refcount %d for %s, got %d", i, GST_OBJECT_NAME (p),
+        GST_OBJECT_REFCOUNT_VALUE (p));
+}
+
+START_TEST (test_ghost_pads)
+{
+  GstElement *b1, *b2, *src, *i1, *sink;
+  GstPad *gsink, *gsrc, *gisrc, *gisink, *isink, *isrc, *fsrc, *fsink;
+
+  b1 = gst_element_factory_make ("pipeline", NULL);
+  b2 = gst_element_factory_make ("bin", NULL);
+  src = gst_element_factory_make ("fakesrc", NULL);
+  g_object_set (src, "num-buffers", (int) 10, NULL);
+  i1 = gst_element_factory_make ("identity", NULL);
+  sink = gst_element_factory_make ("fakesink", NULL);
+
+  fail_unless (gst_bin_add (GST_BIN (b2), i1));
+  fail_unless (gst_bin_add (GST_BIN (b1), src));
+  fail_unless (gst_bin_add (GST_BIN (b1), b2));
+  fail_unless (gst_bin_add (GST_BIN (b1), sink));
+  fail_unless (gst_element_link_pads (src, NULL, i1, NULL));
+  fail_unless (gst_element_link_pads (i1, NULL, sink, NULL));
+  GST_LOCK (b2);
+  fail_unless (b2->numsinkpads == 1);
+  fail_unless (GST_IS_GHOST_PAD (b2->sinkpads->data));
+  fail_unless (b2->numsrcpads == 1);
+  fail_unless (GST_IS_GHOST_PAD (b2->srcpads->data));
+  GST_UNLOCK (b2);
+
+  fsrc = gst_element_get_pad (src, "src");
+  fail_unless (fsrc != NULL);
+  gsink = GST_PAD (gst_object_ref (GST_OBJECT (b2->sinkpads->data)));
+  fail_unless (gsink != NULL);
+  gsrc = GST_PAD (gst_object_ref (GST_OBJECT (b2->srcpads->data)));
+  fail_unless (gsrc != NULL);
+  fsink = gst_element_get_pad (sink, "sink");
+  fail_unless (fsink != NULL);
+
+  isink = gst_element_get_pad (i1, "sink");
+  fail_unless (isink != NULL);
+  isrc = gst_element_get_pad (i1, "src");
+  fail_unless (isrc != NULL);
+  gisrc = gst_pad_get_peer (isink);
+  fail_unless (gisrc != NULL);
+  gisink = gst_pad_get_peer (isrc);
+  fail_unless (gisink != NULL);
+
+  /* all objects above have one refcount owned by us as well */
+
+  assert_gstrefcount (fsrc, 3); /* parent and gisrc */
+  assert_gstrefcount (gsink, 2);        /* parent */
+  assert_gstrefcount (gsrc, 2); /* parent */
+  assert_gstrefcount (fsink, 3);        /* parent and gisink */
+
+  assert_gstrefcount (gisrc, 2);        /* parent */
+  assert_gstrefcount (isink, 3);        /* parent and gsink */
+  assert_gstrefcount (gisink, 2);       /* parent */
+  assert_gstrefcount (isrc, 3); /* parent and gsrc */
+
+  fail_unless (gst_element_set_state (b1,
+          GST_STATE_PLAYING) == GST_STATE_SUCCESS);
+
+  fail_unless (gst_element_set_state (b1, GST_STATE_NULL) == GST_STATE_SUCCESS);
+
+  gst_object_unref (GST_OBJECT (b1));
+}
+END_TEST Suite * gst_ghost_pad_suite (void)
+{
+  Suite *s = suite_create ("GstGhostPad");
+  TCase *tc_chain = tcase_create ("ghost pad tests");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_ghost_pads);
+
+  return s;
+}
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = gst_ghost_pad_suite ();
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_NORMAL);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}
index 4c9854a..79db92b 100644 (file)
@@ -598,7 +598,6 @@ print_pad_info (GstElement * element)
 {
   const GList *pads;
   GstPad *pad;
-  GstRealPad *realpad;
 
   n_print ("\n");
   n_print ("Pads:\n");
@@ -612,54 +611,50 @@ print_pad_info (GstElement * element)
   while (pads) {
     pad = GST_PAD (pads->data);
     pads = g_list_next (pads);
-    realpad = GST_PAD_REALIZE (pad);
 
     n_print ("");
 
-    if (gst_pad_get_direction (GST_PAD (realpad)) == GST_PAD_SRC)
+    if (gst_pad_get_direction (pad) == GST_PAD_SRC)
       g_print ("  SRC: '%s'", gst_pad_get_name (pad));
-    else if (gst_pad_get_direction (GST_PAD (realpad)) == GST_PAD_SINK)
+    else if (gst_pad_get_direction (pad) == GST_PAD_SINK)
       g_print ("  SINK: '%s'", gst_pad_get_name (pad));
     else
       g_print ("  UNKNOWN!!!: '%s'", gst_pad_get_name (pad));
 
-    if (GST_IS_GHOST_PAD (pad))
-      g_print (", ghost of real pad %s:%s\n", GST_DEBUG_PAD_NAME (realpad));
-    else
-      g_print ("\n");
+    g_print ("\n");
 
     n_print ("    Implementation:\n");
-    if (realpad->chainfunc)
+    if (pad->chainfunc)
       n_print ("      Has chainfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc));
-    if (realpad->getrangefunc)
+          GST_DEBUG_FUNCPTR_NAME (pad->chainfunc));
+    if (pad->getrangefunc)
       n_print ("      Has getrangefunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (realpad->getrangefunc));
-    if (realpad->eventfunc != gst_pad_event_default)
+          GST_DEBUG_FUNCPTR_NAME (pad->getrangefunc));
+    if (pad->eventfunc != gst_pad_event_default)
       n_print ("      Has custom eventfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (realpad->eventfunc));
-    if (realpad->queryfunc != gst_pad_query_default)
+          GST_DEBUG_FUNCPTR_NAME (pad->eventfunc));
+    if (pad->queryfunc != gst_pad_query_default)
       n_print ("      Has custom queryfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (realpad->queryfunc));
-    if (realpad->querytypefunc != gst_pad_get_query_types_default) {
+          GST_DEBUG_FUNCPTR_NAME (pad->queryfunc));
+    if (pad->querytypefunc != gst_pad_get_query_types_default) {
       n_print ("        Provides query types:\n");
-      print_query_types (gst_pad_get_query_types (GST_PAD (realpad)));
+      print_query_types (gst_pad_get_query_types (pad));
     }
 
-    if (realpad->intlinkfunc != gst_pad_get_internal_links_default)
+    if (pad->intlinkfunc != gst_pad_get_internal_links_default)
       n_print ("      Has custom intconnfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (realpad->intlinkfunc));
+          GST_DEBUG_FUNCPTR_NAME (pad->intlinkfunc));
 
-    if (realpad->bufferallocfunc)
+    if (pad->bufferallocfunc)
       n_print ("      Has bufferallocfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (realpad->bufferallocfunc));
+          GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc));
 
     if (pad->padtemplate)
       n_print ("    Pad Template: '%s'\n", pad->padtemplate->name_template);
 
-    if (realpad->caps) {
+    if (pad->caps) {
       n_print ("    Capabilities:\n");
-      print_caps (realpad->caps, "      ");
+      print_caps (pad->caps, "      ");
     }
   }
 }
index 2548437..7d686f8 100644 (file)
@@ -475,7 +475,6 @@ print_element_info (GstElementFactory * factory)
   GstElementClass *gstelement_class;
   GList *pads;
   GstPad *pad;
-  GstRealPad *realpad;
   GstStaticPadTemplate *padtemplate;
   gint maxlevel = 0;
 
@@ -585,7 +584,6 @@ print_element_info (GstElementFactory * factory)
     while (pads) {
       pad = GST_PAD (pads->data);
       pads = g_list_next (pads);
-      realpad = GST_PAD_REALIZE (pad);
 
       PUT_START_TAG (2, "pad");
       PUT_ESCAPED (3, "name", gst_pad_get_name (pad));
@@ -597,43 +595,40 @@ print_element_info (GstElementFactory * factory)
       else
         PUT_ESCAPED (3, "direction", "unknown");
 
-      if (GST_IS_GHOST_PAD (pad))
-        PUT_ESCAPED (3, "ghost", gst_pad_get_name (pad));
-
       if (pad->padtemplate)
         PUT_ESCAPED (3, "template", pad->padtemplate->name_template);
 
       PUT_START_TAG (3, "implementation");
-      if (realpad->chainfunc)
+      if (pad->chainfunc)
         PUT_STRING (4, "<chain-based function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc));
-      if (realpad->getrangefunc)
+            GST_DEBUG_FUNCPTR_NAME (pad->chainfunc));
+      if (pad->getrangefunc)
         PUT_STRING (4, "<get-range-based function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (realpad->getrangefunc));
-      if (realpad->eventfunc != gst_pad_event_default)
+            GST_DEBUG_FUNCPTR_NAME (pad->getrangefunc));
+      if (pad->eventfunc != gst_pad_event_default)
         PUT_STRING (4, "<event-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (realpad->eventfunc));
-      if (realpad->queryfunc != gst_pad_query_default)
+            GST_DEBUG_FUNCPTR_NAME (pad->eventfunc));
+      if (pad->queryfunc != gst_pad_query_default)
         PUT_STRING (4, "<query-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (realpad->queryfunc));
-      if (realpad->querytypefunc != gst_pad_get_query_types_default) {
+            GST_DEBUG_FUNCPTR_NAME (pad->queryfunc));
+      if (pad->querytypefunc != gst_pad_get_query_types_default) {
         PUT_STRING (4, "<query-type-func function=\"%s\">",
-            GST_DEBUG_FUNCPTR_NAME (realpad->querytypefunc));
-        print_query_types (gst_pad_get_query_types (GST_PAD (realpad)), 5);
+            GST_DEBUG_FUNCPTR_NAME (pad->querytypefunc));
+        print_query_types (gst_pad_get_query_types (pad), 5);
         PUT_END_TAG (4, "query-type-func");
       }
 
-      if (realpad->intlinkfunc != gst_pad_get_internal_links_default)
+      if (pad->intlinkfunc != gst_pad_get_internal_links_default)
         PUT_STRING (4, "<intlink-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (realpad->intlinkfunc));
+            GST_DEBUG_FUNCPTR_NAME (pad->intlinkfunc));
 
-      if (realpad->bufferallocfunc)
+      if (pad->bufferallocfunc)
         PUT_STRING (4, "<bufferalloc-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (realpad->bufferallocfunc));
+            GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc));
       PUT_END_TAG (3, "implementation");
 
-      if (realpad->caps) {
-        print_caps (realpad->caps, 3);
+      if (pad->caps) {
+        print_caps (pad->caps, 3);
       }
       PUT_END_TAG (2, "pad");
     }