mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 20:42:30 +00:00
element: Add GstElement::state_changed vfunc
API: GstElement::state_changed This is always called when the state of an element has changed and before the corresponding state-changed message is posted on the bus.
This commit is contained in:
parent
3c760a3ee5
commit
3872b816d2
4 changed files with 47 additions and 28 deletions
|
@ -51,6 +51,9 @@ extern const char g_log_domain_gstreamer[];
|
||||||
/* for the pad cache */
|
/* for the pad cache */
|
||||||
#include "gstpad.h"
|
#include "gstpad.h"
|
||||||
|
|
||||||
|
/* for GstElement */
|
||||||
|
#include "gstelement.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
/* used by gstparse.c and grammar.y */
|
/* used by gstparse.c and grammar.y */
|
||||||
|
@ -113,6 +116,10 @@ gboolean _gst_plugin_loader_client_run (void);
|
||||||
|
|
||||||
void _priv_gst_pad_invalidate_cache (GstPad *pad);
|
void _priv_gst_pad_invalidate_cache (GstPad *pad);
|
||||||
|
|
||||||
|
/* Used in GstBin for manual state handling */
|
||||||
|
void _priv_gst_element_state_changed (GstElement *element, GstState oldstate,
|
||||||
|
GstState newstate, GstState pending);
|
||||||
|
|
||||||
/* used in both gststructure.c and gstcaps.c; numbers are completely made up */
|
/* used in both gststructure.c and gstcaps.c; numbers are completely made up */
|
||||||
#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + (s)->fields->len * 22)
|
#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + (s)->fields->len * 22)
|
||||||
|
|
||||||
|
|
18
gst/gstbin.c
18
gst/gstbin.c
|
@ -2828,9 +2828,8 @@ bin_handle_async_start (GstBin * bin, gboolean new_base_time)
|
||||||
GST_OBJECT_UNLOCK (bin);
|
GST_OBJECT_UNLOCK (bin);
|
||||||
|
|
||||||
/* post message */
|
/* post message */
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (bin),
|
_priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), new_state, new_state,
|
||||||
gst_message_new_state_changed (GST_OBJECT_CAST (bin),
|
new_state);
|
||||||
new_state, new_state, new_state));
|
|
||||||
|
|
||||||
post_start:
|
post_start:
|
||||||
if (amessage) {
|
if (amessage) {
|
||||||
|
@ -2872,8 +2871,8 @@ bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
|
||||||
GstState current, pending, target;
|
GstState current, pending, target;
|
||||||
GstStateChangeReturn old_ret;
|
GstStateChangeReturn old_ret;
|
||||||
GstState old_state, old_next;
|
GstState old_state, old_next;
|
||||||
gboolean toplevel;
|
gboolean toplevel, state_changed = FALSE;
|
||||||
GstMessage *smessage = NULL, *amessage = NULL;
|
GstMessage *amessage = NULL;
|
||||||
BinContinueData *cont = NULL;
|
BinContinueData *cont = NULL;
|
||||||
|
|
||||||
if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
|
if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
|
||||||
|
@ -2952,15 +2951,14 @@ bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
|
||||||
|
|
||||||
if (old_next != GST_STATE_PLAYING) {
|
if (old_next != GST_STATE_PLAYING) {
|
||||||
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
|
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
|
||||||
smessage = gst_message_new_state_changed (GST_OBJECT_CAST (bin),
|
state_changed = TRUE;
|
||||||
old_state, old_next, pending);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (bin);
|
GST_OBJECT_UNLOCK (bin);
|
||||||
|
|
||||||
if (smessage) {
|
if (state_changed) {
|
||||||
GST_DEBUG_OBJECT (bin, "posting state change message");
|
_priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), old_state,
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (bin), smessage);
|
old_next, pending);
|
||||||
}
|
}
|
||||||
if (amessage) {
|
if (amessage) {
|
||||||
/* post our combined ASYNC_DONE when all is ASYNC_DONE. */
|
/* post our combined ASYNC_DONE when all is ASYNC_DONE. */
|
||||||
|
|
|
@ -2317,6 +2317,28 @@ nothing_aborted:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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:
|
* gst_element_continue_state:
|
||||||
* @element: a #GstElement to continue the state change of.
|
* @element: a #GstElement to continue the state change of.
|
||||||
|
@ -2344,7 +2366,6 @@ gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
|
||||||
GstStateChangeReturn old_ret;
|
GstStateChangeReturn old_ret;
|
||||||
GstState old_state, old_next;
|
GstState old_state, old_next;
|
||||||
GstState current, next, pending;
|
GstState current, next, pending;
|
||||||
GstMessage *message;
|
|
||||||
GstStateChange transition;
|
GstStateChange transition;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (element);
|
GST_OBJECT_LOCK (element);
|
||||||
|
@ -2380,9 +2401,7 @@ gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
|
||||||
gst_element_state_get_name (old_next),
|
gst_element_state_get_name (old_next),
|
||||||
gst_element_state_get_name (pending), gst_element_state_get_name (next));
|
gst_element_state_get_name (pending), gst_element_state_get_name (next));
|
||||||
|
|
||||||
message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
|
_priv_gst_element_state_changed (element, old_state, old_next, pending);
|
||||||
old_state, old_next, pending);
|
|
||||||
gst_element_post_message (element, message);
|
|
||||||
|
|
||||||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
|
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
|
||||||
"continue state change %s to %s, final %s",
|
"continue state change %s to %s, final %s",
|
||||||
|
@ -2414,16 +2433,9 @@ complete:
|
||||||
* previous return value.
|
* previous return value.
|
||||||
* We do signal the cond though as a _get_state() might be blocking
|
* We do signal the cond though as a _get_state() might be blocking
|
||||||
* on it. */
|
* on it. */
|
||||||
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
|
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
|
||||||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
|
_priv_gst_element_state_changed (element, old_state, old_next,
|
||||||
"posting state-changed %s to %s",
|
GST_STATE_VOID_PENDING);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_STATE_BROADCAST (element);
|
GST_STATE_BROADCAST (element);
|
||||||
|
|
||||||
|
@ -2496,9 +2508,7 @@ gst_element_lost_state_full (GstElement * element, gboolean new_base_time)
|
||||||
GST_ELEMENT_START_TIME (element) = 0;
|
GST_ELEMENT_START_TIME (element) = 0;
|
||||||
GST_OBJECT_UNLOCK (element);
|
GST_OBJECT_UNLOCK (element);
|
||||||
|
|
||||||
message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
|
_priv_gst_element_state_changed (element, new_state, new_state, new_state);
|
||||||
new_state, new_state, new_state);
|
|
||||||
gst_element_post_message (element, message);
|
|
||||||
|
|
||||||
message =
|
message =
|
||||||
gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time);
|
gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time);
|
||||||
|
|
|
@ -602,6 +602,7 @@ struct _GstElement
|
||||||
* @get_query_types: get the supported #GstQueryType of this element
|
* @get_query_types: get the supported #GstQueryType of this element
|
||||||
* @query: perform a #GstQuery on the element
|
* @query: perform a #GstQuery on the element
|
||||||
* @request_new_pad_full: called when a new pad is requested. Since: 0.10.32.
|
* @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
|
* GStreamer element class. Override the vmethods to implement the element
|
||||||
* functionality.
|
* functionality.
|
||||||
|
@ -669,8 +670,11 @@ struct _GstElementClass
|
||||||
GstPad* (*request_new_pad_full) (GstElement *element, GstPadTemplate *templ,
|
GstPad* (*request_new_pad_full) (GstElement *element, GstPadTemplate *templ,
|
||||||
const gchar* name, const GstCaps *caps);
|
const gchar* name, const GstCaps *caps);
|
||||||
|
|
||||||
|
void (*state_changed) (GstElement *element, GstState oldstate,
|
||||||
|
GstState newstate, GstState pending);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING-2];
|
gpointer _gst_reserved[GST_PADDING-3];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* element class pad templates */
|
/* element class pad templates */
|
||||||
|
|
Loading…
Reference in a new issue