From 9b7b1794bc932e992df1afb7cd3c6c5b2f0b9be5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sat, 6 Oct 2001 14:41:20 +0000 Subject: [PATCH] Added code for sending an event to a pad. Original commit message from CVS: Added code for sending an event to a pad. Added code to handle the event in fakesrc and fakesink. --- gst/elements/gstfakesink.c | 28 ++++++++---------- gst/elements/gstfakesrc.c | 52 +++++++++++++++++++++++++++------- gst/elements/gstfakesrc.h | 1 + gst/gstevent.c | 14 +++++++++ gst/gstevent.h | 31 ++++++++++++++++++-- gst/gstpad.c | 28 ++++++++++++++++-- gst/gstpad.h | 3 +- plugins/elements/gstfakesink.c | 28 ++++++++---------- plugins/elements/gstfakesrc.c | 52 +++++++++++++++++++++++++++------- plugins/elements/gstfakesrc.h | 1 + 10 files changed, 178 insertions(+), 60 deletions(-) diff --git a/gst/elements/gstfakesink.c b/gst/elements/gstfakesink.c index 9faa779e15..a3a7832bb8 100644 --- a/gst/elements/gstfakesink.c +++ b/gst/elements/gstfakesink.c @@ -67,7 +67,6 @@ static void gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gst_fakesink_chain (GstPad *pad, GstBuffer *buf); -static gboolean gst_fakesink_event (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data); static GstElementClass *parent_class = NULL; static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 }; @@ -130,7 +129,6 @@ gst_fakesink_init (GstFakeSink *fakesink) pad = gst_pad_new ("sink", GST_PAD_SINK); gst_element_add_pad (GST_ELEMENT (fakesink), pad); gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); - gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event)); fakesink->sinkpads = g_slist_prepend (NULL, pad); fakesink->numsinkpads = 1; @@ -224,8 +222,18 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf) fakesink = GST_FAKESINK (gst_pad_get_parent (pad)); if (GST_IS_EVENT(buf)) { - g_print("fakesink: have event!\n"); - gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED); + GstEvent *event = GST_EVENT (buf); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_EOS: + g_print("fakesink: have EOS event!\n"); + gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED); + break; + default: + g_print("fakesink: have unhandled event!\n"); + break; + } + gst_event_free (event); return; } @@ -245,15 +253,3 @@ gst_fakesink_factory_init (GstElementFactory *factory) return TRUE; } - - - -static gboolean -gst_fakesink_event (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data) -{ - GST_DEBUG (GST_CAT_EVENT, "fakesink has event %d on pad %s:%s\n",event,GST_DEBUG_PAD_NAME(pad)); - if (event == GST_EVENT_EOS) { - GST_DEBUG(GST_CAT_EVENT, "have EOS\n"); - } - return FALSE; -} diff --git a/gst/elements/gstfakesrc.c b/gst/elements/gstfakesrc.c index 6f63cb3141..cae36ea6b3 100644 --- a/gst/elements/gstfakesrc.c +++ b/gst/elements/gstfakesrc.c @@ -86,6 +86,7 @@ static void gst_fakesrc_class_init (GstFakeSrcClass *klass); static void gst_fakesrc_init (GstFakeSrc *fakesrc); static GstPad* gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ); +static void gst_fakesrc_update_functions (GstFakeSrc *src); static void gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); @@ -176,17 +177,12 @@ gst_fakesrc_init (GstFakeSrc *fakesrc) fakesrc->srcpads = g_slist_append (NULL, pad); fakesrc->loop_based = FALSE; - - if (fakesrc->loop_based) - gst_element_set_loop_function (GST_ELEMENT (fakesrc), GST_DEBUG_FUNCPTR (gst_fakesrc_loop)); - else - gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get)); + gst_fakesrc_update_functions (fakesrc); fakesrc->num_buffers = -1; fakesrc->buffer_count = 0; fakesrc->silent = FALSE; - // we're ready right away, since we don't have any args... -// gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY); + fakesrc->need_flush = FALSE; } static GstPad* @@ -216,6 +212,32 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ) return srcpad; } +static gboolean +gst_fakesrc_event_handler (GstPad *pad, GstEvent *event) +{ + GstFakeSrc *src; + + src = GST_FAKESRC (gst_pad_get_parent (pad)); + + 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); + break; + } + // 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; + } +} + static void gst_fakesrc_update_functions (GstFakeSrc *src) { @@ -238,6 +260,8 @@ gst_fakesrc_update_functions (GstFakeSrc *src) else { gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get)); } + + gst_pad_set_event_function (pad, gst_fakesrc_event_handler); pads = g_slist_next (pads); } } @@ -333,6 +357,12 @@ gst_fakesrc_get(GstPad *pad) g_return_val_if_fail (GST_IS_FAKESRC (src), NULL); + 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->num_buffers == 0) { g_print("fakesrc: sending EOS\n"); gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED); @@ -388,17 +418,17 @@ gst_fakesrc_loop(GstElement *element) GstBuffer *buf; if (src->num_buffers == 0) { - gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0); - return; + src->eos = TRUE; } else { - if (src->num_buffers > 0) - src->num_buffers--; + if (src->num_buffers > 0) + src->num_buffers--; } 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_buffer_new(); diff --git a/gst/elements/gstfakesrc.h b/gst/elements/gstfakesrc.h index ce5c2a9439..d9bcc5dfd5 100644 --- a/gst/elements/gstfakesrc.h +++ b/gst/elements/gstfakesrc.h @@ -74,6 +74,7 @@ struct _GstFakeSrc { gint num_buffers; guint64 buffer_count; gboolean silent; + gboolean need_flush; }; struct _GstFakeSrcClass { diff --git a/gst/gstevent.c b/gst/gstevent.c index a31a04a6c3..10aa9c3ca0 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -80,3 +80,17 @@ gst_event_free (GstEvent* event) g_mem_chunk_free (_gst_event_chunk, event); g_mutex_unlock (_gst_event_chunk_lock); } + +/* seek stuff */ +GstEvent* +gst_event_new_seek (GstSeekType type, guint64 offset, gboolean flush) +{ + GstEvent *event; + + event = gst_event_new (GST_EVENT_SEEK); + GST_EVENT_SEEK_TYPE (event) = type; + GST_EVENT_SEEK_OFFSET (event) = offset; + GST_EVENT_SEEK_FLUSH (event) = flush; + + return event; +} diff --git a/gst/gstevent.h b/gst/gstevent.h index 70f5097b88..2e45b2b855 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -46,14 +46,35 @@ extern GType _gst_event_type; #define GST_EVENT(event) ((GstEvent*)(event)) #define GST_IS_EVENT(event) (GST_DATA_TYPE(event) == GST_TYPE_EVENT) -#define GST_EVENT_TYPE(event) (GST_EVENT(event)->type) +#define GST_EVENT_TYPE(event) (GST_EVENT(event)->type) +#define GST_EVENT_TIMESTAMP(event) (GST_EVENT(event)->timstamp) + +/* seek events */ +typedef enum { + GST_SEEK_ANY, + GST_SEEK_TIMEOFFSET, + GST_SEEK_BYTEOFFSET +} GstSeekType; + +#define GST_EVENT_SEEK_TYPE(event) (GST_EVENT(event)->event_data.seek.type) +#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; struct _GstEvent { GstData data; - GstEventType type; + GstEventType type; + guint64 timestamp; + + union { + struct { + GstSeekType type; + guint64 offset; + gboolean flush; + } seek; + } event_data; }; void _gst_event_initialize (void); @@ -61,6 +82,12 @@ void _gst_event_initialize (void); GstEvent* gst_event_new (GstEventType type); void gst_event_free (GstEvent* event); +/* seek events */ +GstEvent* gst_event_new_seek (GstSeekType type, guint64 offset, gboolean flush); + +/* flush events */ +#define gst_event_new_flush() gst_event_new(GST_EVENT_FLUSH) + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gst/gstpad.c b/gst/gstpad.c index b9a4e5238b..07e9afca81 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1939,14 +1939,36 @@ gst_pad_event (GstPad *pad, GstEventType event, gint64 timestamp, guint32 data) GST_DEBUG(GST_CAT_EVENT, "have event %d on pad %s:%s\n",(gint)event,GST_DEBUG_PAD_NAME(pad)); peer = GST_RPAD_PEER(pad); - if (GST_RPAD_EVENTFUNC(peer)) - handled = GST_RPAD_EVENTFUNC(peer) (peer, event, timestamp, data); + if (GST_RPAD_EVENTFUNC(peer)) { + //handled = GST_RPAD_EVENTFUNC(peer) (peer, event, timestamp, data); + } else { GST_DEBUG(GST_CAT_EVENT, "there's no event function for peer %s:%s\n",GST_DEBUG_PAD_NAME(peer)); } if (!handled) { GST_DEBUG(GST_CAT_EVENT, "would proceed with default behavior here\n"); - gst_pad_event_default(peer,event, timestamp, data); + //gst_pad_event_default(peer,event, timestamp, data); } } + +gboolean +gst_pad_send_event (GstPad *pad, GstEvent *event) +{ + gboolean handled = FALSE; + + GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n", + GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad)); + + if (GST_RPAD_EVENTFUNC (pad)) + handled = GST_RPAD_EVENTFUNC (pad) (pad, event); + else { + GST_DEBUG(GST_CAT_EVENT, "there's no event function for pad %s:%s\n", GST_DEBUG_PAD_NAME (pad)); + } + + if (!handled) { + GST_DEBUG(GST_CAT_EVENT, "would proceed with default behavior here\n"); + //gst_pad_event_default (pad, event); + } +} + diff --git a/gst/gstpad.h b/gst/gstpad.h index a93ed0146a..c1d63b043b 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -130,7 +130,7 @@ typedef enum { * buf is the buffer being passed */ typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf); typedef GstBuffer* (*GstPadGetFunction) (GstPad *pad); -typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstEventType event, gint64 timestamp, guint32 data); +typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstEvent *event); typedef GstBuffer* (*GstPadGetRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); typedef GstBuffer* (*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); @@ -412,6 +412,7 @@ FALSE ) }G_STMT_END #endif +gboolean gst_pad_send_event (GstPad *pad, GstEvent *event); GstBuffer* gst_pad_peek (GstPad *pad); GstPad* gst_pad_select (GList *padlist); diff --git a/plugins/elements/gstfakesink.c b/plugins/elements/gstfakesink.c index 9faa779e15..a3a7832bb8 100644 --- a/plugins/elements/gstfakesink.c +++ b/plugins/elements/gstfakesink.c @@ -67,7 +67,6 @@ static void gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gst_fakesink_chain (GstPad *pad, GstBuffer *buf); -static gboolean gst_fakesink_event (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data); static GstElementClass *parent_class = NULL; static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 }; @@ -130,7 +129,6 @@ gst_fakesink_init (GstFakeSink *fakesink) pad = gst_pad_new ("sink", GST_PAD_SINK); gst_element_add_pad (GST_ELEMENT (fakesink), pad); gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); - gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event)); fakesink->sinkpads = g_slist_prepend (NULL, pad); fakesink->numsinkpads = 1; @@ -224,8 +222,18 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf) fakesink = GST_FAKESINK (gst_pad_get_parent (pad)); if (GST_IS_EVENT(buf)) { - g_print("fakesink: have event!\n"); - gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED); + GstEvent *event = GST_EVENT (buf); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_EOS: + g_print("fakesink: have EOS event!\n"); + gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED); + break; + default: + g_print("fakesink: have unhandled event!\n"); + break; + } + gst_event_free (event); return; } @@ -245,15 +253,3 @@ gst_fakesink_factory_init (GstElementFactory *factory) return TRUE; } - - - -static gboolean -gst_fakesink_event (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data) -{ - GST_DEBUG (GST_CAT_EVENT, "fakesink has event %d on pad %s:%s\n",event,GST_DEBUG_PAD_NAME(pad)); - if (event == GST_EVENT_EOS) { - GST_DEBUG(GST_CAT_EVENT, "have EOS\n"); - } - return FALSE; -} diff --git a/plugins/elements/gstfakesrc.c b/plugins/elements/gstfakesrc.c index 6f63cb3141..cae36ea6b3 100644 --- a/plugins/elements/gstfakesrc.c +++ b/plugins/elements/gstfakesrc.c @@ -86,6 +86,7 @@ static void gst_fakesrc_class_init (GstFakeSrcClass *klass); static void gst_fakesrc_init (GstFakeSrc *fakesrc); static GstPad* gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ); +static void gst_fakesrc_update_functions (GstFakeSrc *src); static void gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); @@ -176,17 +177,12 @@ gst_fakesrc_init (GstFakeSrc *fakesrc) fakesrc->srcpads = g_slist_append (NULL, pad); fakesrc->loop_based = FALSE; - - if (fakesrc->loop_based) - gst_element_set_loop_function (GST_ELEMENT (fakesrc), GST_DEBUG_FUNCPTR (gst_fakesrc_loop)); - else - gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get)); + gst_fakesrc_update_functions (fakesrc); fakesrc->num_buffers = -1; fakesrc->buffer_count = 0; fakesrc->silent = FALSE; - // we're ready right away, since we don't have any args... -// gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY); + fakesrc->need_flush = FALSE; } static GstPad* @@ -216,6 +212,32 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ) return srcpad; } +static gboolean +gst_fakesrc_event_handler (GstPad *pad, GstEvent *event) +{ + GstFakeSrc *src; + + src = GST_FAKESRC (gst_pad_get_parent (pad)); + + 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); + break; + } + // 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; + } +} + static void gst_fakesrc_update_functions (GstFakeSrc *src) { @@ -238,6 +260,8 @@ gst_fakesrc_update_functions (GstFakeSrc *src) else { gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get)); } + + gst_pad_set_event_function (pad, gst_fakesrc_event_handler); pads = g_slist_next (pads); } } @@ -333,6 +357,12 @@ gst_fakesrc_get(GstPad *pad) g_return_val_if_fail (GST_IS_FAKESRC (src), NULL); + 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->num_buffers == 0) { g_print("fakesrc: sending EOS\n"); gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED); @@ -388,17 +418,17 @@ gst_fakesrc_loop(GstElement *element) GstBuffer *buf; if (src->num_buffers == 0) { - gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0); - return; + src->eos = TRUE; } else { - if (src->num_buffers > 0) - src->num_buffers--; + if (src->num_buffers > 0) + src->num_buffers--; } 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_buffer_new(); diff --git a/plugins/elements/gstfakesrc.h b/plugins/elements/gstfakesrc.h index ce5c2a9439..d9bcc5dfd5 100644 --- a/plugins/elements/gstfakesrc.h +++ b/plugins/elements/gstfakesrc.h @@ -74,6 +74,7 @@ struct _GstFakeSrc { gint num_buffers; guint64 buffer_count; gboolean silent; + gboolean need_flush; }; struct _GstFakeSrcClass {