Various cleanups and leak fixage.

Original commit message from CVS:
Various cleanups and leak fixage.
This commit is contained in:
Wim Taymans 2001-12-15 22:37:35 +00:00
parent 47145c507a
commit 68d82dd00c
19 changed files with 316 additions and 296 deletions

View file

@ -134,8 +134,6 @@ gst_fakesink_init (GstFakeSink *fakesink)
gst_element_add_pad (GST_ELEMENT (fakesink), pad); gst_element_add_pad (GST_ELEMENT (fakesink), pad);
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
fakesink->sinkpads = g_slist_prepend (NULL, pad);
fakesink->numsinkpads = 1;
fakesink->silent = FALSE; fakesink->silent = FALSE;
fakesink->dump = FALSE; fakesink->dump = FALSE;
} }
@ -156,14 +154,11 @@ gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const
fakesink = GST_FAKESINK (element); fakesink = GST_FAKESINK (element);
name = g_strdup_printf ("sink%d", fakesink->numsinkpads); name = g_strdup_printf ("sink%d", GST_ELEMENT (fakesink)->numsinkpads);
sinkpad = gst_pad_new_from_template (templ, name); sinkpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad); gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad);
fakesink->sinkpads = g_slist_prepend (fakesink->sinkpads, sinkpad);
fakesink->numsinkpads++;
return sinkpad; return sinkpad;
} }
@ -199,7 +194,7 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
switch (prop_id) { switch (prop_id) {
case ARG_NUM_SINKS: case ARG_NUM_SINKS:
g_value_set_int (value, sink->numsinkpads); g_value_set_int (value, GST_ELEMENT (sink)->numsinkpads);
break; break;
case ARG_SILENT: case ARG_SILENT:
g_value_set_boolean (value, sink->silent); g_value_set_boolean (value, sink->silent);

View file

@ -54,8 +54,6 @@ typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink { struct _GstFakeSink {
GstElement element; GstElement element;
GSList *sinkpads;
gint numsinkpads;
gboolean silent; gboolean silent;
gboolean dump; gboolean dump;
}; };

View file

@ -256,18 +256,15 @@ gst_fakesrc_init (GstFakeSrc *fakesrc)
{ {
GstPad *pad; GstPad *pad;
// set the default number of
fakesrc->numsrcpads = 1;
// create our first output pad // create our first output pad
pad = gst_pad_new ("src", GST_PAD_SRC); pad = gst_pad_new ("src", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (fakesrc), pad); gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
fakesrc->srcpads = g_slist_append (NULL, pad);
fakesrc->loop_based = FALSE; fakesrc->loop_based = FALSE;
gst_fakesrc_update_functions (fakesrc); gst_fakesrc_update_functions (fakesrc);
fakesrc->num_buffers = -1; fakesrc->num_buffers = -1;
fakesrc->rt_num_buffers = -1;
fakesrc->buffer_count = 0; fakesrc->buffer_count = 0;
fakesrc->silent = FALSE; fakesrc->silent = FALSE;
fakesrc->dump = FALSE; fakesrc->dump = FALSE;
@ -298,14 +295,11 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
fakesrc = GST_FAKESRC (element); fakesrc = GST_FAKESRC (element);
name = g_strdup_printf ("src%d", fakesrc->numsrcpads); name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads);
srcpad = gst_pad_new_from_template (templ, name); srcpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad); gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
fakesrc->srcpads = g_slist_prepend (fakesrc->srcpads, srcpad);
fakesrc->numsrcpads++;
return srcpad; return srcpad;
} }
@ -340,7 +334,7 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
static void static void
gst_fakesrc_update_functions (GstFakeSrc *src) gst_fakesrc_update_functions (GstFakeSrc *src)
{ {
GSList *pads; GList *pads;
if (src->loop_based) { if (src->loop_based) {
gst_element_set_loop_function (GST_ELEMENT (src), GST_DEBUG_FUNCPTR (gst_fakesrc_loop)); gst_element_set_loop_function (GST_ELEMENT (src), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
@ -349,7 +343,7 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
gst_element_set_loop_function (GST_ELEMENT (src), NULL); gst_element_set_loop_function (GST_ELEMENT (src), NULL);
} }
pads = src->srcpads; pads = GST_ELEMENT (src)->pads;
while (pads) { while (pads) {
GstPad *pad = GST_PAD (pads->data); GstPad *pad = GST_PAD (pads->data);
@ -361,7 +355,7 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
} }
gst_pad_set_event_function (pad, gst_fakesrc_event_handler); gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
pads = g_slist_next (pads); pads = g_list_next (pads);
} }
} }
@ -456,7 +450,7 @@ gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
switch (prop_id) { switch (prop_id) {
case ARG_NUM_SOURCES: case ARG_NUM_SOURCES:
g_value_set_int (value, src->numsrcpads); g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
break; break;
case ARG_LOOP_BASED: case ARG_LOOP_BASED:
g_value_set_boolean (value, src->loop_based); g_value_set_boolean (value, src->loop_based);
@ -656,14 +650,14 @@ gst_fakesrc_get(GstPad *pad)
return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH)); return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH));
} }
if (src->num_buffers == 0) { if (src->rt_num_buffers == 0) {
g_print("fakesrc: sending EOS\n"); g_print("fakesrc: sending EOS\n");
gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED); gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED);
return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
} }
else { else {
if (src->num_buffers > 0) if (src->rt_num_buffers > 0)
src->num_buffers--; src->rt_num_buffers--;
} }
if (src->eos) { if (src->eos) {
@ -704,20 +698,20 @@ gst_fakesrc_loop(GstElement *element)
src = GST_FAKESRC (element); src = GST_FAKESRC (element);
do { do {
GSList *pads; GList *pads;
pads = src->srcpads; pads = GST_ELEMENT (src)->pads;
while (pads) { while (pads) {
GstPad *pad = GST_PAD (pads->data); GstPad *pad = GST_PAD (pads->data);
GstBuffer *buf; GstBuffer *buf;
if (src->num_buffers == 0) { if (src->rt_num_buffers == 0) {
src->eos = TRUE; src->eos = TRUE;
} }
else { else {
if (src->num_buffers > 0) if (src->rt_num_buffers > 0)
src->num_buffers--; src->rt_num_buffers--;
} }
if (src->eos) { if (src->eos) {
@ -737,7 +731,7 @@ gst_fakesrc_loop(GstElement *element)
buf, pad); buf, pad);
gst_pad_push (pad, buf); gst_pad_push (pad, buf);
pads = g_slist_next (pads); pads = g_list_next (pads);
} }
} while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
} }
@ -751,14 +745,30 @@ gst_fakesrc_change_state (GstElement *element)
fakesrc = GST_FAKESRC (element); fakesrc = GST_FAKESRC (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PAUSED_TO_READY:
case GST_STATE_NULL_TO_READY:
fakesrc->buffer_count = 0;
fakesrc->pattern_byte = 0x00;
fakesrc->need_flush = FALSE;
fakesrc->eos = FALSE;
fakesrc->rt_num_buffers = fakesrc->num_buffers;
if (fakesrc->parent) {
gst_buffer_unref (fakesrc->parent);
fakesrc->parent = NULL;
}
break;
case GST_STATE_READY_TO_PAUSED:
case GST_STATE_PAUSED_TO_PLAYING:
case GST_STATE_PLAYING_TO_PAUSED:
case GST_STATE_READY_TO_NULL:
break;
default:
g_asset_not_reached ();
break;
}
if (GST_STATE_PENDING (element) == GST_STATE_READY) { if (GST_STATE_PENDING (element) == GST_STATE_READY) {
fakesrc->buffer_count = 0;
fakesrc->pattern_byte = 0x00;
fakesrc->need_flush = FALSE;
if (fakesrc->parent) {
gst_buffer_unref (fakesrc->parent);
fakesrc->parent = NULL;
}
} }
if (GST_ELEMENT_CLASS (parent_class)->change_state) if (GST_ELEMENT_CLASS (parent_class)->change_state)

View file

@ -85,8 +85,6 @@ struct _GstFakeSrc {
gboolean loop_based; gboolean loop_based;
gboolean eos; gboolean eos;
gint numsrcpads;
GSList *srcpads;
GstFakeSrcOutputType output; GstFakeSrcOutputType output;
GstFakeSrcDataType data; GstFakeSrcDataType data;
@ -102,6 +100,7 @@ struct _GstFakeSrc {
gchar *pattern; gchar *pattern;
GList *patternlist; GList *patternlist;
gint num_buffers; gint num_buffers;
gint rt_num_buffers; /* we are going to change this at runtime */
guint64 buffer_count; guint64 buffer_count;
gboolean silent; gboolean silent;
gboolean dump; gboolean dump;

View file

@ -27,25 +27,26 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
/***** until we have gettext set up properly, don't even try this /***** until we have gettext set up properly, don't even try this*/
#ifdef ENABLE_NLS #if 0
#include <libintl.h> # ifdef ENABLE_NLS
#define _(String) dgettext(PACKAGE,String) # include <libintl.h>
#ifdef gettext_noop # define _(String) dgettext(PACKAGE,String)
#define N_(String) gettext_noop(String) # ifdef gettext_noop
#else // gettext_noop # define N_(String) gettext_noop(String)
#define N_(String) (String) # else /* gettext_noop */
#endif // gettext_noop # define N_(String) (String)
#else // ENABLE_NLS # endif /* gettext_noop */
#define _(String) (String) # else /* ENABLE_NLS */
#define N_(String) (String) # define _(String) (String)
#define textdomain(String) (String) # define N_(String) (String)
#define gettext(String) (String) # define textdomain(String) (String)
#define dgettext(Domain,String) (String) # define gettext(String) (String)
#define dcgettext(Domain,String,Type) (String) # define dgettext(Domain,String) (String)
#define bindtextdomain(Domain,Directory) (Domain) # define dcgettext(Domain,String,Type) (String)
#endif // ENABLE_NLS # define bindtextdomain(Domain,Directory) (Domain)
*****/ # endif /* ENABLE_NLS */
#endif
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */

View file

@ -38,38 +38,36 @@ GstElementDetails gst_bin_details = {
GType _gst_bin_type = 0; GType _gst_bin_type = 0;
static void gst_bin_dispose (GObject *object); static void gst_bin_dispose (GObject * object);
static GstElementStateReturn gst_bin_change_state (GstElement *element); static GstElementStateReturn gst_bin_change_state (GstElement * element);
static GstElementStateReturn gst_bin_change_state_norecurse (GstBin *bin); static GstElementStateReturn gst_bin_change_state_norecurse (GstBin * bin);
static gboolean gst_bin_change_state_type (GstBin *bin, static gboolean gst_bin_change_state_type (GstBin * bin, GstElementState state, GType type);
GstElementState state, static void gst_bin_child_state_change (GstBin * bin, GstElementState old,
GType type); GstElementState new, GstElement * element);
static void gst_bin_child_state_change (GstBin *bin, GstElementState old,
GstElementState new, GstElement *child);
static gboolean gst_bin_iterate_func (GstBin *bin); static gboolean gst_bin_iterate_func (GstBin * bin);
#ifndef GST_DISABLE_LOADSAVE #ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr gst_bin_save_thyself (GstObject *object, xmlNodePtr parent); static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
static void gst_bin_restore_thyself (GstObject *object, xmlNodePtr self); static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
#endif #endif
/* Bin signals and args */ /* Bin signals and args */
enum { enum
{
OBJECT_ADDED, OBJECT_ADDED,
LAST_SIGNAL LAST_SIGNAL
}; };
enum { enum
{
ARG_0, ARG_0,
/* FILL ME */ /* FILL ME */
}; };
static void gst_bin_class_init (GstBinClass * klass);
static void gst_bin_class_init (GstBinClass *klass); static void gst_bin_init (GstBin * bin);
static void gst_bin_init (GstBin *bin);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
static guint gst_bin_signals[LAST_SIGNAL] = { 0 }; static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
@ -79,56 +77,55 @@ gst_bin_get_type (void)
{ {
if (!_gst_bin_type) { if (!_gst_bin_type) {
static const GTypeInfo bin_info = { static const GTypeInfo bin_info = {
sizeof(GstBinClass), sizeof (GstBinClass),
NULL, NULL,
NULL, NULL,
(GClassInitFunc)gst_bin_class_init, (GClassInitFunc) gst_bin_class_init,
NULL, NULL,
NULL, NULL,
sizeof(GstBin), sizeof (GstBin),
8, 8,
(GInstanceInitFunc)gst_bin_init, (GInstanceInitFunc) gst_bin_init,
NULL NULL
}; };
_gst_bin_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0); _gst_bin_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0);
} }
return _gst_bin_type; return _gst_bin_type;
} }
static void static void
gst_bin_class_init (GstBinClass *klass) gst_bin_class_init (GstBinClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstObjectClass *gstobject_class; GstObjectClass *gstobject_class;
GstElementClass *gstelement_class; GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass; gobject_class = (GObjectClass *) klass;
gstobject_class = (GstObjectClass*)klass; gstobject_class = (GstObjectClass *) klass;
gstelement_class = (GstElementClass*)klass; gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT); parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
gst_bin_signals[OBJECT_ADDED] = gst_bin_signals[OBJECT_ADDED] =
g_signal_new ("object_added", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, g_signal_new ("object_added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GstBinClass, object_added), NULL, NULL, G_STRUCT_OFFSET (GstBinClass, object_added), NULL, NULL,
gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
GST_TYPE_ELEMENT);
klass->change_state_type = GST_DEBUG_FUNCPTR (gst_bin_change_state_type);
klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose);
#ifndef GST_DISABLE_LOADSAVE #ifndef GST_DISABLE_LOADSAVE
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_bin_save_thyself); gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_bin_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_bin_restore_thyself); gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
#endif #endif
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose); klass->change_state_type = GST_DEBUG_FUNCPTR (gst_bin_change_state_type);
klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func);
} }
static void static void
gst_bin_init (GstBin *bin) gst_bin_init (GstBin * bin)
{ {
/* in general, we prefer to use cothreads for most things */ /* in general, we prefer to use cothreads for most things */
GST_FLAG_SET (bin, GST_BIN_FLAG_PREFER_COTHREADS); GST_FLAG_SET (bin, GST_BIN_FLAG_PREFER_COTHREADS);
@ -146,36 +143,36 @@ gst_bin_init (GstBin *bin)
* *
* Returns: new bin * Returns: new bin
*/ */
GstElement* GstElement *
gst_bin_new (const gchar *name) gst_bin_new (const gchar * name)
{ {
return gst_elementfactory_make ("bin", name); return gst_elementfactory_make ("bin", name);
} }
static inline void static inline void
gst_bin_reset_element_sched (GstElement *element, GstScheduler *sched) gst_bin_reset_element_sched (GstElement * element, GstScheduler * sched)
{ {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "resetting element's scheduler"); GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "resetting element's scheduler");
gst_element_set_sched (element,sched); gst_element_set_sched (element, sched);
} }
static void static void
gst_bin_set_element_sched (GstElement *element,GstScheduler *sched) gst_bin_set_element_sched (GstElement * element, GstScheduler * sched)
{ {
GList *children; GList *children;
GstElement *child; GstElement *child;
g_return_if_fail (element != NULL); g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_ELEMENT(element)); g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (sched != NULL); g_return_if_fail (sched != NULL);
g_return_if_fail (GST_IS_SCHEDULER(sched)); g_return_if_fail (GST_IS_SCHEDULER (sched));
GST_INFO (GST_CAT_SCHEDULING, "setting element \"%s\" sched to %p",GST_ELEMENT_NAME(element), GST_INFO (GST_CAT_SCHEDULING, "setting element \"%s\" sched to %p", GST_ELEMENT_NAME (element),
sched); sched);
/* if it's actually a Bin */ /* if it's actually a Bin */
if (GST_IS_BIN(element)) { if (GST_IS_BIN (element)) {
if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) { if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is already a manager, not resetting"); GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is already a manager, not resetting");
return; return;
@ -185,59 +182,58 @@ gst_bin_set_element_sched (GstElement *element,GstScheduler *sched)
gst_scheduler_add_element (sched, element); gst_scheduler_add_element (sched, element);
/* set the children's schedule */ /* set the children's schedule */
children = GST_BIN(element)->children; children = GST_BIN (element)->children;
while (children) { while (children) {
child = GST_ELEMENT (children->data); child = GST_ELEMENT (children->data);
children = g_list_next(children); children = g_list_next (children);
gst_bin_set_element_sched (child, sched); gst_bin_set_element_sched (child, sched);
} }
}
/* otherwise, if it's just a regular old element */ /* otherwise, if it's just a regular old element */
} else { else {
gst_scheduler_add_element (sched, element); gst_scheduler_add_element (sched, element);
} }
} }
static void static void
gst_bin_unset_element_sched (GstElement *element) gst_bin_unset_element_sched (GstElement * element)
{ {
GList *children; GList *children;
GstElement *child; GstElement *child;
g_return_if_fail (element != NULL); g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_ELEMENT(element)); g_return_if_fail (GST_IS_ELEMENT (element));
GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from it sched %p", GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from it sched %p",
GST_ELEMENT_NAME(element),GST_ELEMENT_SCHED(element)); GST_ELEMENT_NAME (element), GST_ELEMENT_SCHED (element));
/* if it's actually a Bin */ /* if it's actually a Bin */
if (GST_IS_BIN(element)) { if (GST_IS_BIN (element)) {
if (GST_FLAG_IS_SET(element,GST_BIN_FLAG_MANAGER)) { if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is already a manager, not unsetting sched"); GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element,
"child is already a manager, not unsetting sched");
return; return;
} }
/* FIXME this check should be irrelevant */ gst_scheduler_remove_element (GST_ELEMENT_SCHED (element), element);
if (GST_ELEMENT_SCHED (element))
gst_scheduler_remove_element (GST_ELEMENT_SCHED(element), element);
/* for each child, remove them from their schedule */ /* for each child, remove them from their schedule */
children = GST_BIN(element)->children; children = GST_BIN (element)->children;
while (children) { while (children) {
child = GST_ELEMENT (children->data); child = GST_ELEMENT (children->data);
children = g_list_next(children); children = g_list_next (children);
gst_bin_unset_element_sched (child); gst_bin_unset_element_sched (child);
} }
}
/* otherwise, if it's just a regular old element */ /* otherwise, if it's just a regular old element */
} else { else {
/* FIXME this check should be irrelevant */ gst_scheduler_remove_element (GST_ELEMENT_SCHED (element), element);
if (GST_ELEMENT_SCHED (element))
gst_scheduler_remove_element (GST_ELEMENT_SCHED(element), element);
} }
} }
@ -251,8 +247,7 @@ gst_bin_unset_element_sched (GstElement *element)
* add a reference. * add a reference.
*/ */
void void
gst_bin_add (GstBin *bin, gst_bin_add (GstBin * bin, GstElement * element)
GstElement *element)
{ {
gint state_idx = 0; gint state_idx = 0;
GstElementState state; GstElementState state;
@ -263,7 +258,7 @@ gst_bin_add (GstBin *bin,
g_return_if_fail (GST_IS_ELEMENT (element)); g_return_if_fail (GST_IS_ELEMENT (element));
GST_DEBUG (GST_CAT_PARENTAGE, "adding element \"%s\" to bin \"%s\"\n", GST_DEBUG (GST_CAT_PARENTAGE, "adding element \"%s\" to bin \"%s\"\n",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin)); GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
/* must be not be in PLAYING state in order to modify bin */ /* must be not be in PLAYING state in order to modify bin */
g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING); g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING);
@ -272,24 +267,26 @@ gst_bin_add (GstBin *bin,
g_return_if_fail (GST_ELEMENT_PARENT (element) == NULL); g_return_if_fail (GST_ELEMENT_PARENT (element) == NULL);
/* then check to see if the element's name is already taken in the bin */ /* then check to see if the element's name is already taken in the bin */
g_return_if_fail (gst_object_check_uniqueness (bin->children, GST_ELEMENT_NAME (element)) == TRUE); g_return_if_fail (gst_object_check_uniqueness (bin->children, GST_ELEMENT_NAME (element)) ==
TRUE);
/* set the element's parent and add the element to the bin's list of children */ /* set the element's parent and add the element to the bin's list of children */
gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (bin)); gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (bin));
g_signal_connect_swapped (G_OBJECT (element), "state_change", gst_bin_child_state_change, G_OBJECT (bin)); g_signal_connect_swapped (G_OBJECT (element), "state_change",
G_CALLBACK (gst_bin_child_state_change), G_OBJECT (bin));
bin->children = g_list_append (bin->children, element); bin->children = g_list_append (bin->children, element);
bin->numchildren++; bin->numchildren++;
/* bump our internal state counter */ /* bump our internal state counter */
state = GST_STATE (element); state = GST_STATE (element);
while (state>>=1) state_idx++; while (state >>= 1) state_idx++;
bin->child_states[state_idx]++; bin->child_states[state_idx]++;
/* now we have to deal with manager stuff */ /* now we have to deal with manager stuff
/* we can only do this if there's a scheduler: */ * we can only do this if there's a scheduler:
/* if we're not a manager, and aren't attached to anything, we have no sched (yet) */ * if we're not a manager, and aren't attached to anything, we have no sched (yet) */
if (GST_IS_BIN(element) && GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) { if (GST_IS_BIN (element) && GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is a manager"); GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is a manager");
} }
else if (GST_ELEMENT_SCHED (bin) != NULL) { else if (GST_ELEMENT_SCHED (bin) != NULL) {
@ -309,11 +306,11 @@ gst_bin_add (GstBin *bin,
* Remove the element from its associated bin, unparenting as well. * Remove the element from its associated bin, unparenting as well.
*/ */
void void
gst_bin_remove (GstBin *bin, gst_bin_remove (GstBin * bin, GstElement * element)
GstElement *element)
{ {
gint state_idx = 0; gint state_idx = 0;
GstElementState state; GstElementState state;
gint sig;
g_return_if_fail (bin != NULL); g_return_if_fail (bin != NULL);
g_return_if_fail (GST_IS_BIN (bin)); g_return_if_fail (GST_IS_BIN (bin));
@ -325,14 +322,17 @@ gst_bin_remove (GstBin *bin,
g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING); g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING);
/* the element must have its parent set to the current bin */ /* the element must have its parent set to the current bin */
g_return_if_fail (GST_ELEMENT_PARENT(element) == (GstObject *)bin); g_return_if_fail (GST_ELEMENT_PARENT (element) == (GstObject *) bin);
/* the element must be in the bin's list of children */ /* the element must be in the bin's list of children */
if (g_list_find(bin->children, element) == NULL) { if (g_list_find (bin->children, element) == NULL) {
/* FIXME this should be a warning!!! */ g_warning ("no element \"%s\" in bin \"%s\"\n", GST_ELEMENT_NAME (element),
GST_ERROR_OBJECT(bin,element,"no such element in bin"); GST_ELEMENT_NAME (bin));
return; return;
} }
sig = g_signal_handlers_disconnect_matched (G_OBJECT (element),
G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL,
gst_bin_child_state_change, bin);
/* remove this element from the list of managed elements */ /* remove this element from the list of managed elements */
gst_bin_unset_element_sched (element); gst_bin_unset_element_sched (element);
@ -343,7 +343,7 @@ gst_bin_remove (GstBin *bin,
/* bump our internal state counter */ /* bump our internal state counter */
state = GST_STATE (element); state = GST_STATE (element);
while (state>>=1) state_idx++; while (state >>= 1) state_idx++;
bin->child_states[state_idx]--; bin->child_states[state_idx]--;
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, bin, "removed child %s", GST_ELEMENT_NAME (element)); GST_INFO_ELEMENT (GST_CAT_PARENTAGE, bin, "removed child %s", GST_ELEMENT_NAME (element));
@ -356,38 +356,39 @@ gst_bin_remove (GstBin *bin,
} }
static void static void
gst_bin_child_state_change (GstBin *bin, GstElementState old, GstElementState new, GstElement *child) gst_bin_child_state_change (GstBin * bin, GstElementState old, GstElementState new,
GstElement * child)
{ {
gint old_idx = 0, new_idx = 0, i; gint old_idx = 0, new_idx = 0, i;
GST_INFO (GST_CAT_STATES, "child %s changed state in bin %s from %s to %s", GST_INFO (GST_CAT_STATES, "child %s changed state in bin %s from %s to %s",
GST_ELEMENT_NAME (child), GST_ELEMENT_NAME (bin), GST_ELEMENT_NAME (child), GST_ELEMENT_NAME (bin),
gst_element_statename (old), gst_element_statename (new)); gst_element_statename (old), gst_element_statename (new));
while (old>>=1) old_idx++; while (old >>= 1) old_idx++;
while (new>>=1) new_idx++; while (new >>= 1) new_idx++;
GST_LOCK (bin); GST_LOCK (bin);
bin->child_states[old_idx]--; bin->child_states[old_idx]--;
bin->child_states[new_idx]++; bin->child_states[new_idx]++;
for (i = GST_NUM_STATES-1; i >= 0; i--) { for (i = GST_NUM_STATES - 1; i >= 0; i--) {
if (bin->child_states[i] != 0) { if (bin->child_states[i] != 0) {
if (GST_STATE (bin) != (1 << i)) { if (GST_STATE (bin) != (1 << i)) {
GST_INFO (GST_CAT_STATES, "bin %s need state change to %s", GST_INFO (GST_CAT_STATES, "bin %s need state change to %s",
GST_ELEMENT_NAME (bin), gst_element_statename (1<<i)); GST_ELEMENT_NAME (bin), gst_element_statename (1 << i));
GST_STATE_PENDING (bin) = (1<<i); GST_STATE_PENDING (bin) = (1 << i);
gst_bin_change_state_norecurse (bin); gst_bin_change_state_norecurse (bin);
} }
break; break;
} }
} }
GST_UNLOCK (bin); GST_UNLOCK (bin);
} }
static GstElementStateReturn static GstElementStateReturn
gst_bin_change_state (GstElement *element) gst_bin_change_state (GstElement * element)
{ {
GstBin *bin; GstBin *bin;
GList *children; GList *children;
@ -404,8 +405,7 @@ gst_bin_change_state (GstElement *element)
pending = GST_STATE_PENDING (element); pending = GST_STATE_PENDING (element);
GST_INFO_ELEMENT (GST_CAT_STATES, element, "changing childrens' state from %s to %s", GST_INFO_ELEMENT (GST_CAT_STATES, element, "changing childrens' state from %s to %s",
gst_element_statename (old_state), gst_element_statename (old_state), gst_element_statename (pending));
gst_element_statename (pending));
children = bin->children; children = bin->children;
while (children) { while (children) {
@ -414,25 +414,25 @@ gst_bin_change_state (GstElement *element)
switch (gst_element_set_state (child, pending)) { switch (gst_element_set_state (child, pending)) {
case GST_STATE_FAILURE: case GST_STATE_FAILURE:
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
GST_DEBUG (GST_CAT_STATES,"child '%s' failed to go to state %d(%s)\n", GST_ELEMENT_NAME (child), GST_DEBUG (GST_CAT_STATES, "child '%s' failed to go to state %d(%s)\n",
pending, gst_element_statename (pending)); GST_ELEMENT_NAME (child), pending, gst_element_statename (pending));
gst_element_set_state (child, old_state); gst_element_set_state (child, old_state);
if (GST_ELEMENT_SCHED (child) == GST_ELEMENT_SCHED (element)) { if (GST_ELEMENT_SCHED (child) == GST_ELEMENT_SCHED (element)) {
return GST_STATE_FAILURE; return GST_STATE_FAILURE;
} }
break; break;
case GST_STATE_ASYNC: case GST_STATE_ASYNC:
GST_DEBUG (GST_CAT_STATES,"child '%s' is changing state asynchronously\n", GST_ELEMENT_NAME (child)); GST_DEBUG (GST_CAT_STATES, "child '%s' is changing state asynchronously\n",
GST_ELEMENT_NAME (child));
have_async = TRUE; have_async = TRUE;
break; break;
} }
} }
GST_INFO_ELEMENT (GST_CAT_STATES, element, "done changing bin's state from %s to %s", GST_INFO_ELEMENT (GST_CAT_STATES, element, "done changing bin's state from %s to %s",
gst_element_statename (old_state), gst_element_statename (old_state), gst_element_statename (pending));
gst_element_statename (pending));
if (have_async) if (have_async)
ret = GST_STATE_ASYNC; ret = GST_STATE_ASYNC;
@ -444,19 +444,18 @@ gst_bin_change_state (GstElement *element)
static GstElementStateReturn static GstElementStateReturn
gst_bin_change_state_norecurse (GstBin *bin) gst_bin_change_state_norecurse (GstBin * bin)
{ {
if (GST_ELEMENT_CLASS (parent_class)->change_state) { if (GST_ELEMENT_CLASS (parent_class)->change_state) {
GST_DEBUG_ELEMENT (GST_CAT_STATES, bin, "setting bin's own state\n"); GST_DEBUG_ELEMENT (GST_CAT_STATES, bin, "setting bin's own state\n");
return GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT (bin)); return GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT (bin));
} else }
else
return GST_STATE_FAILURE; return GST_STATE_FAILURE;
} }
static gboolean static gboolean
gst_bin_change_state_type (GstBin *bin, gst_bin_change_state_type (GstBin * bin, GstElementState state, GType type)
GstElementState state,
GType type)
{ {
GList *children; GList *children;
GstElement *child; GstElement *child;
@ -468,11 +467,12 @@ gst_bin_change_state_type (GstBin *bin,
while (children) { while (children) {
child = GST_ELEMENT (children->data); child = GST_ELEMENT (children->data);
if (GST_IS_BIN (child)) { if (GST_IS_BIN (child)) {
if (!gst_bin_set_state_type (GST_BIN (child), state,type)) if (!gst_bin_set_state_type (GST_BIN (child), state, type))
return FALSE; return FALSE;
} else if (G_TYPE_CHECK_INSTANCE_TYPE (child,type)) { }
if (!gst_element_set_state (child,state)) else if (G_TYPE_CHECK_INSTANCE_TYPE (child, type)) {
return FALSE; if (!gst_element_set_state (child, state))
return FALSE;
} }
children = g_list_next (children); children = g_list_next (children);
} }
@ -493,45 +493,41 @@ gst_bin_change_state_type (GstBin *bin,
* Returns: indication if the state change was successfull * Returns: indication if the state change was successfull
*/ */
gboolean gboolean
gst_bin_set_state_type (GstBin *bin, gst_bin_set_state_type (GstBin * bin, GstElementState state, GType type)
GstElementState state,
GType type)
{ {
GstBinClass *oclass; GstBinClass *oclass;
GST_DEBUG (GST_CAT_STATES,"gst_bin_set_state_type(\"%s\",%d,%d)\n", GST_DEBUG (GST_CAT_STATES, "gst_bin_set_state_type(\"%s\",%d,%d)\n",
GST_ELEMENT_NAME (bin), state,type); GST_ELEMENT_NAME (bin), state, type);
g_return_val_if_fail (bin != NULL, FALSE); g_return_val_if_fail (bin != NULL, FALSE);
g_return_val_if_fail (GST_IS_BIN (bin), FALSE); g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
oclass = GST_BIN_CLASS (G_OBJECT_GET_CLASS(bin)); oclass = GST_BIN_CLASS (G_OBJECT_GET_CLASS (bin));
if (oclass->change_state_type) if (oclass->change_state_type)
(oclass->change_state_type) (bin,state,type); (oclass->change_state_type) (bin, state, type);
return TRUE; return TRUE;
} }
static void static void
gst_bin_dispose (GObject *object) gst_bin_dispose (GObject * object)
{ {
GstBin *bin = GST_BIN (object); GstBin *bin = GST_BIN (object);
GList *children, *orig; GList *children, *orig;
GstElement *child; GstElement *child;
GST_DEBUG (GST_CAT_REFCOUNTING,"dispose\n"); GST_DEBUG (GST_CAT_REFCOUNTING, "dispose\n");
if (bin->children) { if (bin->children) {
orig = children = g_list_copy (bin->children); orig = children = g_list_copy (bin->children);
while (children) { while (children) {
child = GST_ELEMENT (children->data); child = GST_ELEMENT (children->data);
/* gst_object_unref (GST_OBJECT (child)); */
/* gst_object_unparent (GST_OBJECT (child)); */
gst_bin_remove (bin, child); gst_bin_remove (bin, child);
children = g_list_next (children); children = g_list_next (children);
} }
g_list_free (orig);
g_list_free (bin->children); g_list_free (bin->children);
g_list_free (orig);
} }
bin->children = NULL; bin->children = NULL;
bin->numchildren = 0; bin->numchildren = 0;
@ -550,9 +546,8 @@ gst_bin_dispose (GObject *object)
* *
* Returns: the element with the given name * Returns: the element with the given name
*/ */
GstElement* GstElement *
gst_bin_get_by_name (GstBin *bin, gst_bin_get_by_name (GstBin * bin, const gchar * name)
const gchar *name)
{ {
GList *children; GList *children;
GstElement *child; GstElement *child;
@ -566,12 +561,13 @@ gst_bin_get_by_name (GstBin *bin,
children = bin->children; children = bin->children;
while (children) { while (children) {
child = GST_ELEMENT (children->data); child = GST_ELEMENT (children->data);
if (!strcmp (GST_OBJECT_NAME(child),name)) if (!strcmp (GST_OBJECT_NAME (child), name))
return child; return child;
if (GST_IS_BIN (child)) { if (GST_IS_BIN (child)) {
GstElement *res = gst_bin_get_by_name (GST_BIN (child), name); GstElement *res = gst_bin_get_by_name (GST_BIN (child), name);
if (res) if (res)
return res; return res;
} }
children = g_list_next (children); children = g_list_next (children);
} }
@ -589,9 +585,8 @@ gst_bin_get_by_name (GstBin *bin,
* *
* Returns: the element with the given name * Returns: the element with the given name
*/ */
GstElement* GstElement *
gst_bin_get_by_name_recurse_up (GstBin *bin, gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
const gchar *name)
{ {
GstElement *result = NULL; GstElement *result = NULL;
GstObject *parent; GstObject *parent;
@ -602,13 +597,12 @@ gst_bin_get_by_name_recurse_up (GstBin *bin,
result = gst_bin_get_by_name (bin, name); result = gst_bin_get_by_name (bin, name);
if (result) if (!result) {
return result; parent = gst_object_get_parent (GST_OBJECT (bin));
parent = gst_object_get_parent (GST_OBJECT (bin)); if (parent && GST_IS_BIN (parent)) {
result = gst_bin_get_by_name_recurse_up (GST_BIN (parent), name);
if (parent && GST_IS_BIN (parent)) { }
result = gst_bin_get_by_name_recurse_up (GST_BIN (parent), name);
} }
return result; return result;
@ -622,8 +616,8 @@ gst_bin_get_by_name_recurse_up (GstBin *bin,
* *
* Returns: a GList of elements * Returns: a GList of elements
*/ */
GList* GList *
gst_bin_get_list (GstBin *bin) gst_bin_get_list (GstBin * bin)
{ {
g_return_val_if_fail (bin != NULL, NULL); g_return_val_if_fail (bin != NULL, NULL);
g_return_val_if_fail (GST_IS_BIN (bin), NULL); g_return_val_if_fail (GST_IS_BIN (bin), NULL);
@ -633,8 +627,7 @@ gst_bin_get_list (GstBin *bin)
#ifndef GST_DISABLE_LOADSAVE #ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr static xmlNodePtr
gst_bin_save_thyself (GstObject *object, gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
xmlNodePtr parent)
{ {
GstBin *bin = GST_BIN (object); GstBin *bin = GST_BIN (object);
xmlNodePtr childlist, elementnode; xmlNodePtr childlist, elementnode;
@ -659,8 +652,7 @@ gst_bin_save_thyself (GstObject *object,
} }
static void static void
gst_bin_restore_thyself (GstObject *object, gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
xmlNodePtr self)
{ {
GstBin *bin = GST_BIN (object); GstBin *bin = GST_BIN (object);
xmlNodePtr field = self->xmlChildrenNode; xmlNodePtr field = self->xmlChildrenNode;
@ -671,12 +663,12 @@ gst_bin_restore_thyself (GstObject *object,
GST_INFO_ELEMENT (GST_CAT_XML, GST_ELEMENT (object), "loading children"); GST_INFO_ELEMENT (GST_CAT_XML, GST_ELEMENT (object), "loading children");
childlist = field->xmlChildrenNode; childlist = field->xmlChildrenNode;
while (childlist) { while (childlist) {
if (!strcmp (childlist->name, "element")) { if (!strcmp (childlist->name, "element")) {
GstElement *element = gst_element_restore_thyself (childlist, GST_OBJECT (bin)); GstElement *element = gst_element_restore_thyself (childlist, GST_OBJECT (bin));
gst_bin_add (bin, element); gst_bin_add (bin, element);
} }
childlist = childlist->next; childlist = childlist->next;
} }
} }
@ -686,12 +678,13 @@ gst_bin_restore_thyself (GstObject *object,
#endif /* GST_DISABLE_LOADSAVE */ #endif /* GST_DISABLE_LOADSAVE */
static gboolean static gboolean
gst_bin_iterate_func (GstBin *bin) gst_bin_iterate_func (GstBin * bin)
{ {
/* only iterate if this is the manager bin */ /* only iterate if this is the manager bin */
if (GST_ELEMENT_SCHED(bin)->parent == GST_ELEMENT (bin)) { if (GST_ELEMENT_SCHED (bin)->parent == GST_ELEMENT (bin)) {
return gst_scheduler_iterate (GST_ELEMENT_SCHED(bin)); return gst_scheduler_iterate (GST_ELEMENT_SCHED (bin));
} else { }
else {
g_warning ("bin \"%d\" can't be iterated on!\n", GST_ELEMENT_NAME (bin)); g_warning ("bin \"%d\" can't be iterated on!\n", GST_ELEMENT_NAME (bin));
} }
@ -708,24 +701,24 @@ gst_bin_iterate_func (GstBin *bin)
* can be used to determine it the bin is in EOS. * can be used to determine it the bin is in EOS.
*/ */
gboolean gboolean
gst_bin_iterate (GstBin *bin) gst_bin_iterate (GstBin * bin)
{ {
GstBinClass *oclass; GstBinClass *oclass;
gboolean running = TRUE; gboolean running = TRUE;
GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME (bin)); GST_DEBUG_ENTER ("(\"%s\")", GST_ELEMENT_NAME (bin));
oclass = GST_BIN_CLASS (G_OBJECT_GET_CLASS(bin)); oclass = GST_BIN_CLASS (G_OBJECT_GET_CLASS (bin));
if (oclass->iterate) if (oclass->iterate)
running = (oclass->iterate) (bin); running = (oclass->iterate) (bin);
GST_DEBUG_LEAVE("(\"%s\") %d",GST_ELEMENT_NAME (bin), running); GST_DEBUG_LEAVE ("(\"%s\") %d", GST_ELEMENT_NAME (bin), running);
if (!running) { if (!running) {
if (GST_STATE (bin) == GST_STATE_PLAYING && GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING) { if (GST_STATE (bin) == GST_STATE_PLAYING && GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING) {
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, bin, "waiting for child shutdown after useless iteration\n"); GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, bin,
/* gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED); */ "waiting for child shutdown after useless iteration\n");
gst_element_wait_state_change (GST_ELEMENT (bin)); gst_element_wait_state_change (GST_ELEMENT (bin));
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, bin, "child shutdown\n"); GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, bin, "child shutdown\n");
} }
@ -733,4 +726,3 @@ gst_bin_iterate (GstBin *bin)
return running; return running;
} }

View file

@ -327,7 +327,9 @@ gst_element_remove_pad (GstElement *element, GstPad *pad)
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_ref (GST_OBJECT (pad));
gst_object_unparent (GST_OBJECT (pad)); gst_object_unparent (GST_OBJECT (pad));
//gst_object_unref (GST_OBJECT (pad));
} }
/** /**
@ -970,22 +972,19 @@ static void
gst_element_dispose (GObject *object) gst_element_dispose (GObject *object)
{ {
GstElement *element = GST_ELEMENT (object); GstElement *element = GST_ELEMENT (object);
GList *pads; GList *pads, *test;
GstPad *pad; GstPad *pad;
gint i;
GST_DEBUG_ELEMENT (GST_CAT_REFCOUNTING, element, "dispose\n"); GST_DEBUG_ELEMENT (GST_CAT_REFCOUNTING, element, "dispose\n");
if (GST_IS_BIN (GST_OBJECT_PARENT (element))) /* first we break all our connections with the ouside */
gst_bin_remove (GST_BIN (GST_OBJECT_PARENT (element)), element);
if (element->pads) { if (element->pads) {
GList *orig; GList *orig;
orig = pads = g_list_copy (element->pads); orig = pads = g_list_copy (element->pads);
while (pads) { while (pads) {
pad = GST_PAD (pads->data); pad = GST_PAD (pads->data);
/* the gst_object_unparent will do the unreffing */ gst_object_destroy (GST_OBJECT (pad));
gst_element_remove_pad(element, pad);
pads = g_list_next (pads); pads = g_list_next (pads);
} }
g_list_free (orig); g_list_free (orig);
@ -995,6 +994,7 @@ gst_element_dispose (GObject *object)
element->numsrcpads = 0; element->numsrcpads = 0;
element->numsinkpads = 0; element->numsinkpads = 0;
element->numpads = 0;
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }

View file

@ -250,12 +250,12 @@ gst_elementfactory_create (GstElementFactory *factory,
if (oclass->elementfactory == NULL) { if (oclass->elementfactory == NULL) {
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"class %s\n", GST_OBJECT_NAME (factory)); GST_DEBUG (GST_CAT_ELEMENTFACTORY,"class %s\n", GST_OBJECT_NAME (factory));
oclass->elementfactory = factory; oclass->elementfactory = factory;
// copy pad template pointers to the element class
oclass->padtemplates = g_list_copy(factory->padtemplates);
oclass->numpadtemplates = factory->numpadtemplates;
} }
/* copy pad template pointers to the element class */
oclass->padtemplates = g_list_copy(factory->padtemplates);
oclass->numpadtemplates = factory->numpadtemplates;
gst_object_set_name (GST_OBJECT (element),name); gst_object_set_name (GST_OBJECT (element),name);
return element; return element;

View file

@ -218,9 +218,7 @@ gst_object_destroy (GstObject *object)
/* need to hold a reference count around all class method /* need to hold a reference count around all class method
* invocations. * invocations.
*/ */
gst_object_ref (object); g_object_run_dispose (G_OBJECT (object));
G_OBJECT_GET_CLASS (object)->dispose (G_OBJECT (object));
gst_object_unref (object);
} }
} }
@ -238,12 +236,12 @@ gst_object_dispose (GObject *object)
static void static void
gst_object_finalize (GObject *object) gst_object_finalize (GObject *object)
{ {
GstObject *gstobject; GstObject *gstobject = GST_OBJECT (object);
gstobject = GST_OBJECT (object);
GST_DEBUG (GST_CAT_REFCOUNTING, "finalize '%s'\n",GST_OBJECT_NAME(object)); GST_DEBUG (GST_CAT_REFCOUNTING, "finalize '%s'\n",GST_OBJECT_NAME(object));
g_signal_handlers_destroy (object);
if (gstobject->name != NULL) if (gstobject->name != NULL)
g_free (gstobject->name); g_free (gstobject->name);

View file

@ -533,14 +533,14 @@ gst_pad_disconnect (GstPad *srcpad,
GST_RPAD_PEER(realsrc) = NULL; GST_RPAD_PEER(realsrc) = NULL;
GST_RPAD_PEER(realsink) = NULL; GST_RPAD_PEER(realsink) = NULL;
// now tell the scheduler
if (realsrc->sched)
gst_scheduler_pad_disconnect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
/* fire off a signal to each of the pads telling them that they've been disconnected */ /* fire off a signal to each of the pads telling them that they've been disconnected */
g_signal_emit(G_OBJECT(realsrc), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsink); g_signal_emit(G_OBJECT(realsrc), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsink);
g_signal_emit(G_OBJECT(realsink), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsrc); g_signal_emit(G_OBJECT(realsink), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsrc);
/* now tell the scheduler */
if (realsrc->sched)
gst_scheduler_pad_connect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s", GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad)); GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
} }
@ -853,7 +853,7 @@ gst_pad_set_caps (GstPad *pad,
if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) { if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) {
g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n", g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n",
GST_DEBUG_PAD_NAME (pad)); GST_DEBUG_PAD_NAME (pad));
/* return FALSE; */ return FALSE;
} }
oldcaps = GST_PAD_CAPS (pad); oldcaps = GST_PAD_CAPS (pad);

View file

@ -20,17 +20,11 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
/* #define GST_DEBUG_ENABLED */
#include "gst_private.h" #include "gst_private.h"
#include "gstpipeline.h" #include "gstpipeline.h"
#include "gstthread.h"
#include "gstutils.h"
#include "gsttype.h"
#include "gstautoplug.h"
#include "gstscheduler.h" #include "gstscheduler.h"
GstElementDetails gst_pipeline_details = { GstElementDetails gst_pipeline_details = {
"Pipeline object", "Pipeline object",
"Bin", "Bin",
@ -55,6 +49,8 @@ enum {
static void gst_pipeline_class_init (GstPipelineClass *klass); static void gst_pipeline_class_init (GstPipelineClass *klass);
static void gst_pipeline_init (GstPipeline *pipeline); static void gst_pipeline_init (GstPipeline *pipeline);
static void gst_pipeline_dispose (GObject *object);
static GstElementStateReturn gst_pipeline_change_state (GstElement *element); static GstElementStateReturn gst_pipeline_change_state (GstElement *element);
static GstBinClass *parent_class = NULL; static GstBinClass *parent_class = NULL;
@ -85,13 +81,17 @@ gst_pipeline_get_type (void) {
static void static void
gst_pipeline_class_init (GstPipelineClass *klass) gst_pipeline_class_init (GstPipelineClass *klass)
{ {
GObjectClass *gobject_class;
GstElementClass *gstelement_class; GstElementClass *gstelement_class;
gobject_class = (GObjectClass *)klass;
gstelement_class = (GstElementClass*)klass; gstelement_class = (GstElementClass*)klass;
parent_class = g_type_class_ref (gst_bin_get_type ()); parent_class = g_type_class_ref (gst_bin_get_type ());
gstelement_class->change_state = gst_pipeline_change_state; gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pipeline_dispose);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_pipeline_change_state);
} }
static void static void
@ -101,9 +101,22 @@ gst_pipeline_init (GstPipeline *pipeline)
GST_FLAG_SET (pipeline, GST_BIN_FLAG_MANAGER); GST_FLAG_SET (pipeline, GST_BIN_FLAG_MANAGER);
GST_ELEMENT_SCHED (pipeline) = gst_schedulerfactory_make ("basic", GST_ELEMENT (pipeline)); GST_ELEMENT_SCHED (pipeline) = gst_schedulerfactory_make ("basic", GST_ELEMENT (pipeline));
gst_object_ref (GST_OBJECT (GST_ELEMENT_SCHED (pipeline)));
gst_object_sink (GST_OBJECT (GST_ELEMENT_SCHED (pipeline)));
GST_DEBUG (GST_CAT_PIPELINE, "pipeline's scheduler is %p\n", GST_ELEMENT_SCHED (pipeline)); GST_DEBUG (GST_CAT_PIPELINE, "pipeline's scheduler is %p\n", GST_ELEMENT_SCHED (pipeline));
} }
static void
gst_pipeline_dispose (GObject *object)
{
GstPipeline *pipeline = GST_PIPELINE (object);
G_OBJECT_CLASS (parent_class)->dispose (object);
gst_object_unref (GST_OBJECT (GST_ELEMENT_SCHED (pipeline)));
}
/** /**
* gst_pipeline_new: * gst_pipeline_new:

View file

@ -26,14 +26,12 @@
#include <gst/gstbin.h> #include <gst/gstbin.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
extern GstElementDetails gst_pipeline_details; extern GstElementDetails gst_pipeline_details;
#define GST_TYPE_PIPELINE \ #define GST_TYPE_PIPELINE \
(gst_pipeline_get_type()) (gst_pipeline_get_type())
#define GST_PIPELINE(obj) \ #define GST_PIPELINE(obj) \

View file

@ -63,6 +63,7 @@ _gst_plugin_initialize (void)
{ {
#ifndef GST_DISABLE_REGISTRY #ifndef GST_DISABLE_REGISTRY
xmlDocPtr doc; xmlDocPtr doc;
xmlNodePtr root;
#endif #endif
main_module = g_module_open (NULL, G_MODULE_BIND_LAZY); main_module = g_module_open (NULL, G_MODULE_BIND_LAZY);

View file

@ -82,6 +82,8 @@ struct _GstSchedulerClass {
GType gst_scheduler_get_type (void); GType gst_scheduler_get_type (void);
#define gst_scheduler_destroy(sched) gst_object_destroy(GST_OBJECT(sched))
void gst_scheduler_add_element (GstScheduler *sched, GstElement *element); void gst_scheduler_add_element (GstScheduler *sched, GstElement *element);
void gst_scheduler_remove_element (GstScheduler *sched, GstElement *element); void gst_scheduler_remove_element (GstScheduler *sched, GstElement *element);
void gst_scheduler_enable_element (GstScheduler *sched, GstElement *element); void gst_scheduler_enable_element (GstScheduler *sched, GstElement *element);

View file

@ -44,6 +44,8 @@ static GType _gst_basic_scheduler_type = 0;
static void gst_basic_scheduler_class_init (GstSchedulerClass * klass); static void gst_basic_scheduler_class_init (GstSchedulerClass * klass);
static void gst_basic_scheduler_init (GstScheduler * scheduler); static void gst_basic_scheduler_init (GstScheduler * scheduler);
static void gst_basic_scheduler_dispose (GObject *object);
static void gst_basic_scheduler_add_element (GstScheduler *sched, GstElement *element); static void gst_basic_scheduler_add_element (GstScheduler *sched, GstElement *element);
static void gst_basic_scheduler_remove_element (GstScheduler *sched, GstElement *element); static void gst_basic_scheduler_remove_element (GstScheduler *sched, GstElement *element);
static void gst_basic_scheduler_enable_element (GstScheduler *sched, GstElement *element); static void gst_basic_scheduler_enable_element (GstScheduler *sched, GstElement *element);
@ -92,6 +94,8 @@ gst_basic_scheduler_class_init (GstSchedulerClass * klass)
parent_class = g_type_class_ref (GST_TYPE_SCHEDULER); parent_class = g_type_class_ref (GST_TYPE_SCHEDULER);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_basic_scheduler_dispose);
klass->add_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_add_element); klass->add_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_add_element);
klass->remove_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_remove_element); klass->remove_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_remove_element);
klass->enable_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_enable_element); klass->enable_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_enable_element);
@ -109,6 +113,12 @@ gst_basic_scheduler_init (GstScheduler *scheduler)
{ {
} }
static void
gst_basic_scheduler_dispose (GObject *object)
{
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static gboolean static gboolean
plugin_init (GModule *module, GstPlugin *plugin) plugin_init (GModule *module, GstPlugin *plugin)
{ {
@ -551,16 +561,17 @@ gst_basic_scheduler_chain_destroy (GstSchedulerChain * chain)
GstScheduler *sched = chain->sched; GstScheduler *sched = chain->sched;
// remove the chain from the schedulers' list of chains // remove the chain from the schedulers' list of chains
chain->sched->chains = g_list_remove (chain->sched->chains, chain); sched->chains = g_list_remove (sched->chains, chain);
chain->sched->num_chains--; sched->num_chains--;
// destroy the chain // destroy the chain
g_list_free (chain->disabled); // should be empty... g_list_free (chain->disabled); // should be empty...
g_list_free (chain->elements); // ditto g_list_free (chain->elements); // ditto
g_free (chain);
GST_INFO (GST_CAT_SCHEDULING, "destroyed chain %p, now are %d chains in sched %p", chain, GST_INFO (GST_CAT_SCHEDULING, "destroyed chain %p, now are %d chains in sched %p", chain,
sched->num_chains, sched); sched->num_chains, sched);
g_free (chain);
} }
static void static void
@ -946,11 +957,11 @@ gst_basic_scheduler_pad_disconnect (GstScheduler * sched, GstPad * srcpad, GstPa
if (chain) { if (chain) {
GST_INFO (GST_CAT_SCHEDULING, "destroying chain"); GST_INFO (GST_CAT_SCHEDULING, "destroying chain");
gst_basic_scheduler_chain_destroy (chain); gst_basic_scheduler_chain_destroy (chain);
}
// now create a new chain to hold element1 and build it from scratch // now create a new chain to hold element1 and build it from scratch
chain1 = gst_basic_scheduler_chain_new (sched); chain1 = gst_basic_scheduler_chain_new (sched);
gst_basic_scheduler_chain_recursive_add (chain1, element1); gst_basic_scheduler_chain_recursive_add (chain1, element1);
}
// check the other element to see if it landed in the newly created chain // check the other element to see if it landed in the newly created chain
if (gst_basic_scheduler_find_chain (sched, element2) == NULL) { if (gst_basic_scheduler_find_chain (sched, element2) == NULL) {

View file

@ -134,8 +134,6 @@ gst_fakesink_init (GstFakeSink *fakesink)
gst_element_add_pad (GST_ELEMENT (fakesink), pad); gst_element_add_pad (GST_ELEMENT (fakesink), pad);
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
fakesink->sinkpads = g_slist_prepend (NULL, pad);
fakesink->numsinkpads = 1;
fakesink->silent = FALSE; fakesink->silent = FALSE;
fakesink->dump = FALSE; fakesink->dump = FALSE;
} }
@ -156,14 +154,11 @@ gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const
fakesink = GST_FAKESINK (element); fakesink = GST_FAKESINK (element);
name = g_strdup_printf ("sink%d", fakesink->numsinkpads); name = g_strdup_printf ("sink%d", GST_ELEMENT (fakesink)->numsinkpads);
sinkpad = gst_pad_new_from_template (templ, name); sinkpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad); gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad);
fakesink->sinkpads = g_slist_prepend (fakesink->sinkpads, sinkpad);
fakesink->numsinkpads++;
return sinkpad; return sinkpad;
} }
@ -199,7 +194,7 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
switch (prop_id) { switch (prop_id) {
case ARG_NUM_SINKS: case ARG_NUM_SINKS:
g_value_set_int (value, sink->numsinkpads); g_value_set_int (value, GST_ELEMENT (sink)->numsinkpads);
break; break;
case ARG_SILENT: case ARG_SILENT:
g_value_set_boolean (value, sink->silent); g_value_set_boolean (value, sink->silent);

View file

@ -54,8 +54,6 @@ typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink { struct _GstFakeSink {
GstElement element; GstElement element;
GSList *sinkpads;
gint numsinkpads;
gboolean silent; gboolean silent;
gboolean dump; gboolean dump;
}; };

View file

@ -256,18 +256,15 @@ gst_fakesrc_init (GstFakeSrc *fakesrc)
{ {
GstPad *pad; GstPad *pad;
// set the default number of
fakesrc->numsrcpads = 1;
// create our first output pad // create our first output pad
pad = gst_pad_new ("src", GST_PAD_SRC); pad = gst_pad_new ("src", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (fakesrc), pad); gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
fakesrc->srcpads = g_slist_append (NULL, pad);
fakesrc->loop_based = FALSE; fakesrc->loop_based = FALSE;
gst_fakesrc_update_functions (fakesrc); gst_fakesrc_update_functions (fakesrc);
fakesrc->num_buffers = -1; fakesrc->num_buffers = -1;
fakesrc->rt_num_buffers = -1;
fakesrc->buffer_count = 0; fakesrc->buffer_count = 0;
fakesrc->silent = FALSE; fakesrc->silent = FALSE;
fakesrc->dump = FALSE; fakesrc->dump = FALSE;
@ -298,14 +295,11 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
fakesrc = GST_FAKESRC (element); fakesrc = GST_FAKESRC (element);
name = g_strdup_printf ("src%d", fakesrc->numsrcpads); name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads);
srcpad = gst_pad_new_from_template (templ, name); srcpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad); gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
fakesrc->srcpads = g_slist_prepend (fakesrc->srcpads, srcpad);
fakesrc->numsrcpads++;
return srcpad; return srcpad;
} }
@ -340,7 +334,7 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
static void static void
gst_fakesrc_update_functions (GstFakeSrc *src) gst_fakesrc_update_functions (GstFakeSrc *src)
{ {
GSList *pads; GList *pads;
if (src->loop_based) { if (src->loop_based) {
gst_element_set_loop_function (GST_ELEMENT (src), GST_DEBUG_FUNCPTR (gst_fakesrc_loop)); gst_element_set_loop_function (GST_ELEMENT (src), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
@ -349,7 +343,7 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
gst_element_set_loop_function (GST_ELEMENT (src), NULL); gst_element_set_loop_function (GST_ELEMENT (src), NULL);
} }
pads = src->srcpads; pads = GST_ELEMENT (src)->pads;
while (pads) { while (pads) {
GstPad *pad = GST_PAD (pads->data); GstPad *pad = GST_PAD (pads->data);
@ -361,7 +355,7 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
} }
gst_pad_set_event_function (pad, gst_fakesrc_event_handler); gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
pads = g_slist_next (pads); pads = g_list_next (pads);
} }
} }
@ -456,7 +450,7 @@ gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
switch (prop_id) { switch (prop_id) {
case ARG_NUM_SOURCES: case ARG_NUM_SOURCES:
g_value_set_int (value, src->numsrcpads); g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
break; break;
case ARG_LOOP_BASED: case ARG_LOOP_BASED:
g_value_set_boolean (value, src->loop_based); g_value_set_boolean (value, src->loop_based);
@ -656,14 +650,14 @@ gst_fakesrc_get(GstPad *pad)
return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH)); return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH));
} }
if (src->num_buffers == 0) { if (src->rt_num_buffers == 0) {
g_print("fakesrc: sending EOS\n"); g_print("fakesrc: sending EOS\n");
gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED); gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED);
return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
} }
else { else {
if (src->num_buffers > 0) if (src->rt_num_buffers > 0)
src->num_buffers--; src->rt_num_buffers--;
} }
if (src->eos) { if (src->eos) {
@ -704,20 +698,20 @@ gst_fakesrc_loop(GstElement *element)
src = GST_FAKESRC (element); src = GST_FAKESRC (element);
do { do {
GSList *pads; GList *pads;
pads = src->srcpads; pads = GST_ELEMENT (src)->pads;
while (pads) { while (pads) {
GstPad *pad = GST_PAD (pads->data); GstPad *pad = GST_PAD (pads->data);
GstBuffer *buf; GstBuffer *buf;
if (src->num_buffers == 0) { if (src->rt_num_buffers == 0) {
src->eos = TRUE; src->eos = TRUE;
} }
else { else {
if (src->num_buffers > 0) if (src->rt_num_buffers > 0)
src->num_buffers--; src->rt_num_buffers--;
} }
if (src->eos) { if (src->eos) {
@ -737,7 +731,7 @@ gst_fakesrc_loop(GstElement *element)
buf, pad); buf, pad);
gst_pad_push (pad, buf); gst_pad_push (pad, buf);
pads = g_slist_next (pads); pads = g_list_next (pads);
} }
} while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
} }
@ -751,14 +745,30 @@ gst_fakesrc_change_state (GstElement *element)
fakesrc = GST_FAKESRC (element); fakesrc = GST_FAKESRC (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PAUSED_TO_READY:
case GST_STATE_NULL_TO_READY:
fakesrc->buffer_count = 0;
fakesrc->pattern_byte = 0x00;
fakesrc->need_flush = FALSE;
fakesrc->eos = FALSE;
fakesrc->rt_num_buffers = fakesrc->num_buffers;
if (fakesrc->parent) {
gst_buffer_unref (fakesrc->parent);
fakesrc->parent = NULL;
}
break;
case GST_STATE_READY_TO_PAUSED:
case GST_STATE_PAUSED_TO_PLAYING:
case GST_STATE_PLAYING_TO_PAUSED:
case GST_STATE_READY_TO_NULL:
break;
default:
g_asset_not_reached ();
break;
}
if (GST_STATE_PENDING (element) == GST_STATE_READY) { if (GST_STATE_PENDING (element) == GST_STATE_READY) {
fakesrc->buffer_count = 0;
fakesrc->pattern_byte = 0x00;
fakesrc->need_flush = FALSE;
if (fakesrc->parent) {
gst_buffer_unref (fakesrc->parent);
fakesrc->parent = NULL;
}
} }
if (GST_ELEMENT_CLASS (parent_class)->change_state) if (GST_ELEMENT_CLASS (parent_class)->change_state)

View file

@ -85,8 +85,6 @@ struct _GstFakeSrc {
gboolean loop_based; gboolean loop_based;
gboolean eos; gboolean eos;
gint numsrcpads;
GSList *srcpads;
GstFakeSrcOutputType output; GstFakeSrcOutputType output;
GstFakeSrcDataType data; GstFakeSrcDataType data;
@ -102,6 +100,7 @@ struct _GstFakeSrc {
gchar *pattern; gchar *pattern;
GList *patternlist; GList *patternlist;
gint num_buffers; gint num_buffers;
gint rt_num_buffers; /* we are going to change this at runtime */
guint64 buffer_count; guint64 buffer_count;
gboolean silent; gboolean silent;
gboolean dump; gboolean dump;