From 8a96f93dc27f4b8237f84b1fc6468576f28018f9 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 10 Oct 2007 15:18:44 +0000 Subject: [PATCH] libs/gst/base/gstbasesink.*: Add function to wait for EOS, subclasses can use this to correctly wait for devices to d... Original commit message from CVS: Patch inspired by: Benoit Fouet * libs/gst/base/gstbasesink.c: (gst_base_sink_wait_eos), (gst_base_sink_event): * libs/gst/base/gstbasesink.h: Add function to wait for EOS, subclasses can use this to correctly wait for devices to drain before performing the EOS logic. Fixes #485343. API: gst_base_sink_wait_eos() --- ChangeLog | 11 ++++++ libs/gst/base/gstbasesink.c | 68 +++++++++++++++++++++++++++++++++++++ libs/gst/base/gstbasesink.h | 3 ++ 3 files changed, 82 insertions(+) diff --git a/ChangeLog b/ChangeLog index fd62684914..94b949afad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-10-10 Wim Taymans + + Patch inspired by: Benoit Fouet + + * libs/gst/base/gstbasesink.c: (gst_base_sink_wait_eos), + (gst_base_sink_event): + * libs/gst/base/gstbasesink.h: + Add function to wait for EOS, subclasses can use this to correctly wait + for devices to drain before performing the EOS logic. Fixes #485343. + API: gst_base_sink_wait_eos() + 2007-10-10 Tim-Philipp Müller * gst/gstplugin.h: diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index 2f446c2b9a..4491b15d23 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -1449,6 +1449,74 @@ stopping: } } +/** + * gst_base_sink_wait_eos: + * @sink: the sink + * @time: the running_time to be reached + * @jitter: the jitter to be filled with time diff (can be NULL) + * + * This function will block until @time is reached. It is usually called by + * subclasses that use their own internal synchronisation but want to let the + * EOS be handled by the base class. + * + * This function should only be called with the PREROLL_LOCK held, like when + * receiving an EOS event in the ::event vmethod. + * + * Since 0.10.15 + * + * Returns: #GstFlowReturn + */ +GstFlowReturn +gst_base_sink_wait_eos (GstBaseSink * sink, GstClockTime time, + GstClockTimeDiff * jitter) +{ + GstClockReturn status; + GstFlowReturn ret; + + do { + GST_DEBUG_OBJECT (sink, "checking preroll"); + + /* first wait for the playing state before we can continue */ + if (G_UNLIKELY (sink->need_preroll)) { + ret = gst_base_sink_wait_preroll (sink); + if (ret != GST_FLOW_OK) + goto flushing; + } + + /* preroll done, we can sync since we are in PLAYING now. */ + GST_DEBUG_OBJECT (sink, "possibly waiting for clock to reach %" + GST_TIME_FORMAT, GST_TIME_ARGS (time)); + + /* wait for the clock, this can be interrupted because we got shut down or + * we PAUSED. */ + status = gst_base_sink_wait_clock (sink, time, jitter); + + GST_DEBUG_OBJECT (sink, "clock returned %d", status); + + /* invalid time, no clock or sync disabled, just continue then */ + if (status == GST_CLOCK_BADTIME) + break; + + /* waiting could have been interrupted and we can be flushing now */ + if (G_UNLIKELY (sink->flushing)) + goto flushing; + + /* retry if we got unscheduled, which means we did not reach the timeout + * yet. if some other error occures, we continue. */ + } while (status == GST_CLOCK_UNSCHEDULED); + + GST_DEBUG_OBJECT (sink, "end of stream"); + + return GST_FLOW_OK; + + /* ERRORS */ +flushing: + { + GST_DEBUG_OBJECT (sink, "we are flushing"); + return GST_FLOW_WRONG_STATE; + } +} + /* with STREAM_LOCK, PREROLL_LOCK * * Make sure we are in PLAYING and synchronize an object to the clock. diff --git a/libs/gst/base/gstbasesink.h b/libs/gst/base/gstbasesink.h index 438adf4ad4..cf9c4b6fba 100644 --- a/libs/gst/base/gstbasesink.h +++ b/libs/gst/base/gstbasesink.h @@ -214,6 +214,9 @@ gboolean gst_base_sink_query_latency (GstBaseSink *sink, gboolean *live, gboole GstClockTime *min_latency, GstClockTime *max_latency); GstClockTime gst_base_sink_get_latency (GstBaseSink *sink); +GstFlowReturn gst_base_sink_wait_eos (GstBaseSink *sink, GstClockTime time, + GstClockTimeDiff *jitter); + G_END_DECLS #endif /* __GST_BASE_SINK_H__ */