}
*/
- 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);
srcpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
+ g_free (name);
+
return srcpad;
}
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);
}
/* 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;
}
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));
}
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,
}
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;
}
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);
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);
/* #define GST_DEBUG_ENABLED */
#include "gst_private.h"
+#include "gstevent.h"
#include "gstbin.h"
#include "gstscheduler.h"
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);
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
#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);
/* 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++;
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)
{
}
}
- 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;
#include "gstextratypes.h"
#include "gstbin.h"
#include "gstscheduler.h"
+#include "gstevent.h"
#include "gstutils.h"
/* Element signals and args */
NEW_PAD,
PAD_REMOVED,
ERROR,
+ EVENT,
EOS,
LAST_SIGNAL
};
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);
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);
#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
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;
element->loopfunc = NULL;
element->threadstate = NULL;
element->sched = NULL;
+ element->state_mutex = g_mutex_new ();
+ element->state_cond = g_cond_new ();
}
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
* 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);
+ 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);
+}
- /* FIXME: this is not finished!!! */
- g_signal_emit (G_OBJECT (element), gst_element_signals[ERROR], 0, error);
+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:
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
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:
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;
}
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);
}
#include <gst/gstconfig.h>
+#include <gst/gsttypes.h>
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/cothreads.h>
#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.
guint16 numsinkpads;
GList *pads;
GstPad *select_pad;
+
+ GMutex *state_mutex;
+ GCond *state_cond;
};
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);
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);
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);
GST_DATA_TYPE (event) = _gst_event_type;
GST_EVENT_TYPE (event) = type;
+ GST_EVENT_TIMESTAMP (event) = 0LL;
+ GST_EVENT_SRC (event) = NULL;
return event;
}
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);
}
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;
+}
+
+
#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" {
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;
#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 {
#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 {
guint64 offset;
gboolean flush;
} seek;
+ struct {
+ GstProps *props;
+ } info;
+ struct {
+ GstElementState old_state;
+ GstElementState new_state;
+ } state;
} event_data;
};
/* 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 */
#include "gsttype.h"
#include "gstbin.h"
#include "gstscheduler.h"
+#include "gstevent.h"
GType _gst_pad_type = 0;
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 = "*";
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);
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));
#include <gst/gstbuffer.h>
#include <gst/cothreads.h>
#include <gst/gstcaps.h>
-#include <gst/gstevent.h>
#ifdef __cplusplus
#include "gstqueue.h"
#include "gstscheduler.h"
+#include "gstevent.h"
GstElementDetails gst_queue_details = {
"Queue",
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
}
*/
- 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);
srcpad = gst_pad_new_from_template (templ, name);
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
+ g_free (name);
+
return srcpad;
}
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);
}
/* 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;
}
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));
}
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,
}
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;
}
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);
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);
#include "gstqueue.h"
#include "gstscheduler.h"
+#include "gstevent.h"
GstElementDetails gst_queue_details = {
"Queue",