Add a property for bins that handle the state change of their childs.

Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gstbin.c: (gst_bin_class_init), (gst_bin_init),
(gst_bin_dispose), (gst_bin_set_property), (gst_bin_get_property),
(gst_bin_remove_func), (gst_bin_handle_message_func):
* gst/gstbin.h:
Add a property for bins that handle the state change of their childs.
Fixes #435880
This commit is contained in:
Edward Hervey 2007-05-22 11:09:45 +00:00
parent 2f0f37ee73
commit 466218f4d0
4 changed files with 99 additions and 5 deletions

View file

@ -1,3 +1,13 @@
2007-05-22 Edward Hervey <edward@fluendo.com>
* docs/gst/gstreamer-sections.txt:
* gst/gstbin.c: (gst_bin_class_init), (gst_bin_init),
(gst_bin_dispose), (gst_bin_set_property), (gst_bin_get_property),
(gst_bin_remove_func), (gst_bin_handle_message_func):
* gst/gstbin.h:
Add a property for bins that handle the state change of their childs.
Fixes #435880
2007-05-22 Sebastian Dröge <slomo@circular-chaos.org> 2007-05-22 Sebastian Dröge <slomo@circular-chaos.org>
* libs/gst/controller/gstinterpolation.c: * libs/gst/controller/gstinterpolation.c:

View file

@ -80,6 +80,7 @@ GST_BIN_CAST
<SUBSECTION Private> <SUBSECTION Private>
gst_bin_get_type gst_bin_get_type
gst_bin_flags_get_type gst_bin_flags_get_type
GstBinPrivate
</SECTION> </SECTION>

View file

@ -195,8 +195,18 @@ GST_ELEMENT_DETAILS ("Generic bin",
"Simple container object", "Simple container object",
"Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>"); "Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>");
struct _GstBinPrivate
{
gboolean asynchandling;
};
static void gst_bin_dispose (GObject * object); static void gst_bin_dispose (GObject * object);
static void gst_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_bin_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_bin_change_state_func (GstElement * element, static GstStateChangeReturn gst_bin_change_state_func (GstElement * element,
GstStateChange transition); GstStateChange transition);
static GstStateChangeReturn gst_bin_get_state_func (GstElement * element, static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
@ -242,7 +252,8 @@ enum
enum enum
{ {
PROP_0 PROP_0,
PROP_ASYNC_HANDLING
/* FILL ME */ /* FILL ME */
}; };
@ -368,6 +379,24 @@ gst_bin_class_init (GstBinClass * klass)
parent_class = g_type_class_peek_parent (klass); parent_class = g_type_class_peek_parent (klass);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bin_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bin_get_property);
/**
* GstBin:async-handling
*
* If set to #TRUE, the bin will handle asynchronous state changes.
* This should be used only if the bin subclass is modifying the state
* of its childs on its own.
*
* Since: 0.10.13
**/
g_object_class_install_property (gobject_class, PROP_ASYNC_HANDLING,
g_param_spec_boolean ("async-handling", "Async Handling",
"The bin will handle Asynchronous state changes",
FALSE, G_PARAM_READWRITE));
/** /**
* GstBin::element-added: * GstBin::element-added:
* @bin: the #GstBin * @bin: the #GstBin
@ -444,6 +473,9 @@ gst_bin_init (GstBin * bin)
GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children", GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children",
bus); bus);
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin); gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
bin->private = g_new0 (GstBinPrivate, 1);
bin->private->asynchandling = FALSE;
} }
static void static void
@ -470,6 +502,11 @@ gst_bin_dispose (GObject * object)
GST_STR_NULL (GST_OBJECT_NAME (object))); GST_STR_NULL (GST_OBJECT_NAME (object)));
} }
if (bin->private) {
g_free (bin->private);
bin->private = NULL;
}
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -487,6 +524,46 @@ gst_bin_new (const gchar * name)
return gst_element_factory_make ("bin", name); return gst_element_factory_make ("bin", name);
} }
static void
gst_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstBin *gstbin;
gstbin = GST_BIN (object);
switch (prop_id) {
case PROP_ASYNC_HANDLING:
GST_OBJECT_LOCK (gstbin);
gstbin->private->asynchandling = g_value_get_boolean (value);
GST_OBJECT_UNLOCK (gstbin);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_bin_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstBin *gstbin;
gstbin = GST_BIN (object);
switch (prop_id) {
case PROP_ASYNC_HANDLING:
GST_OBJECT_LOCK (gstbin);
g_value_set_boolean (value, gstbin->private->asynchandling);
GST_OBJECT_UNLOCK (gstbin);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/* set the index on all elements in this bin /* set the index on all elements in this bin
* *
* MT safe * MT safe
@ -931,6 +1008,8 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
GList *walk, *next; GList *walk, *next;
gboolean other_async = FALSE, this_async = FALSE, cont = FALSE; gboolean other_async = FALSE, this_async = FALSE, cont = FALSE;
GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));
GST_OBJECT_LOCK (element); GST_OBJECT_LOCK (element);
/* Check if the element is already being removed and immediately /* Check if the element is already being removed and immediately
* return */ * return */
@ -1012,7 +1091,7 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
if (!other_async && this_async) { if (!other_async && this_async) {
GST_DEBUG_OBJECT (bin, "we removed the last async element"); GST_DEBUG_OBJECT (bin, "we removed the last async element");
cont = GST_OBJECT_PARENT (bin) == NULL; cont = ((GST_OBJECT_PARENT (bin) == NULL) || bin->private->asynchandling);
if (!cont) { if (!cont) {
bin_handle_async_done (bin, &smessage); bin_handle_async_done (bin, &smessage);
async_message = gst_message_new_async_done (GST_OBJECT_CAST (bin)); async_message = gst_message_new_async_done (GST_OBJECT_CAST (bin));
@ -2685,7 +2764,7 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
bin_handle_async_start (bin, &smessage); bin_handle_async_start (bin, &smessage);
/* prepare an ASYNC_START message */ /* prepare an ASYNC_START message */
if (GST_OBJECT_PARENT (bin)) { if (GST_OBJECT_PARENT (bin) && (!bin->private->asynchandling)) {
forward = TRUE; forward = TRUE;
message = message =
gst_message_new_async_start (GST_OBJECT_CAST (bin), new_base_time); gst_message_new_async_start (GST_OBJECT_CAST (bin), new_base_time);
@ -2740,7 +2819,8 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
/* nothing found, remove all old ASYNC_DONE messages */ /* nothing found, remove all old ASYNC_DONE messages */
bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE); bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);
done = TRUE; done = TRUE;
toplevel = GST_OBJECT_PARENT (bin) == NULL; toplevel = bin->private->asynchandling
|| (GST_OBJECT_PARENT (bin) == NULL);
if (!toplevel) if (!toplevel)
bin_handle_async_done (bin, &smessage); bin_handle_async_done (bin, &smessage);
} }

View file

@ -54,6 +54,7 @@ typedef enum {
typedef struct _GstBin GstBin; typedef struct _GstBin GstBin;
typedef struct _GstBinClass GstBinClass; typedef struct _GstBinClass GstBinClass;
typedef struct _GstBinPrivate GstBinPrivate;
/** /**
* GST_BIN_NUMCHILDREN: * GST_BIN_NUMCHILDREN:
@ -113,8 +114,10 @@ struct _GstBin {
GstClock *provided_clock; GstClock *provided_clock;
GstElement *clock_provider; GstElement *clock_provider;
GstBinPrivate *private;
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING - 1];
}; };
/** /**