Commit 4b908e33 authored by Andy Wingo Wingo's avatar Andy Wingo Wingo

gst/gstutils.c: RPAD fixes all around.

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.
parent 034ae213
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:
......
......@@ -27,6 +27,7 @@ TESTS = $(top_builddir)/tools/gst-register \
gst/gstbuffer \
gst/gstbus \
gst/gstcaps \
gst/gstghostpad \
gst/gstiterator \
gst/gstmessage \
gst/gstobject \
......
......@@ -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;
}
......
/* 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;
}
......@@ -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>
......
......@@ -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:
......@@ -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:
......
......@@ -98,14 +98,6 @@ template.
@presence:
@static_caps:
<!-- ##### MACRO GST_IS_GHOST_PAD_FAST ##### -->
<para>
</para>
@obj:
<!-- ##### MACRO GST_IS_PAD_FAST ##### -->
<para>
......
......@@ -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 \
......
......@@ -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;
......
......@@ -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);
......
......@@ -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 ();
......
......@@ -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>
......
......@@ -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));
......
......@@ -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.