From a0e5a4a96470d52114346bb8b7cc42a1e2c26d0d Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 27 Sep 2006 13:19:55 +0000 Subject: [PATCH] docs/random/moving-plugins: Make it clear that the "compiled-in descriptions" really mean the element details. Original commit message from CVS: * docs/random/moving-plugins: Make it clear that the "compiled-in descriptions" really mean the element details. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_wait_preroll): Update docs. * docs/libs/gstreamer-libs-sections.txt: * libs/gst/base/gstbasesrc.c: (gst_base_src_wait_playing), (gst_base_src_get_range), (gst_base_src_activate_push): * libs/gst/base/gstbasesrc.h: Added function to block while waiting for PLAYING, this function is used by live sources that block on the clock. API: gst_base_src_wait_playing() --- ChangeLog | 18 ++++++ docs/libs/gstreamer-libs-sections.txt | 1 + docs/random/moving-plugins | 2 +- libs/gst/base/gstbasesink.c | 17 ++--- libs/gst/base/gstbasesrc.c | 115 +++++++++++++++++++++++----------- libs/gst/base/gstbasesrc.h | 8 ++- 6 files changed, 112 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79b70a6..6db5e78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-09-27 Wim Taymans + + * docs/random/moving-plugins: + Make it clear that the "compiled-in descriptions" really mean + the element details. + + * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), + (gst_base_sink_wait_preroll): + Update docs. + + * docs/libs/gstreamer-libs-sections.txt: + * libs/gst/base/gstbasesrc.c: (gst_base_src_wait_playing), + (gst_base_src_get_range), (gst_base_src_activate_push): + * libs/gst/base/gstbasesrc.h: + Added function to block while waiting for PLAYING, this function + is used by live sources that block on the clock. + API: gst_base_src_wait_playing() + 2006-09-27 Tim-Philipp Müller Patch by: Peter Kjellerstedt diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 08e1162..fd7e13b 100644 --- a/docs/libs/gstreamer-libs-sections.txt +++ b/docs/libs/gstreamer-libs-sections.txt @@ -149,6 +149,7 @@ GstBaseSrc GstBaseSrcClass GstBaseSrcFlags +gst_base_src_wait_playing gst_base_src_is_live gst_base_src_set_live gst_base_src_set_format diff --git a/docs/random/moving-plugins b/docs/random/moving-plugins index d7dadb3..de194d9 100644 --- a/docs/random/moving-plugins +++ b/docs/random/moving-plugins @@ -77,7 +77,7 @@ CHECKLIST ext/: plug-ins with external dependencies - The plug-in is documented: - - the compiled-in descriptions should be correct + - the compiled-in descriptions (element details) should be correct - every element in the plug-in should have gtk-doc documentation: - longer description of element - why you would use this element diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index f473834..91514e6 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -35,7 +35,7 @@ * #GstBaseSink infrastructure should be sufficient. * * #GstBaseSink provides support for exactly one sink pad, which should be - * named "sink". A sink implementation (subclass of GstBaseSink) should + * named "sink". A sink implementation (subclass of #GstBaseSink) should * install a pad template in its base_init function, like so: * * static void @@ -53,16 +53,16 @@ * * * #GstBaseSink will handle the prerolling correctly. This means that it will - * return GST_STATE_CHANGE_ASYNC from a state change to PAUSED until the first + * return #GST_STATE_CHANGE_ASYNC from a state change to PAUSED until the first * buffer arrives in this element. The base class will call the - * GstBaseSink::preroll vmethod with this preroll buffer and will then commit + * #GstBaseSink::preroll vmethod with this preroll buffer and will then commit * the state change to the next asynchronously pending state. * * When the element is set to PLAYING, #GstBaseSink will synchronise on the * clock using the times returned from ::get_times. If this function returns * #GST_CLOCK_TIME_NONE for the start time, no synchronisation will be done. * Synchronisation can be disabled entirely by setting the object "sync" - * property to FALSE. + * property to %FALSE. * * After synchronisation the virtual method #GstBaseSink::render will be called. * Subclasses should minimally implement this method. @@ -70,7 +70,8 @@ * Since 0.10.3 subclasses that synchronise on the clock in the ::render method * are supported as well. These classes typically receive a buffer in the render * method and can then potentially block on the clock while rendering. A typical - * example is an audiosink. + * example is an audiosink. Since 0.10.11 these subclasses can use + * gst_base_sink_wait_preroll() to perform the blocking wait. * * Upon receiving the EOS event in the PLAYING state, #GstBaseSink will wait * for the clock to reach the time indicated by the stop time of the last @@ -78,14 +79,14 @@ * EOS in PAUSED, preroll completes, the event is queued and an EOS message is * posted when going to PLAYING. * - * #GstBaseSink will internally use the GST_EVENT_NEW_SEGMENT events to schedule + * #GstBaseSink will internally use the #GST_EVENT_NEWSEGMENT events to schedule * synchronisation and clipping of buffers. Buffers that fall completely outside * of the current segment are dropped. Buffers that fall partially in the * segment are rendered (and prerolled). Subclasses should do any subbuffer * clipping themselves when needed. * * #GstBaseSink will by default report the current playback position in - * GST_FORMAT_TIME based on the current clock time and segment information. + * #GST_FORMAT_TIME based on the current clock time and segment information. * If no clock has been set on the element, the query will be forwarded * upstream. * @@ -127,7 +128,7 @@ * synchronisation. For each dropped buffer it will also send a QoS message * upstream. * - * Last reviewed on 2006-03-31 (0.10.5) + * Last reviewed on 2006-09-27 (0.10.11) */ #ifdef HAVE_CONFIG_H diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c index 030471d..933d3d9 100644 --- a/libs/gst/base/gstbasesrc.c +++ b/libs/gst/base/gstbasesrc.c @@ -37,38 +37,38 @@ * * The source can be configured to operate in any #GstFormat with the * gst_base_src_set_format() method. The currently set format determines - * the format of the internal #GstSegment and any #GST_EVENT_NEW_SEGMENT + * the format of the internal #GstSegment and any #GST_EVENT_NEWSEGMENT * events. The default format for #GstBaseSrc is #GST_FORMAT_BYTES. * * * #GstBaseSrc always supports push mode scheduling. If the following * conditions are met, it also supports pull mode scheduling: * - * The format is set to GST_FORMAT_BYTES (default). + * The format is set to #GST_FORMAT_BYTES (default). * - * #GstBaseSrc::is_seekable returns TRUE. + * #GstBaseSrc::is_seekable returns %TRUE. * * * * * Since 0.10.9, any #GstBaseSrc can enable pull based scheduling at any - * time by overriding #GstBaseSrc::check_get_range so that it returns TRUE. + * time by overriding #GstBaseSrc::check_get_range so that it returns %TRUE. * * * If all the conditions are met for operating in pull mode, #GstBaseSrc is * automatically seekable in push mode as well. The following conditions must * be met to make the element seekable in push mode when the format is not - * GST_FORMAT_BYTES: + * #GST_FORMAT_BYTES: * * - * #GstBaseSrc::is_seekable returns TRUE. + * #GstBaseSrc::is_seekable returns %TRUE. * * * #GstBaseSrc::query can convert all supported seek formats to the * internal format as set with gst_base_src_set_format(). * * - * #GstBaseSrc::do_seek is implemented, performs the seek and returns TRUE. + * #GstBaseSrc::do_seek is implemented, performs the seek and returns %TRUE. * * * @@ -91,7 +91,7 @@ * A live source does not produce data in the PAUSED state. This means that the * #GstBaseSrc::create method will not be called in PAUSED but only in PLAYING. * To signal the pipeline that the element will not produce data, the return - * value from the READY to PAUSED state will be GST_STATE_CHANGE_NO_PREROLL. + * value from the READY to PAUSED state will be #GST_STATE_CHANGE_NO_PREROLL. * * * A typical live source will timestamp the buffers it creates with the @@ -100,6 +100,11 @@ * distributed and running. * * + * Live sources that synchronize and block on the clock (and audio source, for + * example) can since 0.10.12 use gst_base_src_wait_playing() when the ::create + * function was interrupted by a state change to PAUSED. + * + * * The #GstBaseSrc::get_times method can be used to implement pseudo-live * sources. The base source will wait for the specified stream time returned in * #GstBaseSrc::get_times before pushing out the buffer. @@ -107,8 +112,8 @@ * a live source. * * - * There is only support in GstBaseSrc for exactly one source pad, which - * should be named "src". A source implementation (subclass of GstBaseSrc) + * There is only support in #GstBaseSrc for exactly one source pad, which + * should be named "src". A source implementation (subclass of #GstBaseSrc) * should install a pad template in its base_init function, like so: * * @@ -146,8 +151,8 @@ * * ... * // stop recording - * gst_element_set_state (audio_source, GST_STATE_NULL); - * gst_element_set_locked_state (audio_source, TRUE); + * gst_element_set_state (audio_source, #GST_STATE_NULL); + * gst_element_set_locked_state (audio_source, %TRUE); * ... * * Now the application should wait for an EOS message @@ -156,8 +161,8 @@ * * ... * // everything done - shut down pipeline - * gst_element_set_state (pipeline, GST_STATE_NULL); - * gst_element_set_locked_state (audio_source, FALSE); + * gst_element_set_state (pipeline, #GST_STATE_NULL); + * gst_element_set_locked_state (audio_source, %FALSE); * ... * * @@ -167,7 +172,7 @@ * thread might be blocked in PREROLL. * * - * Last reviewed on 2006-07-06 (0.10.9) + * Last reviewed on 2006-09-27 (0.10.11) * * */ @@ -421,6 +426,58 @@ gst_base_src_finalize (GObject * object) } /** + * gst_base_src_wait_playing: + * @src: the src + * + * If the #GstBaseSrcClass::create method performs its own synchronisation against + * the clock it must unblock when going from PLAYING to the PAUSED state and call + * this method before continuing to produce the remaining data. + * + * This function will block until a state change to PLAYING happens (in which + * case this function returns #GST_FLOW_OK) or the processing must be stopped due + * to a state change to READY or a FLUSH event (in which case this function + * returns #GST_FLOW_WRONG_STATE). + * + * Since: 0.10.12 + * + * Returns: #GST_FLOW_OK if @src is PLAYING and processing can + * continue. Any other return value should be returned from the create vmethod. + */ +GstFlowReturn +gst_base_src_wait_playing (GstBaseSrc * src) +{ + /* block until the state changes, or we get a flush, or something */ + GST_LIVE_LOCK (src); + if (src->is_live) { + while (G_UNLIKELY (!src->live_running)) { + GST_DEBUG ("live source signal waiting"); + GST_LIVE_SIGNAL (src); + GST_DEBUG ("live source waiting for running state"); + GST_LIVE_WAIT (src); + GST_DEBUG ("live source unlocked"); + } + /* FIXME, use another variable to signal stopping so that we don't + * have to grab another lock. */ + GST_OBJECT_LOCK (src->srcpad); + if (G_UNLIKELY (GST_PAD_IS_FLUSHING (src->srcpad))) + goto flushing; + GST_OBJECT_UNLOCK (src->srcpad); + } + GST_LIVE_UNLOCK (src); + + return GST_FLOW_OK; + + /* ERRORS */ +flushing: + { + GST_DEBUG_OBJECT (src, "pad is flushing"); + GST_OBJECT_UNLOCK (src->srcpad); + GST_LIVE_UNLOCK (src); + return GST_FLOW_WRONG_STATE; + } +} + +/** * gst_base_src_set_live: * @src: base source instance * @live: new live-mode @@ -1266,23 +1323,9 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length, bclass = GST_BASE_SRC_GET_CLASS (src); - GST_LIVE_LOCK (src); - if (src->is_live) { - while (G_UNLIKELY (!src->live_running)) { - GST_DEBUG ("live source signal waiting"); - GST_LIVE_SIGNAL (src); - GST_DEBUG ("live source waiting for running state"); - GST_LIVE_WAIT (src); - GST_DEBUG ("live source unlocked"); - } - /* FIXME, use another variable to signal stopping so that we don't - * have to grab another lock. */ - GST_OBJECT_LOCK (src->srcpad); - if (G_UNLIKELY (GST_PAD_IS_FLUSHING (src->srcpad))) - goto flushing; - GST_OBJECT_UNLOCK (src->srcpad); - } - GST_LIVE_UNLOCK (src); + ret = gst_base_src_wait_playing (src); + if (ret != GST_FLOW_OK) + goto stopped; if (G_UNLIKELY (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))) goto not_started; @@ -1338,12 +1381,10 @@ done: return ret; /* ERROR */ -flushing: +stopped: { - GST_DEBUG_OBJECT (src, "pad is flushing"); - GST_OBJECT_UNLOCK (src->srcpad); - GST_LIVE_UNLOCK (src); - return GST_FLOW_WRONG_STATE; + GST_DEBUG_OBJECT (src, "wait_playing returned %d", ret); + return ret; } not_started: { diff --git a/libs/gst/base/gstbasesrc.h b/libs/gst/base/gstbasesrc.h index e043aaa..13e2e0d 100644 --- a/libs/gst/base/gstbasesrc.h +++ b/libs/gst/base/gstbasesrc.h @@ -205,10 +205,12 @@ struct _GstBaseSrcClass { GType gst_base_src_get_type (void); -void gst_base_src_set_live (GstBaseSrc *src, gboolean live); -gboolean gst_base_src_is_live (GstBaseSrc *src); +GstFlowReturn gst_base_src_wait_playing (GstBaseSrc *src); -void gst_base_src_set_format (GstBaseSrc *src, GstFormat format); +void gst_base_src_set_live (GstBaseSrc *src, gboolean live); +gboolean gst_base_src_is_live (GstBaseSrc *src); + +void gst_base_src_set_format (GstBaseSrc *src, GstFormat format); G_END_DECLS -- 2.7.4