GST_OBJECT_UNLOCK (bin);
/* post message */
- gst_element_post_message (GST_ELEMENT_CAST (bin),
- gst_message_new_state_changed (GST_OBJECT_CAST (bin),
- new_state, new_state, new_state));
+ _priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), new_state, new_state,
+ new_state);
post_start:
if (amessage) {
GstState current, pending, target;
GstStateChangeReturn old_ret;
GstState old_state, old_next;
- gboolean toplevel;
- GstMessage *smessage = NULL, *amessage = NULL;
+ gboolean toplevel, state_changed = FALSE;
+ GstMessage *amessage = NULL;
BinContinueData *cont = NULL;
if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
if (old_next != GST_STATE_PLAYING) {
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
- smessage = gst_message_new_state_changed (GST_OBJECT_CAST (bin),
- old_state, old_next, pending);
+ state_changed = TRUE;
}
}
GST_OBJECT_UNLOCK (bin);
- if (smessage) {
- GST_DEBUG_OBJECT (bin, "posting state change message");
- gst_element_post_message (GST_ELEMENT_CAST (bin), smessage);
+ if (state_changed) {
+ _priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), old_state,
+ old_next, pending);
}
if (amessage) {
/* post our combined ASYNC_DONE when all is ASYNC_DONE. */
}
}
+/* Not static because GstBin has manual state handling too */
+void
+_priv_gst_element_state_changed (GstElement * element, GstState oldstate,
+ GstState newstate, GstState pending)
+{
+ GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
+ GstMessage *message;
+
+ GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+ "notifying about state-changed %s to %s (%s pending)",
+ gst_element_state_get_name (oldstate),
+ gst_element_state_get_name (newstate),
+ gst_element_state_get_name (pending));
+
+ if (klass->state_changed)
+ klass->state_changed (element, oldstate, newstate, pending);
+
+ message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
+ oldstate, newstate, pending);
+ gst_element_post_message (element, message);
+}
+
/**
* gst_element_continue_state:
* @element: a #GstElement to continue the state change of.
GstStateChangeReturn old_ret;
GstState old_state, old_next;
GstState current, next, pending;
- GstMessage *message;
GstStateChange transition;
GST_OBJECT_LOCK (element);
gst_element_state_get_name (old_next),
gst_element_state_get_name (pending), gst_element_state_get_name (next));
- message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
- old_state, old_next, pending);
- gst_element_post_message (element, message);
+ _priv_gst_element_state_changed (element, old_state, old_next, pending);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"continue state change %s to %s, final %s",
* previous return value.
* We do signal the cond though as a _get_state() might be blocking
* on it. */
- if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
- GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
- "posting state-changed %s to %s",
- gst_element_state_get_name (old_state),
- gst_element_state_get_name (old_next));
- message =
- gst_message_new_state_changed (GST_OBJECT_CAST (element), old_state,
- old_next, GST_STATE_VOID_PENDING);
- gst_element_post_message (element, message);
- }
+ if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
+ _priv_gst_element_state_changed (element, old_state, old_next,
+ GST_STATE_VOID_PENDING);
GST_STATE_BROADCAST (element);
GST_ELEMENT_START_TIME (element) = 0;
GST_OBJECT_UNLOCK (element);
- message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
- new_state, new_state, new_state);
- gst_element_post_message (element, message);
+ _priv_gst_element_state_changed (element, new_state, new_state, new_state);
message =
gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time);
* @get_query_types: get the supported #GstQueryType of this element
* @query: perform a #GstQuery on the element
* @request_new_pad_full: called when a new pad is requested. Since: 0.10.32.
+ * @state_changed: called immediately after a new state was set. Since: 0.10.34.
*
* GStreamer element class. Override the vmethods to implement the element
* functionality.
GstPad* (*request_new_pad_full) (GstElement *element, GstPadTemplate *templ,
const gchar* name, const GstCaps *caps);
+ void (*state_changed) (GstElement *element, GstState oldstate,
+ GstState newstate, GstState pending);
+
/*< private >*/
- gpointer _gst_reserved[GST_PADDING-2];
+ gpointer _gst_reserved[GST_PADDING-3];
};
/* element class pad templates */