diff --git a/gst/elements/gstfakesink.c b/gst/elements/gstfakesink.c index 59a61b9653..8c07e258ed 100644 --- a/gst/elements/gstfakesink.c +++ b/gst/elements/gstfakesink.c @@ -226,9 +226,10 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf) } */ - if (!fakesink->silent) - g_print("fakesink: chain ******* (%s:%s)< (%d bytes, %lld) %p\n", + if (!fakesink->silent) { + gst_element_info (GST_ELEMENT (fakesink), "chain ******* (%s:%s)< (%d bytes, %lld) %p", GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf); + } g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0, buf, pad); diff --git a/gst/elements/gstfakesrc.c b/gst/elements/gstfakesrc.c index 5cc436850f..7d8d6e3951 100644 --- a/gst/elements/gstfakesrc.c +++ b/gst/elements/gstfakesrc.c @@ -300,6 +300,8 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ) srcpad = gst_pad_new_from_template (templ, name); gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad); + g_free (name); + return srcpad; } @@ -312,7 +314,6 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: - g_print("fakesrc: have seek event\n"); src->buffer_count = GST_EVENT_SEEK_OFFSET (event); if (!GST_EVENT_SEEK_FLUSH (event)) { gst_event_free (event); @@ -320,11 +321,9 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event) } /* else we do a flush too */ case GST_EVENT_FLUSH: - g_print("fakesrc: have flush event\n"); src->need_flush = TRUE; break; default: - g_print("fakesrc: have unhandled event\n"); break; } @@ -646,12 +645,10 @@ gst_fakesrc_get(GstPad *pad) if (src->need_flush) { src->need_flush = FALSE; - g_print("fakesrc: sending FLUSH\n"); return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH)); } if (src->rt_num_buffers == 0) { - g_print("fakesrc: sending EOS\n"); gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED); return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); } @@ -662,16 +659,17 @@ gst_fakesrc_get(GstPad *pad) if (src->eos) { GST_INFO (0, "fakesrc is setting eos on pad"); - g_print("fakesrc: sending EOS\n"); return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); } buf = gst_fakesrc_create_buffer (src); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; - if (!src->silent) - g_print("fakesrc: get ******* (%s:%s)> (%d bytes, %llu) \n", - GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + if (!src->silent) { + gst_element_info (GST_ELEMENT (src), + "get ******* (%s:%s)> (%d bytes, %llu)", + GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + } GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, src, "pre handoff emit\n"); g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0, @@ -715,7 +713,6 @@ gst_fakesrc_loop(GstElement *element) } if (src->eos) { - GST_INFO (0, "fakesrc is setting eos on pad"); gst_pad_push(pad, GST_BUFFER(gst_event_new (GST_EVENT_EOS))); return; } @@ -723,9 +720,10 @@ gst_fakesrc_loop(GstElement *element) buf = gst_fakesrc_create_buffer (src); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; - if (!src->silent) - g_print("fakesrc: loop ******* (%s:%s) > (%d bytes, %llu) \n", - GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + if (!src->silent) { + gst_element_info (element, "fakesrc: loop ******* (%s:%s) > (%d bytes, %llu)", + GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + } g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0, buf, pad); @@ -768,9 +766,6 @@ gst_fakesrc_change_state (GstElement *element) break; } - if (GST_STATE_PENDING (element) == GST_STATE_READY) { - } - if (GST_ELEMENT_CLASS (parent_class)->change_state) return GST_ELEMENT_CLASS (parent_class)->change_state (element); diff --git a/gst/gstbin.c b/gst/gstbin.c index 4258aa964f..d697b47335 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -23,6 +23,7 @@ /* #define GST_DEBUG_ENABLED */ #include "gst_private.h" +#include "gstevent.h" #include "gstbin.h" #include "gstscheduler.h" @@ -40,11 +41,14 @@ GType _gst_bin_type = 0; static void gst_bin_dispose (GObject * object); -static GstElementStateReturn gst_bin_change_state (GstElement * element); -static GstElementStateReturn gst_bin_change_state_norecurse (GstBin * bin); -static gboolean gst_bin_change_state_type (GstBin * bin, GstElementState state, GType type); -static void gst_bin_child_state_change (GstBin * bin, GstElementState old, - GstElementState new, GstElement * element); +static GstElementStateReturn gst_bin_change_state (GstElement *element); +static GstElementStateReturn gst_bin_change_state_norecurse (GstBin *bin); +static gboolean gst_bin_change_state_type (GstBin *bin, + GstElementState state, + GType type); +static void gst_bin_child_state_change (GstBin *bin, GstElementState old, + GstElementState new, GstElement *child); +static void gst_bin_send_event (GstElement *element, GstEvent *event); static gboolean gst_bin_iterate_func (GstBin * bin); @@ -110,7 +114,10 @@ gst_bin_class_init (GstBinClass * klass) gst_bin_signals[OBJECT_ADDED] = g_signal_new ("object_added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, object_added), NULL, NULL, - gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT); + gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + + klass->change_state_type = GST_DEBUG_FUNCPTR (gst_bin_change_state_type); + klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose); #ifndef GST_DISABLE_LOADSAVE @@ -119,6 +126,7 @@ gst_bin_class_init (GstBinClass * klass) #endif gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state); + gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event); klass->change_state_type = GST_DEBUG_FUNCPTR (gst_bin_change_state_type); klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func); @@ -272,8 +280,6 @@ gst_bin_add (GstBin * bin, GstElement * element) /* set the element's parent and add the element to the bin's list of children */ gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (bin)); - g_signal_connect_swapped (G_OBJECT (element), "state_change", - G_CALLBACK (gst_bin_child_state_change), G_OBJECT (bin)); bin->children = g_list_append (bin->children, element); bin->numchildren++; @@ -384,10 +390,33 @@ gst_bin_child_state_change (GstBin * bin, GstElementState old, GstElementState n break; } } - GST_UNLOCK (bin); } +static void +gst_bin_send_event (GstElement *element, GstEvent *event) +{ + GST_DEBUG (GST_CAT_EVENT, "event from %s in %s\n", + gst_element_get_name (GST_ELEMENT (GST_EVENT_SRC (event))), + gst_element_get_name (element)); + + if (GST_ELEMENT (GST_EVENT_SRC (event)) == element) { + GST_ELEMENT_CLASS (parent_class)->send_event (element, event); + return; + } + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_STATE_CHANGE: + gst_bin_child_state_change (GST_BIN (element), GST_EVENT_STATE_OLD (event), + GST_EVENT_STATE_NEW (event), GST_ELEMENT (GST_EVENT_SRC (event))); + gst_event_free (event); + break; + default: + GST_ELEMENT_CLASS (parent_class)->send_event (element, event); + break; + } +} + static GstElementStateReturn gst_bin_change_state (GstElement * element) { @@ -432,8 +461,10 @@ gst_bin_change_state (GstElement * element) } } - GST_INFO_ELEMENT (GST_CAT_STATES, element, "done changing bin's state from %s to %s", - gst_element_statename (old_state), gst_element_statename (pending)); + GST_INFO_ELEMENT (GST_CAT_STATES, element, "done changing bin's state from %s to %s, now in %s", + gst_element_statename (old_state), + gst_element_statename (pending), + gst_element_statename (GST_STATE (element))); if (have_async) ret = GST_STATE_ASYNC; diff --git a/gst/gstelement.c b/gst/gstelement.c index 028a80923a..6be17a496f 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -29,6 +29,7 @@ #include "gstextratypes.h" #include "gstbin.h" #include "gstscheduler.h" +#include "gstevent.h" #include "gstutils.h" /* Element signals and args */ @@ -37,6 +38,7 @@ enum { NEW_PAD, PAD_REMOVED, ERROR, + EVENT, EOS, LAST_SIGNAL }; @@ -59,6 +61,7 @@ static void gst_element_get_property (GObject *object, guint prop_id, GValue * static void gst_element_dispose (GObject *object); static GstElementStateReturn gst_element_change_state (GstElement *element); +static void gst_element_send_event_func (GstElement *element, GstEvent *event); #ifndef GST_DISABLE_LOADSAVE static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent); @@ -102,27 +105,32 @@ gst_element_class_init (GstElementClass *klass) parent_class = g_type_class_ref(GST_TYPE_OBJECT); gst_element_signals[STATE_CHANGE] = - g_signal_new ("state_change", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("state_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL, gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); gst_element_signals[NEW_PAD] = - g_signal_new ("new_pad", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("new_pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL, - gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - GST_TYPE_PAD); + gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); gst_element_signals[PAD_REMOVED] = - g_signal_new ("pad_removed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("pad_removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL, - gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - GST_TYPE_PAD); + gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); gst_element_signals[ERROR] = - g_signal_new ("error", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL, gst_marshal_VOID__STRING, G_TYPE_NONE,1, - G_TYPE_STRING); + G_TYPE_STRING); + gst_element_signals[EVENT] = + g_signal_new ("event", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstElementClass, event), NULL, NULL, + gst_marshal_VOID__POINTER, G_TYPE_NONE,1, + G_TYPE_POINTER); gst_element_signals[EOS] = - g_signal_new ("eos", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -138,9 +146,10 @@ gst_element_class_init (GstElementClass *klass) #endif klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state); - klass->elementfactory = NULL; - klass->padtemplates = NULL; - klass->numpadtemplates = 0; + klass->send_event = GST_DEBUG_FUNCPTR (gst_element_send_event_func); + klass->elementfactory = NULL; + klass->padtemplates = NULL; + klass->numpadtemplates = 0; } static void @@ -158,7 +167,7 @@ static void gst_element_init (GstElement *element) { element->current_state = GST_STATE_NULL; - element->pending_state = -1; + element->pending_state = GST_STATE_VOID_PENDING; element->numpads = 0; element->numsrcpads = 0; element->numsinkpads = 0; @@ -166,6 +175,8 @@ gst_element_init (GstElement *element) element->loopfunc = NULL; element->threadstate = NULL; element->sched = NULL; + element->state_mutex = g_mutex_new (); + element->state_cond = g_cond_new (); } @@ -760,6 +771,21 @@ gst_element_disconnect (GstElement *src, const gchar *srcpadname, gst_pad_disconnect(srcpad,destpad); } +static void +gst_element_message (GstElement *element, const gchar *type, const gchar *info, va_list var_args) +{ + GstEvent *event; + GstProps *props; + gchar *string; + + string = g_strdup_vprintf (info, var_args); + + event = gst_event_new_info (type, GST_PROPS_STRING (string), NULL); + gst_element_send_event (element, event); + + g_free (string); +} + /** * gst_element_error: * @element: Element with the error @@ -769,15 +795,75 @@ gst_element_disconnect (GstElement *src, const gchar *srcpadname, * condition. It results in the "error" signal. */ void -gst_element_error (GstElement *element, const gchar *error) +gst_element_error (GstElement *element, const gchar *error, ...) { - g_error("GstElement: error in element '%s': %s\n", GST_ELEMENT_NAME(element), error); - - /* FIXME: this is not finished!!! */ - - g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, error); + va_list var_args; + + va_start (var_args, error); + gst_element_message (element, "error", error, var_args); + va_end (var_args); } +/** + * gst_element_info: + * @element: Element with the info + * @info: String describing the info + * + * This function is used internally by elements to signal an info + * condition. It results in the "info" signal. + */ +void +gst_element_info (GstElement *element, const gchar *info, ...) +{ + va_list var_args; + + va_start (var_args, info); + gst_element_message (element, "info", info, var_args); + va_end (var_args); +} + + +static void +gst_element_send_event_func (GstElement *element, GstEvent *event) +{ + if (GST_OBJECT_PARENT (element)) { + gst_element_send_event (GST_ELEMENT (GST_OBJECT_PARENT (element)), event); + } + else { + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_STATE_CHANGE: + g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE], 0, + GST_EVENT_STATE_OLD (event), GST_EVENT_STATE_NEW (event)); + default: + g_signal_emit (G_OBJECT (element), gst_element_signals[EVENT], 0, event); + } + gst_event_free (event); + } +} + +/** + * gst_element_send_event: + * @element: Element generating the event + * @event: the event to send + * + * This function is used intenally by elements to send an event to + * the app. It will result in an "event" signal. + */ +void +gst_element_send_event (GstElement *element, GstEvent *event) +{ + GstElementClass *oclass = (GstElementClass *) G_OBJECT_GET_CLASS (element); + + g_return_if_fail (GST_IS_ELEMENT (element)); + g_return_if_fail (event); + + if (GST_EVENT_SRC (event) == NULL) + GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (element)); + + if (oclass->send_event) + (oclass->send_event) (element, event); + +} /** * gst_element_get_state: @@ -795,13 +881,6 @@ gst_element_get_state (GstElement *element) return GST_STATE (element); } -static void -gst_element_wait_done (GstElement *element, GstElementState old, GstElementState new, GCond *cond) -{ - g_signal_handlers_disconnect_by_func (G_OBJECT (element), gst_element_wait_done, cond); - g_cond_signal (cond); -} - /** * gst_element_wait_state_change: * @element: element wait for @@ -811,17 +890,9 @@ gst_element_wait_done (GstElement *element, GstElementState old, GstElementState void gst_element_wait_state_change (GstElement *element) { - GCond *cond = g_cond_new (); - GMutex *mutex = g_mutex_new (); - - g_mutex_lock (mutex); - g_signal_connect (G_OBJECT (element), "state_change", - G_CALLBACK (gst_element_wait_done), cond); - g_cond_wait (cond, mutex); - g_mutex_unlock (mutex); - - g_mutex_free (mutex); - g_cond_free (cond); + g_mutex_lock (element->state_mutex); + g_cond_wait (element->state_cond, element->state_mutex); + g_mutex_unlock (element->state_mutex); } /** * gst_element_set_state: @@ -935,14 +1006,15 @@ gst_element_change_state (GstElement *element) GST_STATE (element) = GST_STATE_PENDING (element); GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; - /* note: queues' state_change is a special case because it needs to lock - * for synchronization (from another thread). since this signal may block - * or (worse) make another state change, the queue needs to unlock before - * calling. thus, gstqueue.c::gst_queue_state_change() blocks, unblocks, - * unlocks, then emits this. - */ - g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE], 0, - old_state, GST_STATE (element)); + g_mutex_lock (element->state_mutex); + g_cond_signal (element->state_cond); + g_mutex_unlock (element->state_mutex); + + { + GstEvent *event = gst_event_new_state_change (old_state, GST_STATE (element)); + + gst_element_send_event (element, event); + } return GST_STATE_SUCCESS; } @@ -995,6 +1067,8 @@ gst_element_dispose (GObject *object) element->numsrcpads = 0; element->numsinkpads = 0; element->numpads = 0; + g_mutex_free (element->state_mutex); + g_cond_free (element->state_cond); G_OBJECT_CLASS (parent_class)->dispose (object); } diff --git a/gst/gstelement.h b/gst/gstelement.h index 4f48140628..3e80f403a0 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -37,20 +38,23 @@ extern "C" { #define GST_NUM_STATES 4 -typedef enum { - GST_STATE_VOID_PENDING = 0, - GST_STATE_NULL = (1 << 0), - GST_STATE_READY = (1 << 1), - GST_STATE_PAUSED = (1 << 2), - GST_STATE_PLAYING = (1 << 3), -} GstElementState; +//typedef enum _GstElementState GstElementState; +//typedef enum _GstElementStateReturn GstElementStateReturn; -typedef enum { - GST_STATE_FAILURE = 0, - GST_STATE_SUCCESS = 1, - GST_STATE_ASYNC = 2, -} GstElementStateReturn; +enum _GstElementState { + GST_STATE_VOID_PENDING = 0, + GST_STATE_NULL = (1 << 0), + GST_STATE_READY = (1 << 1), + GST_STATE_PAUSED = (1 << 2), + GST_STATE_PLAYING = (1 << 3), +}; + +enum _GstElementStateReturn { + GST_STATE_FAILURE = 0, + GST_STATE_SUCCESS = 1, + GST_STATE_ASYNC = 2, +}; /* NOTE: this probably should be done with an #ifdef to decide * whether to safe-cast or to just do the non-checking cast. @@ -150,6 +154,9 @@ struct _GstElement { guint16 numsinkpads; GList *pads; GstPad *select_pad; + + GMutex *state_mutex; + GCond *state_cond; }; struct _GstElementClass { @@ -166,16 +173,19 @@ struct _GstElementClass { void (*new_pad) (GstElement *element, GstPad *pad); void (*pad_removed) (GstElement *element, GstPad *pad); void (*error) (GstElement *element, gchar *error); + void (*event) (GstElement *element, GstEvent *event); void (*eos) (GstElement *element); /* local pointers for get/set */ void (*set_property) (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); void (*get_property) (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + /* vtable*/ /* change the element state */ GstElementStateReturn (*change_state) (GstElement *element); /* request a new pad */ GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ, const gchar* name); + void (*send_event) (GstElement *element, GstEvent *event); }; void gst_element_class_add_padtemplate (GstElementClass *klass, GstPadTemplate *templ); @@ -214,6 +224,8 @@ void gst_element_disconnect (GstElement *src, const gchar *srcpadname, void gst_element_signal_eos (GstElement *element); +void gst_element_send_event (GstElement *element, GstEvent *event); + GstElementState gst_element_get_state (GstElement *element); gint gst_element_set_state (GstElement *element, GstElementState state); @@ -222,7 +234,8 @@ void gst_element_wait_state_change (GstElement *element); const gchar* gst_element_statename (GstElementState state); -void gst_element_error (GstElement *element, const gchar *error); +void gst_element_info (GstElement *element, const gchar *info, ...); +void gst_element_error (GstElement *element, const gchar *error, ...); GstElementFactory* gst_element_get_factory (GstElement *element); diff --git a/gst/gstevent.c b/gst/gstevent.c index 8607cdc7f0..2a3ff74ed9 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -77,6 +77,8 @@ gst_event_new (GstEventType type) GST_DATA_TYPE (event) = _gst_event_type; GST_EVENT_TYPE (event) = type; + GST_EVENT_TIMESTAMP (event) = 0LL; + GST_EVENT_SRC (event) = NULL; return event; } @@ -91,6 +93,16 @@ void gst_event_free (GstEvent* event) { g_mutex_lock (_gst_event_chunk_lock); + if (GST_EVENT_SRC (event)) { + gst_object_unref (GST_EVENT_SRC (event)); + } + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_INFO: + gst_props_unref (GST_EVENT_INFO_PROPS (event)); + break; + default: + break; + } g_mem_chunk_free (_gst_event_chunk, event); g_mutex_unlock (_gst_event_chunk_lock); } @@ -117,3 +129,49 @@ gst_event_new_seek (GstSeekType type, guint64 offset, gboolean flush) return event; } + +/** + * gst_event_new_info: + * @props: The GstProps for this info event + * + * Allocate a new info event with the given props. + * + * Returns: A new info event. + */ +GstEvent* +gst_event_new_info (const gchar *firstname, ...) +{ + GstEvent *event; + va_list var_args; + + event = gst_event_new (GST_EVENT_INFO); + va_start (var_args, firstname); + + GST_EVENT_INFO_PROPS (event) = gst_props_newv (firstname, var_args); + + va_end (var_args); + + return event; +} +/** + * gst_event_new_state_change: + * @old: The old state + * @state: The new state + * + * Allocate a new state change event with the given props. + * + * Returns: A new state change event. + */ +GstEvent* +gst_event_new_state_change (GstElementState old, GstElementState state) +{ + GstEvent *event; + + event = gst_event_new (GST_EVENT_STATE_CHANGE); + GST_EVENT_STATE_OLD (event) = old; + GST_EVENT_STATE_NEW (event) = state; + + return event; +} + + diff --git a/gst/gstevent.h b/gst/gstevent.h index 2e45b2b855..c1f35f2bd4 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -24,8 +24,11 @@ #ifndef __GST_EVENT_H__ #define __GST_EVENT_H__ +#include +#include #include #include +#include #ifdef __cplusplus extern "C" { @@ -33,11 +36,16 @@ extern "C" { typedef enum { GST_EVENT_UNKNOWN, + /* horizontal events */ GST_EVENT_EOS, GST_EVENT_FLUSH, GST_EVENT_EMPTY, GST_EVENT_SEEK, - GST_EVENT_DISCONTINUOUS + GST_EVENT_DISCONTINUOUS, + /* vertical events */ + GST_EVENT_INFO, + GST_EVENT_ERROR, + GST_EVENT_STATE_CHANGE, } GstEventType; extern GType _gst_event_type; @@ -47,7 +55,8 @@ extern GType _gst_event_type; #define GST_IS_EVENT(event) (GST_DATA_TYPE(event) == GST_TYPE_EVENT) #define GST_EVENT_TYPE(event) (GST_EVENT(event)->type) -#define GST_EVENT_TIMESTAMP(event) (GST_EVENT(event)->timstamp) +#define GST_EVENT_TIMESTAMP(event) (GST_EVENT(event)->timestamp) +#define GST_EVENT_SRC(event) (GST_EVENT(event)->src) /* seek events */ typedef enum { @@ -60,13 +69,18 @@ typedef enum { #define GST_EVENT_SEEK_OFFSET(event) (GST_EVENT(event)->event_data.seek.offset) #define GST_EVENT_SEEK_FLUSH(event) (GST_EVENT(event)->event_data.seek.flush) -typedef struct _GstEvent GstEvent; +#define GST_EVENT_INFO_PROPS(event) (GST_EVENT(event)->event_data.info.props) + +#define GST_EVENT_STATE_OLD(event) (GST_EVENT(event)->event_data.state.old_state) +#define GST_EVENT_STATE_NEW(event) (GST_EVENT(event)->event_data.state.new_state) + struct _GstEvent { GstData data; GstEventType type; guint64 timestamp; + GstObject *src; union { struct { @@ -74,6 +88,13 @@ struct _GstEvent { guint64 offset; gboolean flush; } seek; + struct { + GstProps *props; + } info; + struct { + GstElementState old_state; + GstElementState new_state; + } state; } event_data; }; @@ -88,6 +109,12 @@ GstEvent* gst_event_new_seek (GstSeekType type, guint64 offset, gboolean flush); /* flush events */ #define gst_event_new_flush() gst_event_new(GST_EVENT_FLUSH) +/* info events */ +GstEvent* gst_event_new_info (const gchar *firstname, ...); + +/* state change events */ +GstEvent* gst_event_new_state_change (GstElementState old, GstElementState state); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gst/gstpad.c b/gst/gstpad.c index f2d31913e2..1308b180aa 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -29,6 +29,7 @@ #include "gsttype.h" #include "gstbin.h" #include "gstscheduler.h" +#include "gstevent.h" GType _gst_pad_type = 0; @@ -1671,8 +1672,8 @@ gst_padtemplate_class_init (GstPadTemplateClass *klass) gst_padtemplate_signals[TEMPL_PAD_CREATED] = g_signal_new ("pad_created", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPadTemplateClass, pad_created), NULL, NULL, - gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - GST_TYPE_PAD); + gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); gstobject_class->path_string_separator = "*"; @@ -1969,6 +1970,7 @@ gst_pad_event_default (GstPad *pad, GstEvent *event) GstElement *element = GST_PAD_PARENT (pad); switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: case GST_EVENT_EOS: /* gst_element_signal_eos (element); */ gst_element_set_state (element, GST_STATE_PAUSED); @@ -2006,6 +2008,9 @@ gst_pad_send_event (GstPad *pad, GstEvent *event) g_return_val_if_fail (event, FALSE); + if (GST_EVENT_SRC (event) == NULL) + GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (pad)); + GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n", GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad)); diff --git a/gst/gstpad.h b/gst/gstpad.h index d2f66535e6..b9f61cb867 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -30,7 +30,6 @@ #include #include #include -#include #ifdef __cplusplus diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 23482d7a71..4561fa6f1e 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -35,6 +35,7 @@ #include "gstqueue.h" #include "gstscheduler.h" +#include "gstevent.h" GstElementDetails gst_queue_details = { "Queue", diff --git a/gst/gsttypes.h b/gst/gsttypes.h index e6f0335b41..b169ba7bfe 100644 --- a/gst/gsttypes.h +++ b/gst/gsttypes.h @@ -13,5 +13,9 @@ typedef struct _GstBin GstBin; typedef struct _GstBinClass GstBinClass; typedef struct _GstScheduler GstScheduler; typedef struct _GstSchedulerClass GstSchedulerClass; +typedef struct _GstEvent GstEvent; + +typedef enum _GstElementState GstElementState; +typedef enum _GstElementStateReturn GstElementStateReturn; #endif diff --git a/plugins/elements/gstfakesink.c b/plugins/elements/gstfakesink.c index 59a61b9653..8c07e258ed 100644 --- a/plugins/elements/gstfakesink.c +++ b/plugins/elements/gstfakesink.c @@ -226,9 +226,10 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf) } */ - if (!fakesink->silent) - g_print("fakesink: chain ******* (%s:%s)< (%d bytes, %lld) %p\n", + if (!fakesink->silent) { + gst_element_info (GST_ELEMENT (fakesink), "chain ******* (%s:%s)< (%d bytes, %lld) %p", GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf); + } g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0, buf, pad); diff --git a/plugins/elements/gstfakesrc.c b/plugins/elements/gstfakesrc.c index 5cc436850f..7d8d6e3951 100644 --- a/plugins/elements/gstfakesrc.c +++ b/plugins/elements/gstfakesrc.c @@ -300,6 +300,8 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ) srcpad = gst_pad_new_from_template (templ, name); gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad); + g_free (name); + return srcpad; } @@ -312,7 +314,6 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: - g_print("fakesrc: have seek event\n"); src->buffer_count = GST_EVENT_SEEK_OFFSET (event); if (!GST_EVENT_SEEK_FLUSH (event)) { gst_event_free (event); @@ -320,11 +321,9 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event) } /* else we do a flush too */ case GST_EVENT_FLUSH: - g_print("fakesrc: have flush event\n"); src->need_flush = TRUE; break; default: - g_print("fakesrc: have unhandled event\n"); break; } @@ -646,12 +645,10 @@ gst_fakesrc_get(GstPad *pad) if (src->need_flush) { src->need_flush = FALSE; - g_print("fakesrc: sending FLUSH\n"); return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH)); } if (src->rt_num_buffers == 0) { - g_print("fakesrc: sending EOS\n"); gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED); return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); } @@ -662,16 +659,17 @@ gst_fakesrc_get(GstPad *pad) if (src->eos) { GST_INFO (0, "fakesrc is setting eos on pad"); - g_print("fakesrc: sending EOS\n"); return GST_BUFFER(gst_event_new (GST_EVENT_EOS)); } buf = gst_fakesrc_create_buffer (src); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; - if (!src->silent) - g_print("fakesrc: get ******* (%s:%s)> (%d bytes, %llu) \n", - GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + if (!src->silent) { + gst_element_info (GST_ELEMENT (src), + "get ******* (%s:%s)> (%d bytes, %llu)", + GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + } GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, src, "pre handoff emit\n"); g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0, @@ -715,7 +713,6 @@ gst_fakesrc_loop(GstElement *element) } if (src->eos) { - GST_INFO (0, "fakesrc is setting eos on pad"); gst_pad_push(pad, GST_BUFFER(gst_event_new (GST_EVENT_EOS))); return; } @@ -723,9 +720,10 @@ gst_fakesrc_loop(GstElement *element) buf = gst_fakesrc_create_buffer (src); GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++; - if (!src->silent) - g_print("fakesrc: loop ******* (%s:%s) > (%d bytes, %llu) \n", - GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + if (!src->silent) { + gst_element_info (element, "fakesrc: loop ******* (%s:%s) > (%d bytes, %llu)", + GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf)); + } g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0, buf, pad); @@ -768,9 +766,6 @@ gst_fakesrc_change_state (GstElement *element) break; } - if (GST_STATE_PENDING (element) == GST_STATE_READY) { - } - if (GST_ELEMENT_CLASS (parent_class)->change_state) return GST_ELEMENT_CLASS (parent_class)->change_state (element); diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 23482d7a71..4561fa6f1e 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -35,6 +35,7 @@ #include "gstqueue.h" #include "gstscheduler.h" +#include "gstevent.h" GstElementDetails gst_queue_details = { "Queue",