mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-07 06:52:41 +00:00
gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/.
Original commit message from CVS: 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
This commit is contained in:
parent
d4eef4be74
commit
a8b84d8a57
13 changed files with 381 additions and 123 deletions
|
@ -642,6 +642,7 @@ testsuite/clock/Makefile
|
||||||
testsuite/debug/Makefile
|
testsuite/debug/Makefile
|
||||||
testsuite/dynparams/Makefile
|
testsuite/dynparams/Makefile
|
||||||
testsuite/elements/Makefile
|
testsuite/elements/Makefile
|
||||||
|
testsuite/ghostpads/Makefile
|
||||||
testsuite/indexers/Makefile
|
testsuite/indexers/Makefile
|
||||||
testsuite/parse/Makefile
|
testsuite/parse/Makefile
|
||||||
testsuite/plugin/Makefile
|
testsuite/plugin/Makefile
|
||||||
|
|
|
@ -906,7 +906,7 @@ gst_bin_get_list (GstBin * bin)
|
||||||
* Returns: An element inside the bin implementing the interface.
|
* Returns: An element inside the bin implementing the interface.
|
||||||
*/
|
*/
|
||||||
GstElement *
|
GstElement *
|
||||||
gst_bin_get_by_interface (GstBin *bin, const GType interface)
|
gst_bin_get_by_interface (GstBin *bin, GType interface)
|
||||||
{
|
{
|
||||||
GList *walk;
|
GList *walk;
|
||||||
|
|
||||||
|
@ -942,7 +942,7 @@ gst_bin_get_by_interface (GstBin *bin, const GType interface)
|
||||||
* Returns: An element inside the bin implementing the interface.
|
* Returns: An element inside the bin implementing the interface.
|
||||||
*/
|
*/
|
||||||
GList *
|
GList *
|
||||||
gst_bin_get_all_by_interface (GstBin *bin, const GType interface)
|
gst_bin_get_all_by_interface (GstBin *bin, GType interface)
|
||||||
{
|
{
|
||||||
GList *walk, *ret = NULL;
|
GList *walk, *ret = NULL;
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,8 @@ GstElement* gst_bin_get_by_name (GstBin *bin, const gchar *name);
|
||||||
GstElement* gst_bin_get_by_name_recurse_up (GstBin *bin, const gchar *name);
|
GstElement* gst_bin_get_by_name_recurse_up (GstBin *bin, const gchar *name);
|
||||||
G_CONST_RETURN GList*
|
G_CONST_RETURN GList*
|
||||||
gst_bin_get_list (GstBin *bin);
|
gst_bin_get_list (GstBin *bin);
|
||||||
GstElement* gst_bin_get_by_interface (GstBin *bin, const GType interface);
|
GstElement* gst_bin_get_by_interface (GstBin *bin, GType interface);
|
||||||
GList * gst_bin_get_all_by_interface (GstBin *bin, const GType interface);
|
GList * gst_bin_get_all_by_interface (GstBin *bin, GType interface);
|
||||||
|
|
||||||
gboolean gst_bin_iterate (GstBin *bin);
|
gboolean gst_bin_iterate (GstBin *bin);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#define CAPS_POISON(caps) G_STMT_START{ \
|
#define CAPS_POISON(caps) G_STMT_START{ \
|
||||||
|
@ -46,6 +47,14 @@ static void _gst_caps_value_init (GValue *value);
|
||||||
static void _gst_caps_value_free (GValue *value);
|
static void _gst_caps_value_free (GValue *value);
|
||||||
static void _gst_caps_value_copy (const GValue *src, GValue *dest);
|
static void _gst_caps_value_copy (const GValue *src, GValue *dest);
|
||||||
static gpointer _gst_caps_value_peek_pointer (const GValue *value);
|
static gpointer _gst_caps_value_peek_pointer (const GValue *value);
|
||||||
|
static gchar* _gst_caps_collect_value (GValue *value,
|
||||||
|
guint n_collect_values,
|
||||||
|
GTypeCValue *collect_values,
|
||||||
|
guint collect_flags);
|
||||||
|
static gchar* _gst_caps_lcopy_value (const GValue *value,
|
||||||
|
guint n_collect_values,
|
||||||
|
GTypeCValue *collect_values,
|
||||||
|
guint collect_flags);
|
||||||
static gboolean _gst_caps_from_string_inplace (GstCaps *caps,
|
static gboolean _gst_caps_from_string_inplace (GstCaps *caps,
|
||||||
const gchar *string);
|
const gchar *string);
|
||||||
|
|
||||||
|
@ -59,10 +68,10 @@ void _gst_caps_initialize (void)
|
||||||
_gst_caps_value_free,
|
_gst_caps_value_free,
|
||||||
_gst_caps_value_copy,
|
_gst_caps_value_copy,
|
||||||
_gst_caps_value_peek_pointer,
|
_gst_caps_value_peek_pointer,
|
||||||
NULL,
|
"p",
|
||||||
NULL,
|
_gst_caps_collect_value,
|
||||||
NULL,
|
"p",
|
||||||
NULL,
|
_gst_caps_lcopy_value,
|
||||||
};
|
};
|
||||||
static const GTypeInfo caps2_info = {
|
static const GTypeInfo caps2_info = {
|
||||||
0,
|
0,
|
||||||
|
@ -1134,7 +1143,7 @@ static void _gst_caps_transform_to_string (const GValue *src_value,
|
||||||
|
|
||||||
static void _gst_caps_value_init (GValue *value)
|
static void _gst_caps_value_init (GValue *value)
|
||||||
{
|
{
|
||||||
value->data[0].v_pointer = gst_caps_new_empty();
|
value->data[0].v_pointer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _gst_caps_value_free (GValue *value)
|
static void _gst_caps_value_free (GValue *value)
|
||||||
|
@ -1159,6 +1168,49 @@ static gpointer _gst_caps_value_peek_pointer (const GValue *value)
|
||||||
return value->data[0].v_pointer;
|
return value->data[0].v_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* adapted from gboxed.c */
|
||||||
|
static gchar*
|
||||||
|
_gst_caps_collect_value (GValue *value,
|
||||||
|
guint n_collect_values,
|
||||||
|
GTypeCValue *collect_values,
|
||||||
|
guint collect_flags)
|
||||||
|
{
|
||||||
|
if (!collect_values[0].v_pointer)
|
||||||
|
value->data[0].v_pointer = NULL;
|
||||||
|
else
|
||||||
|
if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
|
||||||
|
{
|
||||||
|
value->data[0].v_pointer = collect_values[0].v_pointer;
|
||||||
|
value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value->data[0].v_pointer = gst_caps_copy (collect_values[0].v_pointer);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar*
|
||||||
|
_gst_caps_lcopy_value (const GValue *value,
|
||||||
|
guint n_collect_values,
|
||||||
|
GTypeCValue *collect_values,
|
||||||
|
guint collect_flags)
|
||||||
|
{
|
||||||
|
GstCaps **boxed_p = collect_values[0].v_pointer;
|
||||||
|
|
||||||
|
if (!boxed_p)
|
||||||
|
return g_strdup_printf ("value location for `%s' passed as NULL",
|
||||||
|
G_VALUE_TYPE_NAME (value));
|
||||||
|
|
||||||
|
if (!value->data[0].v_pointer)
|
||||||
|
*boxed_p = NULL;
|
||||||
|
else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
|
||||||
|
*boxed_p = value->data[0].v_pointer;
|
||||||
|
else
|
||||||
|
*boxed_p = gst_caps_copy (value->data[0].v_pointer);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* fixate utility functions */
|
/* fixate utility functions */
|
||||||
|
|
||||||
gboolean gst_caps_structure_fixate_field_nearest_int (GstStructure *structure,
|
gboolean gst_caps_structure_fixate_field_nearest_int (GstStructure *structure,
|
||||||
|
|
121
gst/gstelement.c
121
gst/gstelement.c
|
@ -1056,7 +1056,8 @@ gst_element_add_pad (GstElement *element, GstPad *pad)
|
||||||
g_return_if_fail (GST_IS_ELEMENT (element));
|
g_return_if_fail (GST_IS_ELEMENT (element));
|
||||||
g_return_if_fail (GST_IS_PAD (pad));
|
g_return_if_fail (GST_IS_PAD (pad));
|
||||||
|
|
||||||
/* first check to make sure the pad's parent is already set */
|
/* first check to make sure the pad hasn't already been added to another
|
||||||
|
* element */
|
||||||
g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
|
g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
|
||||||
|
|
||||||
/* then check to see if there's already a pad by that name here */
|
/* then check to see if there's already a pad by that name here */
|
||||||
|
@ -1070,10 +1071,18 @@ gst_element_add_pad (GstElement *element, GstPad *pad)
|
||||||
/* add it to the list */
|
/* add it to the list */
|
||||||
element->pads = g_list_append (element->pads, pad);
|
element->pads = g_list_append (element->pads, pad);
|
||||||
element->numpads++;
|
element->numpads++;
|
||||||
if (gst_pad_get_direction (pad) == GST_PAD_SRC)
|
|
||||||
|
switch (gst_pad_get_direction (pad)) {
|
||||||
|
case GST_PAD_SRC:
|
||||||
element->numsrcpads++;
|
element->numsrcpads++;
|
||||||
else
|
break;
|
||||||
|
case GST_PAD_SINK:
|
||||||
element->numsinkpads++;
|
element->numsinkpads++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* can happen for ghost pads */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* activate element when we are playing */
|
/* activate element when we are playing */
|
||||||
if (GST_STATE (element) == GST_STATE_PLAYING)
|
if (GST_STATE (element) == GST_STATE_PLAYING)
|
||||||
|
@ -1083,6 +1092,36 @@ gst_element_add_pad (GstElement *element, GstPad *pad)
|
||||||
g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
|
g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 the given pad, and adds it to the list of pads
|
||||||
|
* for this element.
|
||||||
|
*
|
||||||
|
* Returns: the added ghost #GstPad, or NULL on error.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* then check to see if there's already a pad by that name here */
|
||||||
|
g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
|
||||||
|
|
||||||
|
ghostpad = gst_ghost_pad_new (name, pad);
|
||||||
|
|
||||||
|
gst_element_add_pad (element, ghostpad);
|
||||||
|
|
||||||
|
return ghostpad;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_element_remove_pad:
|
* gst_element_remove_pad:
|
||||||
* @element: a #GstElement to remove pad from.
|
* @element: a #GstElement to remove pad from.
|
||||||
|
@ -1100,79 +1139,42 @@ gst_element_remove_pad (GstElement *element, GstPad *pad)
|
||||||
|
|
||||||
g_return_if_fail (GST_PAD_PARENT (pad) == element);
|
g_return_if_fail (GST_PAD_PARENT (pad) == element);
|
||||||
|
|
||||||
/* check to see if the pad is still linked */
|
|
||||||
/* FIXME: what if someone calls _remove_pad instead of
|
|
||||||
_remove_ghost_pad? */
|
|
||||||
if (GST_IS_REAL_PAD (pad)) {
|
if (GST_IS_REAL_PAD (pad)) {
|
||||||
|
/* unlink if necessary */
|
||||||
if (GST_RPAD_PEER (pad) != NULL) {
|
if (GST_RPAD_PEER (pad) != NULL) {
|
||||||
gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
|
gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
|
||||||
}
|
}
|
||||||
|
} else if (GST_IS_GHOST_PAD (pad)) {
|
||||||
|
g_object_set (pad, "real-pad", NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove it from the list */
|
/* remove it from the list */
|
||||||
element->pads = g_list_remove (element->pads, pad);
|
element->pads = g_list_remove (element->pads, pad);
|
||||||
element->numpads--;
|
element->numpads--;
|
||||||
if (gst_pad_get_direction (pad) == GST_PAD_SRC)
|
switch (gst_pad_get_direction (pad)) {
|
||||||
|
case GST_PAD_SRC:
|
||||||
element->numsrcpads--;
|
element->numsrcpads--;
|
||||||
else
|
break;
|
||||||
|
case GST_PAD_SINK:
|
||||||
element->numsinkpads--;
|
element->numsinkpads--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* can happen for ghost pads */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
|
g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
|
||||||
|
|
||||||
gst_object_unparent (GST_OBJECT (pad));
|
gst_object_unparent (GST_OBJECT (pad));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Creates a ghost pad from the given pad, and adds it to the list of pads
|
|
||||||
* for this element.
|
|
||||||
*
|
|
||||||
* Returns: the added ghost #GstPad, or NULL, if no ghost pad was created.
|
|
||||||
*/
|
|
||||||
GstPad *
|
|
||||||
gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
|
|
||||||
{
|
|
||||||
GstPad *ghostpad;
|
|
||||||
|
|
||||||
g_return_val_if_fail (element != NULL, NULL);
|
|
||||||
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
|
|
||||||
g_return_val_if_fail (pad != NULL, NULL);
|
|
||||||
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
|
||||||
|
|
||||||
/* then check to see if there's already a pad by that name here */
|
|
||||||
g_return_val_if_fail (gst_object_check_uniqueness (element->pads, name) == TRUE, NULL);
|
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
|
|
||||||
"creating new ghost pad called %s, from pad %s:%s",
|
|
||||||
name, GST_DEBUG_PAD_NAME(pad));
|
|
||||||
ghostpad = gst_ghost_pad_new (name, pad);
|
|
||||||
|
|
||||||
/* add it to the list */
|
|
||||||
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"adding ghost pad %s to element %s",
|
|
||||||
name, GST_ELEMENT_NAME (element));
|
|
||||||
element->pads = g_list_append (element->pads, ghostpad);
|
|
||||||
element->numpads++;
|
|
||||||
/* set the parent of the ghostpad */
|
|
||||||
gst_object_set_parent (GST_OBJECT (ghostpad), GST_OBJECT (element));
|
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s",GST_DEBUG_PAD_NAME(ghostpad));
|
|
||||||
|
|
||||||
/* emit the NEW_GHOST_PAD signal */
|
|
||||||
g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
|
|
||||||
|
|
||||||
return ghostpad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_element_remove_ghost_pad:
|
* gst_element_remove_ghost_pad:
|
||||||
* @element: a #GstElement to remove the ghost pad from.
|
* @element: a #GstElement to remove the ghost pad from.
|
||||||
* @pad: ghost #GstPad to remove.
|
* @pad: ghost #GstPad to remove.
|
||||||
*
|
*
|
||||||
* Removes a ghost pad from an element.
|
* Removes a ghost pad from an element. Deprecated, use gst_element_remove_pad
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
|
gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
|
||||||
|
@ -1180,15 +1182,10 @@ gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
|
||||||
g_return_if_fail (GST_IS_ELEMENT (element));
|
g_return_if_fail (GST_IS_ELEMENT (element));
|
||||||
g_return_if_fail (GST_IS_GHOST_PAD (pad));
|
g_return_if_fail (GST_IS_GHOST_PAD (pad));
|
||||||
|
|
||||||
/* FIXME this is redundant?
|
g_warning ("gst_element_remove_ghost_pad is deprecated.\n"
|
||||||
* wingo 10-july-2001: I don't think so, you have to actually remove the pad
|
"Use gst_element_remove_pad instead.");
|
||||||
* from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
|
|
||||||
* the real pad's ghost pad list
|
|
||||||
*/
|
|
||||||
gst_object_ref (GST_OBJECT (pad));
|
|
||||||
gst_element_remove_pad (element, pad);
|
gst_element_remove_pad (element, pad);
|
||||||
gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
|
|
||||||
gst_object_unref (GST_OBJECT (pad));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,5 @@ VOID:UINT,POINTER
|
||||||
BOOLEAN:VOID
|
BOOLEAN:VOID
|
||||||
BOOLEAN:POINTER
|
BOOLEAN:POINTER
|
||||||
POINTER:POINTER
|
POINTER:POINTER
|
||||||
|
BOXED:BOXED
|
||||||
|
VOID:BOXED
|
||||||
|
|
160
gst/gstpad.c
160
gst/gstpad.c
|
@ -183,8 +183,8 @@ gst_real_pad_class_init (GstRealPadClass *klass)
|
||||||
gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
|
gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
|
||||||
g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
|
G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
|
||||||
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
|
gst_marshal_VOID__BOXED, G_TYPE_NONE, 1,
|
||||||
G_TYPE_POINTER);
|
GST_TYPE_CAPS);
|
||||||
gst_real_pad_signals[REAL_LINKED] =
|
gst_real_pad_signals[REAL_LINKED] =
|
||||||
g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
|
G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
|
||||||
|
@ -199,11 +199,9 @@ gst_real_pad_class_init (GstRealPadClass *klass)
|
||||||
g_signal_new ("fixate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
g_signal_new ("fixate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GstRealPadClass, appfixatefunc),
|
G_STRUCT_OFFSET (GstRealPadClass, appfixatefunc),
|
||||||
_gst_real_pad_fixate_accumulator, NULL,
|
_gst_real_pad_fixate_accumulator, NULL,
|
||||||
gst_marshal_POINTER__POINTER, G_TYPE_POINTER, 1,
|
gst_marshal_BOXED__BOXED, GST_TYPE_CAPS, 1,
|
||||||
G_TYPE_POINTER);
|
GST_TYPE_CAPS);
|
||||||
|
|
||||||
/* gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
|
|
||||||
/* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
|
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
|
||||||
g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
|
g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
|
||||||
TRUE, G_PARAM_READWRITE));
|
TRUE, G_PARAM_READWRITE));
|
||||||
|
@ -221,7 +219,7 @@ static gboolean
|
||||||
_gst_real_pad_fixate_accumulator (GSignalInvocationHint *ihint,
|
_gst_real_pad_fixate_accumulator (GSignalInvocationHint *ihint,
|
||||||
GValue *return_accu, const GValue *handler_return, gpointer dummy)
|
GValue *return_accu, const GValue *handler_return, gpointer dummy)
|
||||||
{
|
{
|
||||||
if (g_value_get_pointer (handler_return)) {
|
if (g_value_get_boxed (handler_return)) {
|
||||||
g_value_copy (handler_return, return_accu);
|
g_value_copy (handler_return, return_accu);
|
||||||
/* stop emission if something was returned */
|
/* stop emission if something was returned */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -400,7 +398,10 @@ gst_pad_get_direction (GstPad *pad)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
|
g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
|
||||||
|
|
||||||
return GST_PAD_DIRECTION (pad);
|
if (GST_IS_REAL_PAD (pad))
|
||||||
|
return GST_PAD_DIRECTION (pad);
|
||||||
|
else
|
||||||
|
return GST_PAD_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1837,12 +1838,18 @@ gst_pad_add_ghost_pad (GstPad *pad,
|
||||||
g_return_if_fail (ghostpad != NULL);
|
g_return_if_fail (ghostpad != NULL);
|
||||||
g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
|
g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
|
||||||
|
|
||||||
realpad = GST_PAD_REALIZE (pad);
|
/* if we're ghosting a ghost pad, drill down to find the real pad */
|
||||||
|
realpad = (GstRealPad*)pad;
|
||||||
|
while (GST_IS_GHOST_PAD (realpad))
|
||||||
|
realpad = GST_GPAD_REALPAD (realpad);
|
||||||
|
g_return_if_fail (GST_IS_REAL_PAD (realpad));
|
||||||
|
|
||||||
|
/* will ref the pad template */
|
||||||
|
GST_GPAD_REALPAD (ghostpad) = realpad;
|
||||||
realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
|
realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
|
||||||
|
gst_pad_set_pad_template (GST_PAD (ghostpad), GST_PAD_PAD_TEMPLATE (pad));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_remove_ghost_pad:
|
* gst_pad_remove_ghost_pad:
|
||||||
* @pad: a #GstPad to remove the ghost pad from.
|
* @pad: a #GstPad to remove the ghost pad from.
|
||||||
|
@ -1861,6 +1868,7 @@ gst_pad_remove_ghost_pad (GstPad *pad,
|
||||||
realpad = GST_PAD_REALIZE (pad);
|
realpad = GST_PAD_REALIZE (pad);
|
||||||
g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad);
|
g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad);
|
||||||
|
|
||||||
|
gst_pad_set_pad_template (GST_PAD (ghostpad), NULL);
|
||||||
realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
|
realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
|
||||||
GST_GPAD_REALPAD (ghostpad) = NULL;
|
GST_GPAD_REALPAD (ghostpad) = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2441,8 +2449,8 @@ gst_pad_get_caps (GstPad *pad)
|
||||||
*
|
*
|
||||||
* Gets the template capabilities of this pad.
|
* Gets the template capabilities of this pad.
|
||||||
*
|
*
|
||||||
* Returns: the template #GstCaps of this pad, unref the caps
|
* Returns: the #GstCaps of this pad template. If you intend to keep a reference
|
||||||
* if you no longer need it.
|
* on the caps, make a copy (see gst_caps_copy ()).
|
||||||
*/
|
*/
|
||||||
const GstCaps*
|
const GstCaps*
|
||||||
gst_pad_get_pad_template_caps (GstPad *pad)
|
gst_pad_get_pad_template_caps (GstPad *pad)
|
||||||
|
@ -2470,8 +2478,8 @@ gst_pad_get_pad_template_caps (GstPad *pad)
|
||||||
*
|
*
|
||||||
* Gets the capability with the given name from this pad template.
|
* Gets the capability with the given name from this pad template.
|
||||||
*
|
*
|
||||||
* Returns: the #GstCaps, or NULL if not found or in case of an error. unref
|
* Returns: the #GstCaps of this pad template, or NULL if not found. If you
|
||||||
* the caps if you no longer need it.
|
* intend to keep a reference on the caps, make a copy (see gst_caps_copy ()).
|
||||||
*/
|
*/
|
||||||
const GstCaps*
|
const GstCaps*
|
||||||
gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
|
gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
|
||||||
|
@ -2497,7 +2505,7 @@ gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
|
||||||
* Checks if two pads have compatible capabilities.
|
* Checks if two pads have compatible capabilities.
|
||||||
*
|
*
|
||||||
* Returns: TRUE if they are compatible or if the capabilities
|
* Returns: TRUE if they are compatible or if the capabilities
|
||||||
* could not be checked
|
* could not be checked.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
|
gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
|
||||||
|
@ -2684,6 +2692,9 @@ gst_real_pad_dispose (GObject *object)
|
||||||
/* No linked pad can ever be disposed.
|
/* No linked pad can ever be disposed.
|
||||||
* It has to have a parent to be linked
|
* It has to have a parent to be linked
|
||||||
* and a parent would hold a reference */
|
* and a parent would hold a reference */
|
||||||
|
/* FIXME: what about if g_object_dispose is explicitly called on the pad? Is
|
||||||
|
that legal? otherwise we could assert GST_OBJECT_PARENT (pad) == NULL as
|
||||||
|
well... */
|
||||||
g_assert (GST_PAD_PEER (pad) == NULL);
|
g_assert (GST_PAD_PEER (pad) == NULL);
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s", GST_DEBUG_PAD_NAME(pad));
|
GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s", GST_DEBUG_PAD_NAME(pad));
|
||||||
|
@ -2697,16 +2708,23 @@ gst_real_pad_dispose (GObject *object)
|
||||||
while (ghostpads) {
|
while (ghostpads) {
|
||||||
GstPad *ghostpad = GST_PAD (ghostpads->data);
|
GstPad *ghostpad = GST_PAD (ghostpads->data);
|
||||||
|
|
||||||
if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))){
|
if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))) {
|
||||||
GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'",
|
GstElement *parent = GST_ELEMENT (GST_OBJECT_PARENT (ghostpad));
|
||||||
GST_OBJECT_NAME (GST_OBJECT_PARENT (ghostpad)));
|
|
||||||
|
|
||||||
gst_element_remove_ghost_pad (GST_ELEMENT (GST_OBJECT_PARENT (ghostpad)), GST_PAD (ghostpad));
|
GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing ghost pad from element '%s'",
|
||||||
|
GST_OBJECT_NAME (parent));
|
||||||
|
gst_element_remove_pad (parent, ghostpad);
|
||||||
|
} else {
|
||||||
|
/* handle the case where we have some floating ghost pad that was never
|
||||||
|
added to an element */
|
||||||
|
g_object_set (ghostpad, "real-pad", NULL, NULL);
|
||||||
}
|
}
|
||||||
ghostpads = g_list_next (ghostpads);
|
ghostpads = g_list_next (ghostpads);
|
||||||
}
|
}
|
||||||
g_list_free (orig);
|
g_list_free (orig);
|
||||||
g_list_free (GST_REAL_PAD(pad)->ghostpads);
|
/* as the ghost pads are removed, they remove themselves from ->ghostpads.
|
||||||
|
So it should be empty now. Let's assert that. */
|
||||||
|
g_assert (GST_REAL_PAD(pad)->ghostpads == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
|
if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
|
||||||
|
@ -3239,8 +3257,8 @@ gst_pad_template_new (const gchar *name_template,
|
||||||
*
|
*
|
||||||
* Gets the capabilities of the pad template.
|
* Gets the capabilities of the pad template.
|
||||||
*
|
*
|
||||||
* Returns: the #GstCaps of the pad template. unref the caps
|
* Returns: the #GstCaps of the pad template. If you need to keep a reference to
|
||||||
* after use.
|
* the caps, make a copy (see gst_caps_copy ()).
|
||||||
*/
|
*/
|
||||||
const GstCaps*
|
const GstCaps*
|
||||||
gst_pad_template_get_caps (GstPadTemplate *templ)
|
gst_pad_template_get_caps (GstPadTemplate *templ)
|
||||||
|
@ -3285,9 +3303,19 @@ GType _gst_ghost_pad_type = 0;
|
||||||
static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
|
static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
|
||||||
static void gst_ghost_pad_init (GstGhostPad *pad);
|
static void gst_ghost_pad_init (GstGhostPad *pad);
|
||||||
static void gst_ghost_pad_dispose (GObject *object);
|
static void gst_ghost_pad_dispose (GObject *object);
|
||||||
|
static void gst_ghost_pad_get_property (GObject* object, guint prop_id,
|
||||||
|
GValue* value, GParamSpec* pspec);
|
||||||
|
static void gst_ghost_pad_set_property (GObject* object, guint prop_id,
|
||||||
|
const GValue* value, GParamSpec* pspec);
|
||||||
|
|
||||||
static GstPad *ghost_pad_parent_class = NULL;
|
static GstPad *ghost_pad_parent_class = NULL;
|
||||||
/* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
|
/* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GPAD_ARG_0,
|
||||||
|
GPAD_ARG_REAL_PAD
|
||||||
|
/* fill me */
|
||||||
|
};
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gst_ghost_pad_get_type (void)
|
gst_ghost_pad_get_type (void)
|
||||||
|
@ -3317,6 +3345,12 @@ gst_ghost_pad_class_init (GstGhostPadClass *klass)
|
||||||
ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
|
ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
|
||||||
|
|
||||||
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
|
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
|
||||||
|
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_set_property);
|
||||||
|
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_get_property);
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, GPAD_ARG_REAL_PAD,
|
||||||
|
g_param_spec_object ("real-pad", "Real pad", "The real pad for the ghost pad",
|
||||||
|
GST_TYPE_PAD, G_PARAM_READWRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3324,17 +3358,59 @@ gst_ghost_pad_init (GstGhostPad *pad)
|
||||||
{
|
{
|
||||||
/* zeroed by glib */
|
/* zeroed by glib */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ghost_pad_dispose (GObject *object)
|
gst_ghost_pad_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
GstGhostPad *pad = GST_GHOST_PAD (object);
|
g_object_set (object, "real-pad", NULL, NULL);
|
||||||
|
|
||||||
if (pad->realpad)
|
|
||||||
gst_pad_remove_ghost_pad((GstPad *) pad->realpad, (GstPad *) pad);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (ghost_pad_parent_class)->dispose (object);
|
G_OBJECT_CLASS (ghost_pad_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ghost_pad_set_property (GObject* object, guint prop_id,
|
||||||
|
const GValue* value, GParamSpec* pspec)
|
||||||
|
{
|
||||||
|
GstPad *ghostpad = (GstPad*)object;
|
||||||
|
GstPad *oldrealpad = (GstPad*)GST_GPAD_REALPAD (ghostpad);
|
||||||
|
GstPad *realpad = NULL;
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case GPAD_ARG_REAL_PAD:
|
||||||
|
realpad = g_value_get_object (value);
|
||||||
|
|
||||||
|
if (oldrealpad) {
|
||||||
|
if (realpad == oldrealpad)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
gst_pad_remove_ghost_pad (oldrealpad, ghostpad);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (realpad)
|
||||||
|
gst_pad_add_ghost_pad (realpad, ghostpad);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ghost_pad_get_property (GObject* object, guint prop_id,
|
||||||
|
GValue* value, GParamSpec* pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id) {
|
||||||
|
case GPAD_ARG_REAL_PAD:
|
||||||
|
g_value_set_object (value, GST_GPAD_REALPAD (object));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_ghost_pad_new:
|
* gst_ghost_pad_new:
|
||||||
* @name: the name of the new ghost pad.
|
* @name: the name of the new ghost pad.
|
||||||
|
@ -3342,40 +3418,28 @@ gst_ghost_pad_dispose (GObject *object)
|
||||||
*
|
*
|
||||||
* Creates a new ghost pad associated with the given pad, and names it with
|
* Creates a new ghost pad associated with the given pad, and names it with
|
||||||
* the given name. If name is NULL, a guaranteed unique name (across all
|
* the given name. If name is NULL, a guaranteed unique name (across all
|
||||||
* ghost pads) will be assigned (most likely of the form ghostpad%d).
|
* ghost pads) will be assigned.
|
||||||
*
|
*
|
||||||
* Returns: a new ghost #GstPad, or NULL in case of an error.
|
* Returns: a new ghost #GstPad, or NULL in case of an error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GstPad*
|
GstPad*
|
||||||
gst_ghost_pad_new (const gchar *name,
|
gst_ghost_pad_new (const gchar *name,
|
||||||
GstPad *pad)
|
GstPad *pad)
|
||||||
{
|
{
|
||||||
GstGhostPad *ghostpad;
|
GstPad *gpad;
|
||||||
GstRealPad *realpad;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||||
|
|
||||||
ghostpad = g_object_new (gst_ghost_pad_get_type () ,NULL);
|
gpad = g_object_new (GST_TYPE_GHOST_PAD,
|
||||||
gst_pad_set_name (GST_PAD (ghostpad), name);
|
"name", name,
|
||||||
|
"real-pad", pad,
|
||||||
|
NULL);
|
||||||
|
|
||||||
realpad = (GstRealPad *) pad;
|
GST_CAT_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\" for pad %s:%s",
|
||||||
|
GST_OBJECT_NAME (gpad),
|
||||||
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
|
|
||||||
while (!GST_IS_REAL_PAD (realpad)) {
|
return gpad;
|
||||||
realpad = GST_PAD_REALIZE (realpad);
|
|
||||||
}
|
|
||||||
GST_GPAD_REALPAD (ghostpad) = realpad;
|
|
||||||
gst_pad_set_pad_template (GST_PAD (ghostpad), GST_PAD_PAD_TEMPLATE (pad));
|
|
||||||
|
|
||||||
/* add ourselves to the real pad's list of ghostpads */
|
|
||||||
gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));
|
|
||||||
|
|
||||||
/* FIXME need to ref the real pad here... ? */
|
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\"",
|
|
||||||
gst_pad_get_name (GST_PAD (ghostpad)));
|
|
||||||
|
|
||||||
return GST_PAD (ghostpad);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,12 +13,12 @@ else
|
||||||
GST_DEBUG_DIRS = debug
|
GST_DEBUG_DIRS = debug
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS = bins bytestream cleanup dynparams \
|
SUBDIRS = bins bytestream cleanup dynparams ghostpads \
|
||||||
caps plugin elements clock refcounting tags threads \
|
caps plugin elements clock refcounting tags threads \
|
||||||
indexers debug $(GST_PARSE_DIRS) $(GST_DEBUG_DIRS)
|
indexers debug $(GST_PARSE_DIRS) $(GST_DEBUG_DIRS)
|
||||||
|
|
||||||
DIST_SUBDIRS = bins bytestream caps cleanup clock dynparams elements indexers \
|
DIST_SUBDIRS = bins bytestream caps cleanup clock dynparams elements indexers \
|
||||||
plugin refcounting tags threads parse debug
|
plugin refcounting tags threads parse debug ghostpads
|
||||||
|
|
||||||
tests_pass = test_gst_init
|
tests_pass = test_gst_init
|
||||||
tests_fail =
|
tests_fail =
|
||||||
|
|
7
tests/old/testsuite/ghostpads/Makefile.am
Normal file
7
tests/old/testsuite/ghostpads/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
tests_pass = ghostpads
|
||||||
|
tests_fail =
|
||||||
|
|
||||||
|
ghostpads_SOURCES = ghostpads.c
|
||||||
|
|
64
tests/old/testsuite/ghostpads/ghostpads.c
Normal file
64
tests/old/testsuite/ghostpads/ghostpads.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Andy Wingo <wingo at pobox.com>
|
||||||
|
*
|
||||||
|
* 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/gst.h>
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc, gchar *argv[])
|
||||||
|
{
|
||||||
|
GstElement *pipeline, *bin;
|
||||||
|
GstElement *fakesrc, *fakesink, *identity;
|
||||||
|
GstPad *sink, *src, *real = (GstPad*)0xdeadbeef;
|
||||||
|
|
||||||
|
gst_init (&argc, &argv);
|
||||||
|
|
||||||
|
pipeline = gst_element_factory_make ("pipeline", NULL);
|
||||||
|
bin = gst_element_factory_make ("bin", NULL);
|
||||||
|
fakesrc = gst_element_factory_make ("fakesrc", NULL);
|
||||||
|
fakesink = gst_element_factory_make ("fakesink", NULL);
|
||||||
|
identity = gst_element_factory_make ("identity", NULL);
|
||||||
|
|
||||||
|
gst_bin_add_many (GST_BIN (pipeline), fakesrc, bin, fakesink, NULL);
|
||||||
|
gst_bin_add (GST_BIN (bin), identity);
|
||||||
|
|
||||||
|
sink = gst_element_add_ghost_pad (bin,
|
||||||
|
gst_element_get_pad (identity, "sink"),
|
||||||
|
"sink");
|
||||||
|
src = gst_element_add_ghost_pad (bin,
|
||||||
|
gst_element_get_pad (identity, "src"),
|
||||||
|
"src");
|
||||||
|
|
||||||
|
gst_element_link_many (fakesrc, bin, fakesink);
|
||||||
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
if (!gst_bin_iterate (GST_BIN (pipeline)))
|
||||||
|
g_assert_not_reached ();
|
||||||
|
|
||||||
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||||
|
|
||||||
|
/* test the cleanup */
|
||||||
|
gst_object_ref (GST_OBJECT (sink));
|
||||||
|
gst_object_unref ((GstObject*)pipeline);
|
||||||
|
g_object_get (sink, "real-pad", &real, NULL);
|
||||||
|
g_assert (real == NULL);
|
||||||
|
g_assert (G_OBJECT (sink)->ref_count == 1);
|
||||||
|
gst_object_unref (GST_OBJECT (sink));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -13,12 +13,12 @@ else
|
||||||
GST_DEBUG_DIRS = debug
|
GST_DEBUG_DIRS = debug
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS = bins bytestream cleanup dynparams \
|
SUBDIRS = bins bytestream cleanup dynparams ghostpads \
|
||||||
caps plugin elements clock refcounting tags threads \
|
caps plugin elements clock refcounting tags threads \
|
||||||
indexers debug $(GST_PARSE_DIRS) $(GST_DEBUG_DIRS)
|
indexers debug $(GST_PARSE_DIRS) $(GST_DEBUG_DIRS)
|
||||||
|
|
||||||
DIST_SUBDIRS = bins bytestream caps cleanup clock dynparams elements indexers \
|
DIST_SUBDIRS = bins bytestream caps cleanup clock dynparams elements indexers \
|
||||||
plugin refcounting tags threads parse debug
|
plugin refcounting tags threads parse debug ghostpads
|
||||||
|
|
||||||
tests_pass = test_gst_init
|
tests_pass = test_gst_init
|
||||||
tests_fail =
|
tests_fail =
|
||||||
|
|
7
testsuite/ghostpads/Makefile.am
Normal file
7
testsuite/ghostpads/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
tests_pass = ghostpads
|
||||||
|
tests_fail =
|
||||||
|
|
||||||
|
ghostpads_SOURCES = ghostpads.c
|
||||||
|
|
64
testsuite/ghostpads/ghostpads.c
Normal file
64
testsuite/ghostpads/ghostpads.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Andy Wingo <wingo at pobox.com>
|
||||||
|
*
|
||||||
|
* 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/gst.h>
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc, gchar *argv[])
|
||||||
|
{
|
||||||
|
GstElement *pipeline, *bin;
|
||||||
|
GstElement *fakesrc, *fakesink, *identity;
|
||||||
|
GstPad *sink, *src, *real = (GstPad*)0xdeadbeef;
|
||||||
|
|
||||||
|
gst_init (&argc, &argv);
|
||||||
|
|
||||||
|
pipeline = gst_element_factory_make ("pipeline", NULL);
|
||||||
|
bin = gst_element_factory_make ("bin", NULL);
|
||||||
|
fakesrc = gst_element_factory_make ("fakesrc", NULL);
|
||||||
|
fakesink = gst_element_factory_make ("fakesink", NULL);
|
||||||
|
identity = gst_element_factory_make ("identity", NULL);
|
||||||
|
|
||||||
|
gst_bin_add_many (GST_BIN (pipeline), fakesrc, bin, fakesink, NULL);
|
||||||
|
gst_bin_add (GST_BIN (bin), identity);
|
||||||
|
|
||||||
|
sink = gst_element_add_ghost_pad (bin,
|
||||||
|
gst_element_get_pad (identity, "sink"),
|
||||||
|
"sink");
|
||||||
|
src = gst_element_add_ghost_pad (bin,
|
||||||
|
gst_element_get_pad (identity, "src"),
|
||||||
|
"src");
|
||||||
|
|
||||||
|
gst_element_link_many (fakesrc, bin, fakesink);
|
||||||
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
if (!gst_bin_iterate (GST_BIN (pipeline)))
|
||||||
|
g_assert_not_reached ();
|
||||||
|
|
||||||
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||||
|
|
||||||
|
/* test the cleanup */
|
||||||
|
gst_object_ref (GST_OBJECT (sink));
|
||||||
|
gst_object_unref ((GstObject*)pipeline);
|
||||||
|
g_object_get (sink, "real-pad", &real, NULL);
|
||||||
|
g_assert (real == NULL);
|
||||||
|
g_assert (G_OBJECT (sink)->ref_count == 1);
|
||||||
|
gst_object_unref (GST_OBJECT (sink));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue