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.
This commit is contained in:
Andy Wingo 2005-06-08 22:16:27 +00:00
parent 034ae2139d
commit 4b908e33e0
32 changed files with 1746 additions and 1595 deletions

View file

@ -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:

View 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 \

View 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;
}

120
check/gst/gstghostpad.c Normal file
View file

@ -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;
}

View 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>

View 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:

View file

@ -62,12 +62,72 @@ 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:
<!-- ##### SIGNAL GstPad::request-link ##### -->
<para>
</para>
@gstpad: the object which received the signal.
<!-- ##### SIGNAL GstPad::unlinked ##### -->
<para>
</para>
@gstpad: the object which received the signal.
@arg1:
<!-- ##### ARG GstPad:caps ##### -->
<para>
</para>
<!-- ##### ARG GstPad:direction ##### -->
<para>
</para>
<!-- ##### ARG GstPad:template ##### -->
<para>
</para>
<!-- ##### MACRO GST_PAD_LINK_FAILED ##### -->
<para>
@ -87,35 +147,6 @@ successfull negotiation step (OK/DONE).
@ret: the #GstPadLinkReturn value
<!-- ##### MACRO GST_PAD_QUERY_TYPE_FUNCTION ##### -->
<para>
A convenience macro to construct query type functions
</para>
@functionname: the name of the function
@...: query types, 0 to mark the last element
<!-- ##### MACRO GST_PAD_FORMATS_FUNCTION ##### -->
<para>
Convenience function to define an array of formats that can be used
as #GstPadGetFormatsFunction.
</para>
@functionname: The name of the function
@...: comma separated list of formats, 0 to mark the end
<!-- ##### MACRO GST_PAD_EVENT_MASK_FUNCTION ##### -->
<para>
Convenience function to define an array of event masks that can be used
as #GstPadGetEventMaskFunction.
</para>
@functionname: The name of the function
@...: comma separated list of event maks, { 0, } to mark the end
<!-- ##### USER_FUNCTION GstPadChainFunction ##### -->
<para>
A function that will be called when chaining buffers.
@ -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:

View file

@ -98,14 +98,6 @@ template.
@presence:
@static_caps:
<!-- ##### MACRO GST_IS_GHOST_PAD_FAST ##### -->
<para>
</para>
@obj:
<!-- ##### MACRO GST_IS_PAD_FAST ##### -->
<para>

View 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 \

View 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;

View 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);

View file

@ -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 ();

View file

@ -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>

View 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));

View 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);
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);
/* 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));
}
} else if (GST_IS_GHOST_PAD (pad)) {
g_object_set (pad, "real-pad", NULL, NULL);
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_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;
/* 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);
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));
}
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_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 (peer));
}
}
gst_object_unref (GST_OBJECT_CAST (pad));
if (!done) {
/* all other conditions are just push based pads */
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"activating pad %s in push mode", GST_OBJECT_NAME (pad));
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_LOCK (element);
if (cookie != element->pads_cookie)
goto restart;

View 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);

593
gst/gstghostpad.c Normal file
View file

@ -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;
}

53
gst/gstghostpad.h Normal file
View file

@ -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__ */

View 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);

File diff suppressed because it is too large Load diff

View file

@ -39,54 +39,25 @@
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)
#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)
/* 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_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_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_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_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_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_RPAD_BUFFERALLOCFUNC(pad) (GST_REAL_PAD_CAST(pad)->bufferallocfunc)
#define GST_PAD_BUFFERALLOCFUNC(pad) (GST_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_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_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_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_REALIZE(pad)->stream_rec_lock)
#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

View 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;

View 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);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
realpad = GST_REAL_PAD_CAST (pad);
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,

View 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)

View 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;

View 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);

View 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;

View 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 \

View 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;
}

View file

@ -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;
}

View 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, " ");
}
}
}

View 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");
}