From d7e33dd2ce79f39f4f832d5747945ba1ee386715 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 3 Feb 2003 22:50:55 +0000 Subject: [PATCH] - Use the eventhandler instead of the event function to send events. Original commit message from CVS: - Use the eventhandler instead of the event function to send events. - make the scheduler setup the eventhandlers - intercept flush events on pads links that can potentially queue data and flush it. - some more debugging info in spider. I can think of one case where this flush might fail: unconnected pads where the scheduler has not set up the eventhandler yet. I'll come up with a solution for that soon. --- gst/autoplug/gstspideridentity.c | 4 +-- gst/gstpad.c | 4 +-- gst/schedulers/gstbasicscheduler.c | 42 +++++++++++++++++++++++++++++ gst/schedulers/gstoptimalscheduler.c | 52 ++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 4 deletions(-) diff --git a/gst/autoplug/gstspideridentity.c b/gst/autoplug/gstspideridentity.c index 7992f6d..8d5b606 100644 --- a/gst/autoplug/gstspideridentity.c +++ b/gst/autoplug/gstspideridentity.c @@ -190,6 +190,7 @@ gst_spider_identity_chain (GstPad *pad, GstBuffer *buf) if ((ident->src != NULL) && (GST_PAD_PEER (ident->src) != NULL)) { /* g_print("pushing buffer %p (refcount %d - buffersize %d) to pad %s:%s\n", buf, GST_BUFFER_REFCOUNT (buf), GST_BUFFER_SIZE (buf), GST_DEBUG_PAD_NAME (ident->src)); */ + GST_DEBUG (0, "push %p %lld", buf, GST_BUFFER_OFFSET (buf)); gst_pad_push (ident->src, buf); } else if (GST_IS_BUFFER (buf)) { gst_buffer_unref (buf); @@ -401,7 +402,6 @@ gst_spider_identity_src_loop (GstSpiderIdentity *ident) gst_spider_identity_dumb_loop (ident); return; } - gst_element_interrupt (GST_ELEMENT (ident)); } /* This loop function is only needed when typefinding. @@ -525,7 +525,7 @@ gst_spider_identity_handle_src_event (GstPad *pad, GstEvent *event) gboolean res = TRUE; GstSpiderIdentity *ident; - GST_DEBUG (0, "spider_identity src_event\n"); + GST_DEBUG (0, "spider_identity src_event"); ident = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad)); diff --git a/gst/gstpad.c b/gst/gstpad.c index 71e20e7..cc37b0d 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -2871,8 +2871,8 @@ gst_pad_send_event (GstPad *pad, GstEvent *event) GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s", GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad)); - if (GST_RPAD_EVENTFUNC (rpad)) - success = GST_RPAD_EVENTFUNC (rpad) (GST_PAD_CAST (rpad), event); + if (GST_RPAD_EVENTHANDLER (rpad)) + success = GST_RPAD_EVENTHANDLER (rpad) (GST_PAD_CAST (rpad), event); else { GST_DEBUG (GST_CAT_EVENT, "there's no event function for pad %s:%s", GST_DEBUG_PAD_NAME (rpad)); diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c index f36eb82..ba339b5 100644 --- a/gst/schedulers/gstbasicscheduler.c +++ b/gst/schedulers/gstbasicscheduler.c @@ -524,6 +524,42 @@ gst_basic_scheduler_gethandler_proxy (GstPad * pad) } static gboolean +gst_basic_scheduler_eventhandler_proxy (GstPad *srcpad, GstEvent *event) +{ + gboolean flush; + + GST_INFO (GST_CAT_SCHEDULING, "intercepting event %d on pad %s:%s", + GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (srcpad)); + + /* figure out if we need to flush */ + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + flush = TRUE; + break; + case GST_EVENT_SEEK: + case GST_EVENT_SEEK_SEGMENT: + flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; + break; + default: + flush = FALSE; + break; + } + + if (flush) { + GST_INFO (GST_CAT_SCHEDULING, "event is flush"); + GstData *data = GST_DATA (GST_RPAD_BUFPEN (srcpad)); + + if (data) { + GST_INFO (GST_CAT_SCHEDULING, "need to clear some buffers"); + + gst_data_unref (data); + GST_RPAD_BUFPEN (srcpad) = NULL; + } + } + return GST_RPAD_EVENTFUNC (srcpad) (srcpad, event); +} + +static gboolean gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain) { GList *elements; @@ -627,6 +663,8 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain) } } } + /* in any case we need to copy the eventfunc into the handler */ + GST_RPAD_EVENTHANDLER (peerpad) = GST_RPAD_EVENTFUNC (peerpad); } /* if the element is DECOUPLED or outside the manager, we have to chain */ @@ -652,12 +690,16 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain) "setting cothreaded push proxy for sinkpad %s:%s", GST_DEBUG_PAD_NAME (pad)); GST_RPAD_CHAINHANDLER (pad) = GST_DEBUG_FUNCPTR (gst_basic_scheduler_chainhandler_proxy); + GST_RPAD_EVENTHANDLER (pad) = GST_RPAD_EVENTFUNC (pad); } else { GST_DEBUG (GST_CAT_SCHEDULING, "setting cothreaded pull proxy for srcpad %s:%s", GST_DEBUG_PAD_NAME (pad)); GST_RPAD_GETHANDLER (pad) = GST_DEBUG_FUNCPTR (gst_basic_scheduler_gethandler_proxy); + /* the gethandler proxy function can queue a buffer in the bufpen, we need + * to remove this buffer when a flush event is sent on the pad */ + GST_RPAD_EVENTHANDLER (pad) = GST_DEBUG_FUNCPTR (gst_basic_scheduler_eventhandler_proxy); } } } diff --git a/gst/schedulers/gstoptimalscheduler.c b/gst/schedulers/gstoptimalscheduler.c index 86d1777..1cd4945 100644 --- a/gst/schedulers/gstoptimalscheduler.c +++ b/gst/schedulers/gstoptimalscheduler.c @@ -922,6 +922,48 @@ gst_opt_scheduler_chain_wrapper (GstPad *sinkpad, GstBuffer *buffer) } } +static void +clear_queued (GstData *data, gpointer user_data) +{ + gst_data_unref (data); +} + +static gboolean +gst_opt_scheduler_event_wrapper (GstPad *srcpad, GstEvent *event) +{ + gboolean flush; + + GST_INFO (GST_CAT_SCHEDULING, "intercepting event %d on pad %s:%s", + GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (srcpad)); + + /* figure out if this is a flush event */ + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + flush = TRUE; + break; + case GST_EVENT_SEEK: + case GST_EVENT_SEEK_SEGMENT: + flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; + break; + default: + flush = FALSE; + break; + } + + if (flush) { + GST_INFO (GST_CAT_SCHEDULING, "event is flush"); + GList *buflist = GST_PAD_BUFLIST (srcpad); + + if (buflist) { + GST_INFO (GST_CAT_SCHEDULING, "need to clear some buffers"); + g_list_foreach (buflist, (GFunc) clear_queued, NULL); + g_list_free (buflist); + GST_PAD_BUFLIST (srcpad) = NULL; + } + } + return GST_RPAD_EVENTFUNC (srcpad) (srcpad, event); +} + /* setup the scheduler context for a group. The right schedule function * is selected based on the group type and cothreads are created if * needed */ @@ -1352,6 +1394,8 @@ gst_opt_scheduler_pad_link (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad GST_RPAD_CHAINHANDLER (sinkpad) = GST_RPAD_CHAINFUNC (sinkpad); else GST_RPAD_CHAINHANDLER (sinkpad) = gst_opt_scheduler_chain_wrapper; + GST_RPAD_EVENTHANDLER (srcpad) = GST_RPAD_EVENTFUNC (srcpad); + GST_RPAD_EVENTHANDLER (sinkpad) = GST_RPAD_EVENTFUNC (sinkpad); /* the two elements should be put into the same group, * this also means that they are in the same chain automatically */ @@ -1376,6 +1420,8 @@ gst_opt_scheduler_pad_link (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad GST_RPAD_CHAINHANDLER (sinkpad) = GST_RPAD_CHAINFUNC (sinkpad); else GST_RPAD_CHAINHANDLER (sinkpad) = gst_opt_scheduler_chain_wrapper; + GST_RPAD_EVENTHANDLER (srcpad) = GST_RPAD_EVENTFUNC (srcpad); + GST_RPAD_EVENTHANDLER (sinkpad) = GST_RPAD_EVENTFUNC (sinkpad); /* the two elements should be put into the same group, * this also means that they are in the same chain automatically, @@ -1387,6 +1433,8 @@ gst_opt_scheduler_pad_link (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad GST_INFO (GST_CAT_SCHEDULING, "get to loop based link"); GST_RPAD_GETHANDLER (srcpad) = GST_RPAD_GETFUNC (srcpad); + GST_RPAD_EVENTHANDLER (srcpad) = GST_RPAD_EVENTFUNC (srcpad); + GST_RPAD_EVENTHANDLER (sinkpad) = GST_RPAD_EVENTFUNC (sinkpad); /* the two elements should be put into the same group, * this also means that they are in the same chain automatically, @@ -1403,6 +1451,10 @@ gst_opt_scheduler_pad_link (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad GST_RPAD_CHAINHANDLER (sinkpad) = gst_opt_scheduler_loop_wrapper; GST_RPAD_GETHANDLER (srcpad) = gst_opt_scheduler_get_wrapper; + GST_RPAD_EVENTHANDLER (sinkpad) = GST_RPAD_EVENTFUNC (sinkpad); + /* events on the srcpad have to be intercepted as we might need to + * flush the buffer lists */ + GST_RPAD_EVENTHANDLER (srcpad) = gst_opt_scheduler_event_wrapper; group1 = GST_ELEMENT_SCHED_GROUP (element1); group2 = GST_ELEMENT_SCHED_GROUP (element2); -- 2.7.4