diff --git a/ChangeLog b/ChangeLog index 9546703920..772f969072 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-10-18 Wim Taymans + + * gst/gstbin.c: (gst_bin_class_init), (gst_bin_get_state_func), + (gst_bin_recalc_func): + * gst/gstelement.c: (gst_element_set_clock), + (gst_element_abort_state), (gst_element_lost_state): + Cleanups, prepare for state change fixes. + 2005-10-18 Wim Taymans * gst/gstbin.h: diff --git a/gst/gstbin.c b/gst/gstbin.c index 63ea14422e..765c8403eb 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -104,6 +104,7 @@ static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent); static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self); #endif +static void gst_bin_recalc_func (GstBin * child, gpointer data); static gint bin_element_is_sink (GstElement * child, GstBin * bin); /* Bin signals and properties */ @@ -224,6 +225,7 @@ gst_bin_class_init (GstBinClass * klass) GObjectClass *gobject_class; GstObjectClass *gstobject_class; GstElementClass *gstelement_class; + GError *err; gobject_class = (GObjectClass *) klass; gstobject_class = (GstObjectClass *) klass; @@ -277,6 +279,14 @@ gst_bin_class_init (GstBinClass * klass) klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func); klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func); + + GST_DEBUG ("creating bin thread pool"); + err = NULL; + klass->pool = + g_thread_pool_new ((GFunc) gst_bin_recalc_func, NULL, 1, FALSE, &err); + if (err != NULL) { + g_critical ("could alloc threadpool %s", err->message); + } } static void @@ -916,13 +926,16 @@ gst_bin_get_state_func (GstElement * element, GstState * state, GstState * pending, GstClockTime timeout) { GstBin *bin = GST_BIN (element); + GstStateChangeReturn ret; - GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state"); + GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin, "getting state"); /* do a non forced recalculation of the state */ gst_bin_recalc_state (bin, FALSE); - return parent_class->get_state (element, state, pending, timeout); + ret = parent_class->get_state (element, state, pending, timeout); + + return ret; } static void @@ -1560,6 +1573,17 @@ gst_bin_send_event (GstElement * element, GstEvent * event) return res; } +static void +gst_bin_recalc_func (GstBin * bin, gpointer data) +{ + GST_DEBUG_OBJECT (bin, "doing state recalc"); + GST_STATE_LOCK (bin); + gst_bin_recalc_state (bin, FALSE); + GST_STATE_UNLOCK (bin); + GST_DEBUG_OBJECT (bin, "state recalc done"); + gst_object_unref (bin); +} + static GstBusSyncReply bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin) { diff --git a/gst/gstelement.c b/gst/gstelement.c index f4978cc6df..f9366e9588 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -397,6 +397,8 @@ gst_element_set_clock (GstElement * element, GstClock * clock) oclass = GST_ELEMENT_GET_CLASS (element); + GST_DEBUG_OBJECT (element, "setting clock %p", clock); + if (oclass->set_clock) oclass->set_clock (element, clock); @@ -1748,23 +1750,35 @@ gst_element_abort_state (GstElement * element) { GstState pending; +#ifndef GST_DISABLE_GST_DEBUG + GstState old_state; +#endif g_return_if_fail (GST_IS_ELEMENT (element)); pending = GST_STATE_PENDING (element); - if (pending != GST_STATE_VOID_PENDING && - GST_STATE_RETURN (element) != GST_STATE_CHANGE_FAILURE) { + if (pending == GST_STATE_VOID_PENDING || + GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE) + goto nothing_aborted; + #ifndef GST_DISABLE_GST_DEBUG - GstState old_state = GST_STATE (element); + old_state = GST_STATE (element); + + GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, + "aborting state from %s to %s", gst_element_state_get_name (old_state), + gst_element_state_get_name (pending)); #endif - GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, - "aborting state from %s to %s", gst_element_state_get_name (old_state), - gst_element_state_get_name (pending)); - /* flag error */ - GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE; + /* flag error */ + GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE; - GST_STATE_BROADCAST (element); + GST_STATE_BROADCAST (element); + + return; + +nothing_aborted: + { + return; } } @@ -1888,25 +1902,33 @@ gst_element_commit_state (GstElement * element) void gst_element_lost_state (GstElement * element) { + GstState current_state; + GstMessage *message; + g_return_if_fail (GST_IS_ELEMENT (element)); - if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING && - GST_STATE_RETURN (element) != GST_STATE_CHANGE_FAILURE) { - GstState current_state; - GstMessage *message; + if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING || + GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE) + goto nothing_lost; - current_state = GST_STATE (element); + current_state = GST_STATE (element); - GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, - "lost state of %s", gst_element_state_get_name (current_state)); + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, + "lost state of %s", gst_element_state_get_name (current_state)); - GST_STATE_NEXT (element) = current_state; - GST_STATE_PENDING (element) = current_state; - GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC; + GST_STATE_NEXT (element) = current_state; + GST_STATE_PENDING (element) = current_state; + GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC; - message = gst_message_new_state_changed (GST_OBJECT (element), - FALSE, current_state, current_state, current_state); - gst_element_post_message (element, message); + message = gst_message_new_state_changed (GST_OBJECT (element), + FALSE, current_state, current_state, current_state); + gst_element_post_message (element, message); + + return; + +nothing_lost: + { + return; } }