gstreamer/gst/gstbin.c

1232 lines
34 KiB
C
Raw Normal View History

/* GStreamer
*
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2004 Wim Taymans <wim@fluendo.com>
*
* gstbin.c: GstBin container object and support code
*
* 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.
*
* MT safe.
*/
#include "gst_private.h"
#include "gstevent.h"
#include "gstbin.h"
#include "gstmarshal.h"
#include "gstxml.h"
#include "gstinfo.h"
#include "gsterror.h"
#include "gstscheduler.h"
#include "gstindex.h"
#include "gstutils.h"
GST_DEBUG_CATEGORY_STATIC (bin_debug);
#define GST_CAT_DEFAULT bin_debug
#define GST_LOG_BIN_CONTENTS(bin, text) GST_LOG_OBJECT ((bin), \
text ": %d elements: %u PLAYING, %u PAUSED, %u READY, %u NULL, own state: %s", \
(bin)->numchildren, (guint) (bin)->child_states[3], \
(guint) (bin)->child_states[2], (bin)->child_states[1], \
(bin)->child_states[0], gst_element_state_get_name (GST_STATE (bin)))
static GstElementDetails gst_bin_details = GST_ELEMENT_DETAILS ("Generic bin",
"Generic/Bin",
"Simple container object",
"Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>");
GType _gst_bin_type = 0;
static void gst_bin_dispose (GObject * object);
static GstElementStateReturn gst_bin_change_state (GstElement * element);
static GstElementStateReturn gst_bin_get_state (GstElement * element,
GstElementState * state, GstElementState * pending, GTimeVal * timeout);
#ifndef GST_DISABLE_INDEX
static void gst_bin_set_index (GstElement * element, GstIndex * index);
#endif
static void gst_bin_set_clock (GstElement * element, GstClock * clock);
static GstClock *gst_bin_get_clock (GstElement * element);
Correctly distribute clock/scheduler to elements Original commit message from CVS: * gst/elements/gstfakesink.c: (gst_fakesink_event): * gst/elements/gstfakesrc.c: (gst_fakesrc_update_functions), (gst_fakesrc_loop), (gst_fakesrc_activate): * gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_getrange), (gst_filesrc_get), (gst_filesrc_loop): * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: (gst_caps_intersect): * gst/gstelement.c: (gst_element_pads_activate), (gst_element_change_state), (gst_element_create_task): * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstpad.c: (gst_real_pad_init), (gst_real_pad_get_property), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_set_loop_function), (gst_pad_set_getrange_function), (gst_pad_set_acceptcaps_function), (gst_pad_set_fixatecaps_function), (gst_pad_set_setcaps_function), (gst_pad_unlink), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_relink_filtered), (gst_pad_get_caps), (gst_pad_set_caps), (gst_pad_configure_sink), (gst_pad_configure_src), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_get_negotiated_caps), (gst_pad_get_filter_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler), (gst_pipeline_change_state), (gst_pipeline_get_scheduler), (gst_pipeline_get_bus): * gst/gstpipeline.h: * gst/gstqueue.c: (gst_queue_init), (gst_queue_locked_flush), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_src_activate), (gst_queue_change_state): * gst/gsttask.h: * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink), (gst_pad_can_link_filtered): * gst/schedulers/threadscheduler.c: (gst_thread_scheduler_func): * libs/gst/Makefile.am: * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): Correctly distribute clock/scheduler to elements Caps intersection improvement. MT fixes. Work on scheduling simplifications, get rid of _pull and prepare for scheduling setup. More work on capsnego.
2004-12-20 16:07:05 +00:00
static void gst_bin_set_bus (GstElement * element, GstBus * bus);
static void gst_bin_set_scheduler (GstElement * element, GstScheduler * sched);
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
#ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
#endif
/* Bin signals and args */
enum
{
ELEMENT_ADDED,
ELEMENT_REMOVED,
LAST_SIGNAL
};
enum
{
ARG_0
/* FILL ME */
};
static void gst_bin_base_init (gpointer g_class);
static void gst_bin_class_init (GstBinClass * klass);
static void gst_bin_init (GstBin * bin);
static GstElementClass *parent_class = NULL;
static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
/**
* gst_bin_get_type:
*
* Returns: the type of #GstBin
*/
GType
gst_bin_get_type (void)
{
if (!_gst_bin_type) {
static const GTypeInfo bin_info = {
sizeof (GstBinClass),
gst_bin_base_init,
NULL,
(GClassInitFunc) gst_bin_class_init,
NULL,
NULL,
sizeof (GstBin),
0,
(GInstanceInitFunc) gst_bin_init,
NULL
};
_gst_bin_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0);
GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD,
"debugging info for the 'bin' container element");
}
return _gst_bin_type;
}
static void
gst_bin_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_bin_details);
}
static void
gst_bin_class_init (GstBinClass * klass)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass *) klass;
gstobject_class = (GstObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
gst_bin_signals[ELEMENT_ADDED] =
g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_added), NULL,
NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
gst_bin_signals[ELEMENT_REMOVED] =
g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL,
NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose);
#ifndef GST_DISABLE_LOADSAVE
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_bin_save_thyself);
gstobject_class->restore_thyself =
GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
#endif
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state);
gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state);
#ifndef GST_DISABLE_INDEX
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index);
#endif
gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_bin_get_clock);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock);
Correctly distribute clock/scheduler to elements Original commit message from CVS: * gst/elements/gstfakesink.c: (gst_fakesink_event): * gst/elements/gstfakesrc.c: (gst_fakesrc_update_functions), (gst_fakesrc_loop), (gst_fakesrc_activate): * gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_getrange), (gst_filesrc_get), (gst_filesrc_loop): * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: (gst_caps_intersect): * gst/gstelement.c: (gst_element_pads_activate), (gst_element_change_state), (gst_element_create_task): * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstpad.c: (gst_real_pad_init), (gst_real_pad_get_property), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_set_loop_function), (gst_pad_set_getrange_function), (gst_pad_set_acceptcaps_function), (gst_pad_set_fixatecaps_function), (gst_pad_set_setcaps_function), (gst_pad_unlink), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_relink_filtered), (gst_pad_get_caps), (gst_pad_set_caps), (gst_pad_configure_sink), (gst_pad_configure_src), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_get_negotiated_caps), (gst_pad_get_filter_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler), (gst_pipeline_change_state), (gst_pipeline_get_scheduler), (gst_pipeline_get_bus): * gst/gstpipeline.h: * gst/gstqueue.c: (gst_queue_init), (gst_queue_locked_flush), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_src_activate), (gst_queue_change_state): * gst/gsttask.h: * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink), (gst_pad_can_link_filtered): * gst/schedulers/threadscheduler.c: (gst_thread_scheduler_func): * libs/gst/Makefile.am: * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): Correctly distribute clock/scheduler to elements Caps intersection improvement. MT fixes. Work on scheduling simplifications, get rid of _pull and prepare for scheduling setup. More work on capsnego.
2004-12-20 16:07:05 +00:00
gstelement_class->set_bus = GST_DEBUG_FUNCPTR (gst_bin_set_bus);
gstelement_class->set_scheduler = GST_DEBUG_FUNCPTR (gst_bin_set_scheduler);
klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
}
static void
gst_bin_init (GstBin * bin)
{
bin->numchildren = 0;
bin->children = NULL;
bin->children_cookie = 0;
}
/**
* gst_bin_new:
* @name: name of new bin
*
* Create a new bin with given name.
*
* Returns: new bin
*/
GstElement *
gst_bin_new (const gchar * name)
{
return gst_element_factory_make ("bin", name);
}
/* set the index on all elements in this bin
*
* MT safe
*/
#ifndef GST_DISABLE_INDEX
static void
gst_bin_set_index (GstElement * element, GstIndex * index)
{
GstBin *bin;
GList *children;
bin = GST_BIN (element);
GST_LOCK (bin);
for (children = bin->children; children; children = g_list_next (children)) {
GstElement *child = GST_ELEMENT (children->data);
gst_element_set_index (child, index);
}
GST_UNLOCK (bin);
}
#endif
/* set the clock on all elements in this bin
*
* MT safe
*/
static void
gst_bin_set_clock (GstElement * element, GstClock * clock)
{
GList *children;
GstBin *bin;
bin = GST_BIN (element);
GST_LOCK (bin);
for (children = bin->children; children; children = g_list_next (children)) {
GstElement *child = GST_ELEMENT (children->data);
gst_element_set_clock (child, clock);
}
GST_UNLOCK (bin);
}
/* get the clock for this bin by asking all of the children in this bin
*
* MT safe
*/
static GstClock *
gst_bin_get_clock (GstElement * element)
{
GstClock *result = NULL;
GstBin *bin;
GList *children;
bin = GST_BIN (element);
GST_LOCK (bin);
for (children = bin->children; children; children = g_list_next (children)) {
GstElement *child = GST_ELEMENT (children->data);
result = gst_element_get_clock (child);
if (result)
break;
}
GST_UNLOCK (bin);
return result;
}
/* set the bus on all of the children in this bin
*
* MT safe
*/
Correctly distribute clock/scheduler to elements Original commit message from CVS: * gst/elements/gstfakesink.c: (gst_fakesink_event): * gst/elements/gstfakesrc.c: (gst_fakesrc_update_functions), (gst_fakesrc_loop), (gst_fakesrc_activate): * gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_getrange), (gst_filesrc_get), (gst_filesrc_loop): * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: (gst_caps_intersect): * gst/gstelement.c: (gst_element_pads_activate), (gst_element_change_state), (gst_element_create_task): * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstpad.c: (gst_real_pad_init), (gst_real_pad_get_property), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_set_loop_function), (gst_pad_set_getrange_function), (gst_pad_set_acceptcaps_function), (gst_pad_set_fixatecaps_function), (gst_pad_set_setcaps_function), (gst_pad_unlink), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_relink_filtered), (gst_pad_get_caps), (gst_pad_set_caps), (gst_pad_configure_sink), (gst_pad_configure_src), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_get_negotiated_caps), (gst_pad_get_filter_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler), (gst_pipeline_change_state), (gst_pipeline_get_scheduler), (gst_pipeline_get_bus): * gst/gstpipeline.h: * gst/gstqueue.c: (gst_queue_init), (gst_queue_locked_flush), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_src_activate), (gst_queue_change_state): * gst/gsttask.h: * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink), (gst_pad_can_link_filtered): * gst/schedulers/threadscheduler.c: (gst_thread_scheduler_func): * libs/gst/Makefile.am: * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): Correctly distribute clock/scheduler to elements Caps intersection improvement. MT fixes. Work on scheduling simplifications, get rid of _pull and prepare for scheduling setup. More work on capsnego.
2004-12-20 16:07:05 +00:00
static void
gst_bin_set_bus (GstElement * element, GstBus * bus)
{
GList *children;
GstBin *bin;
bin = GST_BIN (element);
parent_class->set_bus (element, bus);
GST_LOCK (bin);
for (children = bin->children; children; children = g_list_next (children)) {
GstElement *child = GST_ELEMENT (children->data);
gst_element_set_bus (child, bus);
}
GST_UNLOCK (bin);
}
/* set the scheduler on all of the children in this bin
*
* MT safe
*/
Correctly distribute clock/scheduler to elements Original commit message from CVS: * gst/elements/gstfakesink.c: (gst_fakesink_event): * gst/elements/gstfakesrc.c: (gst_fakesrc_update_functions), (gst_fakesrc_loop), (gst_fakesrc_activate): * gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_getrange), (gst_filesrc_get), (gst_filesrc_loop): * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: (gst_caps_intersect): * gst/gstelement.c: (gst_element_pads_activate), (gst_element_change_state), (gst_element_create_task): * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstpad.c: (gst_real_pad_init), (gst_real_pad_get_property), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_set_loop_function), (gst_pad_set_getrange_function), (gst_pad_set_acceptcaps_function), (gst_pad_set_fixatecaps_function), (gst_pad_set_setcaps_function), (gst_pad_unlink), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_relink_filtered), (gst_pad_get_caps), (gst_pad_set_caps), (gst_pad_configure_sink), (gst_pad_configure_src), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_get_negotiated_caps), (gst_pad_get_filter_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler), (gst_pipeline_change_state), (gst_pipeline_get_scheduler), (gst_pipeline_get_bus): * gst/gstpipeline.h: * gst/gstqueue.c: (gst_queue_init), (gst_queue_locked_flush), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_src_activate), (gst_queue_change_state): * gst/gsttask.h: * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink), (gst_pad_can_link_filtered): * gst/schedulers/threadscheduler.c: (gst_thread_scheduler_func): * libs/gst/Makefile.am: * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): Correctly distribute clock/scheduler to elements Caps intersection improvement. MT fixes. Work on scheduling simplifications, get rid of _pull and prepare for scheduling setup. More work on capsnego.
2004-12-20 16:07:05 +00:00
static void
gst_bin_set_scheduler (GstElement * element, GstScheduler * sched)
{
GList *children;
GstBin *bin;
bin = GST_BIN (element);
parent_class->set_scheduler (element, sched);
GST_LOCK (bin);
for (children = bin->children; children; children = g_list_next (children)) {
GstElement *child = GST_ELEMENT (children->data);
gst_element_set_scheduler (child, sched);
}
GST_UNLOCK (bin);
}
/* add an element to this bin
*
* MT safe
*/
static gboolean
gst_bin_add_func (GstBin * bin, GstElement * element)
{
gchar *elem_name;
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
/* we obviously can't add ourself to ourself */
if (G_UNLIKELY (GST_ELEMENT_CAST (element) == GST_ELEMENT_CAST (bin)))
goto adding_itself;
/* get the element name to make sure it is unique in this bin, FIXME, another
* thread can change the name after the unlock. */
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
GST_LOCK (element);
elem_name = g_strdup (GST_ELEMENT_NAME (element));
GST_UNLOCK (element);
GST_LOCK (bin);
/* then check to see if the element's name is already taken in the bin,
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
* we can safely take the lock here. This check is probably bogus because
* you can safely change the element name after adding it to the bin. */
if (G_UNLIKELY (gst_object_check_uniqueness (bin->children,
elem_name) == FALSE))
goto duplicate_name;
/* set the element's parent and add the element to the bin's list of children */
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT (element),
GST_OBJECT (bin))))
goto had_parent;
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
bin->children = g_list_prepend (bin->children, element);
bin->numchildren++;
bin->children_cookie++;
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
Correctly distribute clock/scheduler to elements Original commit message from CVS: * gst/elements/gstfakesink.c: (gst_fakesink_event): * gst/elements/gstfakesrc.c: (gst_fakesrc_update_functions), (gst_fakesrc_loop), (gst_fakesrc_activate): * gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_getrange), (gst_filesrc_get), (gst_filesrc_loop): * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: (gst_caps_intersect): * gst/gstelement.c: (gst_element_pads_activate), (gst_element_change_state), (gst_element_create_task): * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstpad.c: (gst_real_pad_init), (gst_real_pad_get_property), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_set_loop_function), (gst_pad_set_getrange_function), (gst_pad_set_acceptcaps_function), (gst_pad_set_fixatecaps_function), (gst_pad_set_setcaps_function), (gst_pad_unlink), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_relink_filtered), (gst_pad_get_caps), (gst_pad_set_caps), (gst_pad_configure_sink), (gst_pad_configure_src), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_get_negotiated_caps), (gst_pad_get_filter_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler), (gst_pipeline_change_state), (gst_pipeline_get_scheduler), (gst_pipeline_get_bus): * gst/gstpipeline.h: * gst/gstqueue.c: (gst_queue_init), (gst_queue_locked_flush), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_src_activate), (gst_queue_change_state): * gst/gsttask.h: * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink), (gst_pad_can_link_filtered): * gst/schedulers/threadscheduler.c: (gst_thread_scheduler_func): * libs/gst/Makefile.am: * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): Correctly distribute clock/scheduler to elements Caps intersection improvement. MT fixes. Work on scheduling simplifications, get rid of _pull and prepare for scheduling setup. More work on capsnego.
2004-12-20 16:07:05 +00:00
gst_element_set_manager (element, GST_ELEMENT (bin)->manager);
gst_element_set_bus (element, GST_ELEMENT (bin)->bus);
gst_element_set_scheduler (element, GST_ELEMENT (bin)->scheduler);
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
GST_UNLOCK (bin);
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
elem_name);
g_free (elem_name);
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_ADDED], 0, element);
return TRUE;
/* ERROR handling here */
adding_itself:
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
GST_LOCK (bin);
g_warning ("Cannot add bin %s to itself", GST_ELEMENT_NAME (bin));
GST_UNLOCK (bin);
return FALSE;
duplicate_name:
g_warning ("Name %s is not unique in bin %s, not adding",
elem_name, GST_ELEMENT_NAME (bin));
GST_UNLOCK (bin);
g_free (elem_name);
return FALSE;
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
had_parent:
g_warning ("Element %s already has parent", elem_name);
GST_UNLOCK (bin);
g_free (elem_name);
return FALSE;
}
/**
* gst_bin_add:
* @bin: #GstBin to add element to
* @element: #GstElement to add to bin
*
* Adds the given element to the bin. Sets the element's parent, and thus
* takes ownership of the element. An element can only be added to one bin.
*
* Returns: TRUE if the element could be added, FALSE on wrong parameters or
* the bin does not want to accept the element.
*
* MT safe.
*/
gboolean
gst_bin_add (GstBin * bin, GstElement * element)
{
GstBinClass *bclass;
gboolean result;
g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
bclass = GST_BIN_GET_CLASS (bin);
if (G_UNLIKELY (bclass->add_element == NULL))
goto no_function;
GST_CAT_DEBUG (GST_CAT_PARENTAGE, "adding element %s to bin %s",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
result = bclass->add_element (bin, element);
return result;
no_function:
g_warning ("adding elements to bin %s is not supported",
GST_ELEMENT_NAME (bin));
return FALSE;
}
/* remove an element from the bin
*
* MT safe
*/
static gboolean
gst_bin_remove_func (GstBin * bin, GstElement * element)
{
gchar *elem_name;
/* grab element name so we can print it */
GST_LOCK (element);
elem_name = g_strdup (GST_ELEMENT_NAME (element));
GST_UNLOCK (element);
GST_LOCK (bin);
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
/* the element must be in the bin's list of children */
if (G_UNLIKELY (g_list_find (bin->children, element) == NULL))
goto not_in_bin;
/* now remove the element from the list of elements */
bin->children = g_list_remove (bin->children, element);
bin->numchildren--;
bin->children_cookie++;
GST_UNLOCK (bin);
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
elem_name);
g_free (elem_name);
gst_element_set_manager (element, NULL);
gst_element_set_bus (element, NULL);
gst_element_set_scheduler (element, NULL);
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
/* we ref here because after the _unparent() the element can be disposed
* and we still need it to fire a signal. */
gst_object_ref (GST_OBJECT (element));
gst_object_unparent (GST_OBJECT (element));
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element);
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
gst_object_unref (GST_OBJECT (element));
return TRUE;
not_in_bin:
g_warning ("Element %s is not in bin %s", elem_name, GST_ELEMENT_NAME (bin));
GST_UNLOCK (bin);
g_free (elem_name);
return FALSE;
}
/**
* gst_bin_remove:
* @bin: #GstBin to remove element from
* @element: #GstElement to remove
*
* Remove the element from its associated bin, unparenting it as well.
* Unparenting the element means that the element will be dereferenced,
* so if the bin holds the only reference to the element, the element
* will be freed in the process of removing it from the bin. If you
* want the element to still exist after removing, you need to call
* #gst_object_ref before removing it from the bin.
*
* Returns: TRUE if the element could be removed, FALSE on wrong parameters or
* the bin does not want to remove the element.
*
* MT safe.
*/
gboolean
gst_bin_remove (GstBin * bin, GstElement * element)
{
GstBinClass *bclass;
gboolean result;
g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
bclass = GST_BIN_GET_CLASS (bin);
if (G_UNLIKELY (bclass->remove_element == NULL))
goto no_function;
GST_CAT_DEBUG (GST_CAT_PARENTAGE, "removing element %s from bin %s",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
result = bclass->remove_element (bin, element);
return result;
no_function:
g_warning ("removing elements from bin %s is not supported",
GST_ELEMENT_NAME (bin));
return FALSE;
}
static GstIteratorItem
iterate_child (GstIterator * it, GstElement * child)
{
gst_object_ref (GST_OBJECT (child));
return GST_ITERATOR_ITEM_PASS;
}
/**
* gst_bin_iterate_elements:
* @bin: #Gstbin to iterate the elements of
*
* Get an iterator for the elements in this bin.
* Each element will have its refcount increased, so unref
* after usage.
*
* Returns: a #GstIterator of #GstElements. gst_iterator_free after
* use. returns NULL when passing bad parameters.
*
* MT safe.
*/
GstIterator *
gst_bin_iterate_elements (GstBin * bin)
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
{
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
GstIterator *result;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
GST_LOCK (bin);
/* add ref because the iterator refs the bin. When the iterator
* is freed it will unref the bin again using the provided dispose
* function. */
gst_object_ref (GST_OBJECT (bin));
result = gst_iterator_new_list (GST_GET_LOCK (bin),
&bin->children_cookie,
&bin->children,
bin,
(GstIteratorItemFunction) iterate_child,
(GstIteratorDisposeFunction) gst_object_unref);
GST_UNLOCK (bin);
return result;
}
static GstIteratorItem
iterate_child_recurse (GstIterator * it, GstElement * child)
{
gst_object_ref (GST_OBJECT (child));
if (GST_IS_BIN (child)) {
GstIterator *other = gst_bin_iterate_recurse (GST_BIN (child));
gst_iterator_push (it, other);
}
return GST_ITERATOR_ITEM_PASS;
}
/**
* gst_bin_iterate_recurse:
* @bin: #Gstbin to iterate the elements of
*
* Get an iterator for the elements in this bin.
* Each element will have its refcount increased, so unref
* after usage. This iterator recurses into GstBin children.
*
* Returns: a #GstIterator of #GstElements. gst_iterator_free after
* use. returns NULL when passing bad parameters.
*
* MT safe.
*/
GstIterator *
gst_bin_iterate_recurse (GstBin * bin)
{
GstIterator *result;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
GST_LOCK (bin);
/* add ref because the iterator refs the bin. When the iterator
* is freed it will unref the bin again using the provided dispose
* function. */
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
gst_object_ref (GST_OBJECT (bin));
result = gst_iterator_new_list (GST_GET_LOCK (bin),
&bin->children_cookie,
&bin->children,
bin,
(GstIteratorItemFunction) iterate_child_recurse,
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
(GstIteratorDisposeFunction) gst_object_unref);
GST_UNLOCK (bin);
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
return result;
return NULL;
}
GstIterator *
gst_bin_iterate_recurse_up (GstBin * bin)
{
return NULL;
}
/* returns 0 if the element is a sink, this is made so that
* we can use this function as a filter
*
* MT safe
*/
static gint
bin_element_is_sink (GstElement * child, GstBin * bin)
{
gint ret = 1;
/* we lock the child here for the remainder of the function to
* get its pads and name safely. */
GST_LOCK (child);
/* check if this is a sink element, these are the elements
* without (linked) source pads. */
if (child->numsrcpads == 0) {
/* shortcut */
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
"adding child %s as sink", GST_OBJECT_NAME (child));
ret = 0;
} else {
/* loop over all pads, try to figure out if this element
* is a sink because it has no linked source pads */
GList *pads;
gboolean connected_src = FALSE;
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
GstPad *peer;
peer = gst_pad_get_peer (GST_PAD_CAST (pads->data));
if (peer) {
GstElement *parent;
parent = gst_pad_get_parent (peer);
if (parent) {
GstObject *grandparent;
grandparent = gst_object_get_parent (GST_OBJECT_CAST (parent));
if (grandparent == GST_OBJECT_CAST (bin)) {
connected_src = TRUE;
}
if (grandparent) {
gst_object_unref (GST_OBJECT_CAST (grandparent));
}
gst_object_unref (GST_OBJECT_CAST (parent));
}
gst_object_unref (GST_OBJECT_CAST (peer));
if (connected_src) {
break;
}
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
}
}
if (connected_src) {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
"not adding child %s as sink: linked source pads",
GST_OBJECT_NAME (child));
} else {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
"adding child %s as sink since it has unlinked source pads in this bin",
GST_OBJECT_NAME (child));
ret = 0;
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
}
}
GST_UNLOCK (child);
/* we did not find the element, need to release the ref
* added by the iterator */
if (ret == 1)
gst_object_unref (GST_OBJECT (child));
return ret;
}
/**
* gst_bin_iterate_sinks:
* @bin: #Gstbin to iterate on
*
* Get an iterator for the sink elements in this bin.
* Each element will have its refcount increased, so unref
* after usage.
*
* Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
*
* MT safe.
*/
GstIterator *
gst_bin_iterate_sinks (GstBin * bin)
{
GstIterator *children;
GstIterator *result;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
children = gst_bin_iterate_elements (bin);
result = gst_iterator_filter (children, bin,
(GCompareFunc) bin_element_is_sink);
return result;
}
/* this functions loops over all children, as soon as one does
* not return SUCCESS, we return that value.
*
* MT safe
*/
static GstElementStateReturn
gst_bin_get_state (GstElement * element, GstElementState * state,
GstElementState * pending, GTimeVal * timeout)
{
GstBin *bin = GST_BIN (element);
GstElementStateReturn ret;
GList *children;
guint32 children_cookie;
/* we cannot take the state lock yet as we might block when querying
* the children, holding the lock too long for no reason. */
/* next we poll all children for their state to see if one of them
* is still busy with its state change. */
GST_LOCK (bin);
restart:
ret = GST_STATE_SUCCESS;
children = bin->children;
children_cookie = bin->children_cookie;
while (children) {
GstElement *child = GST_ELEMENT_CAST (children->data);
gst_object_ref (GST_OBJECT_CAST (child));
GST_UNLOCK (bin);
/* ret is ASYNC if some child is still performing the state change */
ret = gst_element_get_state (child, NULL, NULL, timeout);
gst_object_unref (GST_OBJECT_CAST (child));
if (ret != GST_STATE_SUCCESS) {
/* some child is still busy or in error, we can report that
* right away. */
goto done;
}
/* now grab the lock to iterate to the next child */
GST_LOCK (bin);
if (G_UNLIKELY (children_cookie != bin->children_cookie))
/* child added/removed during state change, restart */
goto restart;
children = g_list_next (children);
}
GST_UNLOCK (bin);
done:
/* now we can take the state lock */
GST_STATE_LOCK (bin);
switch (ret) {
case GST_STATE_SUCCESS:
/* we can commit the state */
gst_element_commit_state (element);
break;
case GST_STATE_FAILURE:
/* some element failed, abort the state change */
gst_element_abort_state (element);
break;
default:
/* other cases are just passed along */
break;
}
/* and report the state if needed */
if (state)
*state = GST_STATE (element);
if (pending)
*pending = GST_STATE_PENDING (element);
GST_STATE_UNLOCK (bin);
return ret;
}
/* this function is called with the STATE_LOCK held. It works
* as follows:
*
* 1) put all sink elements on the queue.
* 2) change state of elements in queue, put linked elements to queue.
* 3) while queue not empty goto 2)
*
* This will effectively change the state of all elements in the bin
* from the sinks to the sources. We have to change the states this
* way so that when a source element pushes data, the downstream element
* is in the right state to receive the data.
*
* MT safe.
*/
static GstElementStateReturn
gst_bin_change_state (GstElement * element)
{
GstBin *bin;
GstElementStateReturn ret;
GstElementState old_state, pending;
gboolean have_async = FALSE;
GList *children;
guint32 children_cookie;
GQueue *elem_queue; /* list of elements waiting for a state change */
bin = GST_BIN (element);
/* we don't need to take the STATE_LOCK, it is already taken */
old_state = GST_STATE (element);
pending = GST_STATE_PENDING (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"changing state of children from %s to %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (pending));
if (pending == GST_STATE_VOID_PENDING)
return GST_STATE_SUCCESS;
/* all elements added to this queue should have their refcount
* incremented */
elem_queue = g_queue_new ();
/* first step, find all sink elements, these are the elements
* without (linked) source pads. */
GST_LOCK (bin);
restart:
children = bin->children;
children_cookie = bin->children_cookie;
while (children) {
GstElement *child = GST_ELEMENT_CAST (children->data);
gst_object_ref (GST_OBJECT_CAST (child));
GST_UNLOCK (bin);
if (bin_element_is_sink (child, bin) == 0) {
/* this also keeps the refcount on the element, note that
* the _is_sink function unrefs the element when it is not
* a sink. */
g_queue_push_tail (elem_queue, child);
}
GST_LOCK (bin);
if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
/* undo what we had */
g_queue_foreach (elem_queue, (GFunc) gst_object_unref, NULL);
while (g_queue_pop_head (elem_queue));
goto restart;
}
children = g_list_next (children);
}
GST_UNLOCK (bin);
/* second step, change state of elements in the queue */
while (!g_queue_is_empty (elem_queue)) {
GstElement *qelement = g_queue_pop_head (elem_queue);
GList *pads;
gboolean locked;
/* queue all elements connected to the sinkpads of this element */
GST_LOCK (qelement);
pads = qelement->sinkpads;
while (pads) {
GstPad *pad = GST_PAD_CAST (pads->data);
GstPad *peer;
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"found sinkpad %s:%s", GST_DEBUG_PAD_NAME (pad));
peer = gst_pad_get_peer (pad);
if (peer) {
GstObject *peer_elem;
peer_elem = gst_object_get_parent (GST_OBJECT_CAST (peer));
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
if (peer_elem) {
GstObject *parent;
/* see if this element is in the bin we are currently handling */
parent = gst_object_get_parent (GST_OBJECT_CAST (peer_elem));
if (parent && parent == GST_OBJECT_CAST (bin)) {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"adding element %s to queue", GST_ELEMENT_NAME (peer_elem));
/* was reffed before pushing on the queue by the
* gst_object_get_parent() call we used to get the element. */
g_queue_push_tail (elem_queue, peer_elem);
} else {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"not adding element %s to queue, it is in another bin",
GST_ELEMENT_NAME (peer_elem));
}
if (parent) {
gst_object_unref (GST_OBJECT_CAST (parent));
}
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
}
gst_object_unref (GST_OBJECT_CAST (peer));
} else {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"pad %s:%s does not have a peer", GST_DEBUG_PAD_NAME (pad));
}
pads = g_list_next (pads);
}
/* peel off the locked flag and release the element lock */
locked = GST_FLAG_IS_SET (qelement, GST_ELEMENT_LOCKED_STATE);
GST_UNLOCK (qelement);
if (G_UNLIKELY (locked))
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
goto next_element;
qelement->base_time = element->base_time;
ret = gst_element_set_state (qelement, pending);
switch (ret) {
case GST_STATE_SUCCESS:
GST_CAT_DEBUG (GST_CAT_STATES,
"child '%s' changed state to %d(%s) successfully",
GST_ELEMENT_NAME (qelement), pending,
gst_element_state_get_name (pending));
break;
case GST_STATE_ASYNC:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"child '%s' is changing state asynchronously",
GST_ELEMENT_NAME (qelement));
have_async = TRUE;
break;
case GST_STATE_FAILURE:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"child '%s' failed to go to state %d(%s)",
GST_ELEMENT_NAME (qelement),
pending, gst_element_state_get_name (pending));
ret = GST_STATE_FAILURE;
/* release refcount of element we popped off the queue */
gst_object_unref (GST_OBJECT (qelement));
goto exit;
default:
g_assert_not_reached ();
break;
}
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
next_element:
gst_object_unref (GST_OBJECT (qelement));
}
if (have_async) {
ret = GST_STATE_ASYNC;
} else {
if (parent_class->change_state) {
ret = parent_class->change_state (element);
} else {
ret = GST_STATE_SUCCESS;
}
if (ret == GST_STATE_SUCCESS) {
/* we can commit the state change now */
gst_element_commit_state (element);
}
}
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"done changing bin's state from %s to %s, now in %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (pending),
gst_element_state_get_name (GST_STATE (element)));
exit:
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
/* release refcounts in queue, should normally be empty */
g_queue_foreach (elem_queue, (GFunc) gst_object_unref, NULL);
g_queue_free (elem_queue);
return ret;
}
static void
gst_bin_dispose (GObject * object)
{
GstBin *bin = GST_BIN (object);
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Original commit message from CVS: * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_dispose), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (pad_compare_name), (gst_element_get_static_pad), (gst_element_get_request_pad), (gst_element_get_pad), (gst_element_iterate_pads), (gst_element_class_get_pad_template_list), (gst_element_class_get_pad_template), (gst_element_get_random_pad), (gst_element_get_event_masks), (gst_element_send_event), (gst_element_seek), (gst_element_get_query_types), (gst_element_query), (gst_element_get_formats), (gst_element_convert), (gst_element_post_message), (gst_element_set_locked_state), (gst_element_get_state), (gst_element_set_state), (gst_element_pads_activate), (gst_element_dispose), (gst_element_set_manager_func), (gst_element_get_manager): * gst/gstelement.h: * gst/gstiterator.c: (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list): * gst/gstiterator.h: * gst/gstmessage.c: (_gst_message_copy): * gst/gstobject.c: (gst_object_class_init), (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_replace), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_dispose), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_is_blocked), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler): * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink): * gst/parse/grammar.y: * tools/gst-compprep.c: (main): * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): More MT fixes, added design document describing refcounting policies used in GStreamer and locking involved. Fixed unsafe ghostpad dereffing. Removed old unsafe methods.
2004-12-13 11:33:55 +00:00
/* ref to not hit 0 again */
gst_object_ref (GST_OBJECT (object));
while (bin->children) {
gst_bin_remove (bin, GST_ELEMENT (bin->children->data));
}
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose no children");
g_assert (bin->children == NULL);
g_assert (bin->numchildren == 0);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static gint
compare_name (GstElement * element, const gchar * name)
{
gint eq;
GST_LOCK (element);
eq = strcmp (GST_ELEMENT_NAME (element), name) == 0;
GST_UNLOCK (element);
if (eq != 0) {
gst_object_unref (GST_OBJECT (element));
}
return eq;
}
/**
* gst_bin_get_by_name:
* @bin: #Gstbin to search
* @name: the element name to search for
*
* Get the element with the given name from this bin. This
* function recurses into subbins.
*
* Returns: the element with the given name. Returns NULL if the
* element is not found or when bad parameters were given. Unref after
* usage.
*
* MT safe.
*/
GstElement *
gst_bin_get_by_name (GstBin * bin, const gchar * name)
{
GstIterator *children;
GstIterator *result;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
children = gst_bin_iterate_recurse (bin);
result = gst_iterator_find_custom (children, (gpointer) name,
(GCompareFunc) compare_name);
return GST_ELEMENT_CAST (result);
}
/**
* gst_bin_get_by_name_recurse_up:
* @bin: #Gstbin to search
* @name: the element name to search for
*
* Get the element with the given name from this bin. If the
* element is not found, a recursion is performed on the parent bin.
*
* Returns: the element with the given name or NULL when the element
* was not found or bad parameters were given. Unref after usage.
*
* MT safe.
*/
GstElement *
gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
{
GstElement *result;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
g_return_val_if_fail (name != NULL, NULL);
result = gst_bin_get_by_name (bin, name);
if (!result) {
GstObject *parent;
parent = gst_object_get_parent (GST_OBJECT_CAST (bin));
if (parent && GST_IS_BIN (parent)) {
result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name);
}
gst_object_unref (parent);
}
return result;
}
static gint
compare_interface (GstElement * element, gpointer interface)
{
gint ret;
if (G_TYPE_CHECK_INSTANCE_TYPE (element, GPOINTER_TO_INT (interface))) {
ret = 0;
} else {
/* we did not find the element, need to release the ref
* added by the iterator */
gst_object_unref (GST_OBJECT (element));
ret = 1;
}
return ret;
}
/**
* gst_bin_get_by_interface:
* @bin: bin to find element in
* @interface: interface to be implemented by interface
*
* Looks for the first element inside the bin that implements the given
* interface. If such an element is found, it returns the element. You can
* cast this element to the given interface afterwards.
* If you want all elements that implement the interface, use
* gst_bin_iterate_all_by_interface(). The function recurses bins inside bins.
*
* Returns: An element inside the bin implementing the interface. Unref after
* usage.
*
* MT safe.
*/
GstElement *
gst_bin_get_by_interface (GstBin * bin, GType interface)
{
GstIterator *children;
GstIterator *result;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
children = gst_bin_iterate_recurse (bin);
result = gst_iterator_find_custom (children, GINT_TO_POINTER (interface),
(GCompareFunc) compare_interface);
return GST_ELEMENT_CAST (result);
}
/**
* gst_bin_get_all_by_interface:
* @bin: bin to find elements in
* @interface: interface to be implemented by interface
*
* Looks for all elements inside the bin that implements the given
* interface. You can safely cast all returned elements to the given interface.
* The function recurses bins inside bins. The iterator will return a series
* of #GstElement that should be unreffed after usage.
*
* Returns: An iterator for the elements inside the bin implementing the interface.
*
*/
GstIterator *
gst_bin_iterate_all_by_interface (GstBin * bin, GType interface)
{
GstIterator *children;
GstIterator *result;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
children = gst_bin_iterate_recurse (bin);
result = gst_iterator_filter (children, GINT_TO_POINTER (interface),
(GCompareFunc) compare_interface);
return result;
}
#ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr
gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
{
GstBin *bin = GST_BIN (object);
xmlNodePtr childlist, elementnode;
GList *children;
GstElement *child;
if (GST_OBJECT_CLASS (parent_class)->save_thyself)
GST_OBJECT_CLASS (parent_class)->save_thyself (GST_OBJECT (bin), parent);
childlist = xmlNewChild (parent, NULL, "children", NULL);
GST_CAT_INFO (GST_CAT_XML, "[%s]: saving %d children",
GST_ELEMENT_NAME (bin), bin->numchildren);
children = bin->children;
while (children) {
child = GST_ELEMENT (children->data);
elementnode = xmlNewChild (childlist, NULL, "element", NULL);
gst_object_save_thyself (GST_OBJECT (child), elementnode);
children = g_list_next (children);
}
return childlist;
}
static void
gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
{
GstBin *bin = GST_BIN (object);
xmlNodePtr field = self->xmlChildrenNode;
xmlNodePtr childlist;
while (field) {
if (!strcmp (field->name, "children")) {
GST_CAT_INFO (GST_CAT_XML, "[%s]: loading children",
GST_ELEMENT_NAME (object));
childlist = field->xmlChildrenNode;
while (childlist) {
if (!strcmp (childlist->name, "element")) {
GstElement *element =
gst_xml_make_element (childlist, GST_OBJECT (bin));
/* it had to be parented to find the pads, now we ref and unparent so
* we can add it to the bin */
gst_object_ref (GST_OBJECT (element));
gst_object_unparent (GST_OBJECT (element));
gst_bin_add (bin, element);
}
childlist = childlist->next;
}
}
field = field->next;
}
if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
(GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
}
#endif /* GST_DISABLE_LOADSAVE */