- Elements can now send events to their parent.

Original commit message from CVS:
- Elements can now send events to their parent.
- remove the g_signals from the core for parent<->child communication
- the application can easily get element info by listening for an event
signal from the toplevel bin.
- added gst_element_info()/_error().
- fakesrc and fakesink use the info event instead of g_print.
- GST_TYPE_* causes segfaults with elect fence, rever to G_TYPE_POINTER
until we know what's wrong.
- various leaks fixed wrt element destroy.
- The object that created the event is now stored as GST_EVENT_SRC
This commit is contained in:
Wim Taymans 2001-12-18 19:03:07 +00:00
parent 19bb74b352
commit 56d3cdf64a
14 changed files with 317 additions and 112 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -26,6 +26,7 @@
#include <gst/gstconfig.h>
#include <gst/gsttypes.h>
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/cothreads.h>
@ -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);

View file

@ -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;
}

View file

@ -24,8 +24,11 @@
#ifndef __GST_EVENT_H__
#define __GST_EVENT_H__
#include <gst/gsttypes.h>
#include <gst/gstelement.h>
#include <gst/gstobject.h>
#include <gst/gstdata.h>
#include <gst/gstcaps.h>
#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 */

View file

@ -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));

View file

@ -30,7 +30,6 @@
#include <gst/gstbuffer.h>
#include <gst/cothreads.h>
#include <gst/gstcaps.h>
#include <gst/gstevent.h>
#ifdef __cplusplus

View file

@ -35,6 +35,7 @@
#include "gstqueue.h"
#include "gstscheduler.h"
#include "gstevent.h"
GstElementDetails gst_queue_details = {
"Queue",

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -35,6 +35,7 @@
#include "gstqueue.h"
#include "gstscheduler.h"
#include "gstevent.h"
GstElementDetails gst_queue_details = {
"Queue",