Documentation updates.

Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gstbin.c: (bin_bus_handler), (gst_bin_handle_message_func):
* gst/gstbin.h:
* gst/gstbus.c: (gst_bus_class_init):
* gst/gstbus.h:
* gst/gstclock.c:
* gst/gstelement.c: (gst_element_set_locked_state):
* gst/gstsegment.c:
Documentation updates.
* gst/gstpipeline.c: (gst_pipeline_get_type),
(gst_pipeline_class_init), (gst_pipeline_init),
(gst_pipeline_dispose), (gst_pipeline_set_property),
(gst_pipeline_get_property), (do_pipeline_seek),
(gst_pipeline_send_event), (gst_pipeline_change_state),
(gst_pipeline_provide_clock_func), (gst_pipeline_set_delay),
(gst_pipeline_get_delay):
* gst/gstpipeline.h:
Added methods for setting the delay.
API: gst_pipeline_set_delay
API: gst_pipeline_get_delay
Add pipeline debug category
Various cleanups.
Updated docs.
Don't reset stream time when seek failed.
This commit is contained in:
Wim Taymans 2006-03-13 11:04:38 +00:00
parent b69033434f
commit 429ebfff2c
11 changed files with 393 additions and 126 deletions

View file

@ -1,3 +1,31 @@
2006-03-13 Wim Taymans <wim@fluendo.com>
* docs/gst/gstreamer-sections.txt:
* gst/gstbin.c: (bin_bus_handler), (gst_bin_handle_message_func):
* gst/gstbin.h:
* gst/gstbus.c: (gst_bus_class_init):
* gst/gstbus.h:
* gst/gstclock.c:
* gst/gstelement.c: (gst_element_set_locked_state):
* gst/gstsegment.c:
Documentation updates.
* gst/gstpipeline.c: (gst_pipeline_get_type),
(gst_pipeline_class_init), (gst_pipeline_init),
(gst_pipeline_dispose), (gst_pipeline_set_property),
(gst_pipeline_get_property), (do_pipeline_seek),
(gst_pipeline_send_event), (gst_pipeline_change_state),
(gst_pipeline_provide_clock_func), (gst_pipeline_set_delay),
(gst_pipeline_get_delay):
* gst/gstpipeline.h:
Added methods for setting the delay.
API: gst_pipeline_set_delay
API: gst_pipeline_get_delay
Add pipeline debug category
Various cleanups.
Updated docs.
Don't reset stream time when seek failed.
2006-03-13 Wim Taymans <wim@fluendo.com>
* docs/design/draft-klass.txt:

View file

@ -1404,16 +1404,23 @@ GstPipelineFlags
gst_pipeline_new
gst_pipeline_auto_clock
gst_pipeline_get_bus
gst_pipeline_get_clock
gst_pipeline_get_last_stream_time
gst_pipeline_set_clock
gst_pipeline_set_new_stream_time
gst_pipeline_use_clock
gst_pipeline_get_auto_flush_bus
gst_pipeline_set_clock
gst_pipeline_get_clock
gst_pipeline_use_clock
gst_pipeline_auto_clock
gst_pipeline_set_new_stream_time
gst_pipeline_get_last_stream_time
gst_pipeline_set_auto_flush_bus
gst_pipeline_get_auto_flush_bus
gst_pipeline_set_delay
gst_pipeline_get_delay
<SUBSECTION Standard>
GstPipelineClass
GST_PIPELINE

View file

@ -79,21 +79,58 @@
* a SEGMENT_START have posted a SEGMENT_DONE.</para></listitem>
* </varlistentry>
* <varlistentry>
* <term>GST_MESSAGE_DURATION</term>
* <listitem><para> Is posted by an element that detected a change
* in the stream duration. The default bin behaviour is to clear any
* cached duration values so that the next duration query will perform
* a full duration recalculation. The duration change is posted to the
* application so that it can refetch the new duration with a duration
* query.
* </para></listitem>
* </varlistentry>
* <varlistentry>
* <term>GST_MESSAGE_CLOCK_LOST</term>
* <listitem><para> This message is posted by an element when it
* can no longer provide a clock. The default bin behaviour is to
* check if the lost clock was the one provided by the bin. If so and
* the bin is currently in the PLAYING state, the message is forwarded to
* the bin parent.
* This message is also generated when a clock provider is removed from
* the bin. If this message is received by the application, it should
* PAUSE the pipeline and set it back to PLAYING to force a new clock
* distribution.
* </para></listitem>
* </varlistentry>
* <varlistentry>
* <term>GST_MESSAGE_CLOCK_PROVIDE</term>
* <listitem><para> This message is generated when an element
* can provide a clock. This mostly happens when a new clock
* provider is added to the bin. The default behaviour of the bin is to
* mark the currently selected clock as dirty, which will perform a clock
* recalculation the next time the bin is asked to provide a clock.
* This message is never sent tot the application but is forwarded to
* the parent of the bin.
* </para></listitem>
* </varlistentry>
* <varlistentry>
* <term>OTHERS</term>
* <listitem><para> posted upwards.</para></listitem>
* </varlistentry>
* </variablelist>
*
*
* A #GstBin implements the following default behaviour for answering to a
* #GstQuery:
* <variablelist>
* <varlistentry>
* <term>GST_QUERY_DURATION</term>
* <listitem><para>If the query has been asked before with the same format,
* <listitem><para>If the query has been asked before with the same format
* and the bin is a toplevel bin (ie. has no parent),
* use the cached previous value. If no previous value was cached, the
* query is sent to all sink elements in the bin and the MAXIMUM of all
* values is returned and cached. If no sinks are available in the bin, the
* query fails.</para></listitem>
* values is returned. If the bin is a toplevel bin the value is cached.
* If no sinks are available in the bin, the query fails.
* </para></listitem>
* </varlistentry>
* <varlistentry>
* <term>OTHERS</term>
@ -110,7 +147,7 @@
* </para>
* </refsect2>
*
* Last reviewed on 2005-12-16 (0.10.0)
* Last reviewed on 2006-03-12 (0.10.5)
*/
#include "gst_private.h"
@ -1918,6 +1955,21 @@ gst_bin_recalc_func (GstBin * bin, gpointer data)
gst_object_unref (bin);
}
static GstBusSyncReply
bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
{
GstBinClass *bclass;
bclass = GST_BIN_GET_CLASS (bin);
if (bclass->handle_message)
bclass->handle_message (bin, message);
else
gst_message_unref (message);
return GST_BUS_DROP;
}
/* handle child messages:
*
* GST_MESSAGE_EOS: This message is only posted by sinks
@ -1941,23 +1993,26 @@ gst_bin_recalc_func (GstBin * bin, gpointer data)
* changes its duration marks our cached values invalid.
* This message is also posted upwards.
*
* GST_MESSAGE_CLOCK_LOST: This message is posted by an element when it
* can no longer provide a clock. The default bin behaviour is to
* check if the lost clock was the one provided by the bin. If so and
* we are currently in the PLAYING state, we forward the message to
* our parent.
* This message is also generated when we remove a clock provider from
* a bin. If this message is received by the application, it should
* PAUSE the pipeline and set it back to PLAYING to force a new clock
* distribution.
*
* GST_MESSAGE_CLOCK_PROVIDE: This message is generated when an element
* can provide a clock. This mostly happens when we add a new clock
* provider to the bin. The default behaviour of the bin is to mark the
* currently selected clock as dirty, which will perform a clock
* recalculation the next time we are asked to provide a clock.
* This message is never sent tot the application but is forwarded to
* the parent.
*
* OTHER: post upwards.
*/
static GstBusSyncReply
bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
{
GstBinClass *bclass;
bclass = GST_BIN_GET_CLASS (bin);
if (bclass->handle_message)
bclass->handle_message (bin, message);
else
gst_message_unref (message);
return GST_BUS_DROP;
}
static void
gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
{

View file

@ -83,7 +83,7 @@ typedef struct _GstBinClass GstBinClass;
* @children: the list of children in this bin
* @children_cookie: updated whenever @children changes
* @child_bus: internal bus for handling child messages
* @messages: queued messages
* @messages: queued and cached messages
* @polling: the bin is currently calculating its state
* @state_dirty: the bin needs to recalculate its state
* @clock_dirty: the bin needs to select a new clock

View file

@ -48,7 +48,9 @@
* bus to handle them.
* Alternatively the application can register an asynchronous bus function
* using gst_bus_add_watch_full() or gst_bus_add_watch(). This function will
* receive messages a short while after they have been posted.
* install a #GSource in the default glib main loop and will deliver messages
* a short while after they have been posted. Note that the main loop should
* be running for the asynchronous callbacks.
*
* It is also possible to get messages from the bus without any thread
* marshalling with the gst_bus_set_sync_handler() method. This makes it
@ -61,7 +63,7 @@
* Note that a #GstPipeline will set its bus into flushing state when changing
* from READY to NULL state.
*
* Last reviewed on 2005-10-28 (0.9.4)
* Last reviewed on 2006-03-12 (0.10.5)
*/
#include <errno.h>
@ -195,7 +197,8 @@ gst_bus_class_init (GstBusClass * klass)
* @message: the message that has been posted asynchronously
*
* A message has been posted on the bus. This signal is emitted from a
* GSource added to the mainloop.
* GSource added to the mainloop. this signal will only be emited when
* there is a mainloop running.
*/
gst_bus_signals[ASYNC_MESSAGE] =
g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
@ -684,13 +687,13 @@ gst_bus_create_watch (GstBus * bus)
* @user_data: user data passed to @func.
* @notify: the function to call when the source is removed.
*
* Adds a bus watch to the default main context with the given priority.
* If the func returns FALSE, the source will be removed.
* Adds a bus watch to the default main context with the given @priority.
*
* When the func is called, the message belongs to the caller; if you want to
* keep a copy of it, call gst_message_ref() before leaving the func.
* When @func is called, the message belongs to the caller; if you want to
* keep a copy of it, call gst_message_ref() before leaving @func.
*
* The watch can be removed using #g_source_remove().
* The watch can be removed using g_source_remove() or by returning FALSE
* from @func.
*
* Returns: The event source id.
*
@ -727,7 +730,8 @@ gst_bus_add_watch_full (GstBus * bus, gint priority,
*
* Adds a bus watch to the default main context with the default priority.
*
* The watch can be removed using #g_source_remove().
* The watch can be removed using g_source_remove() or by returning FALSE
* from @func.
*
* Returns: The event source id.
*
@ -874,7 +878,7 @@ gst_bus_poll (GstBus * bus, GstMessageType events, GstClockTimeDiff timeout)
* @message: the #GstMessage received
* @data: user data
*
* A helper GstBusFunc that can be used to convert all asynchronous messages
* A helper #GstBusFunc that can be used to convert all asynchronous messages
* into signals.
*
* Returns: TRUE
@ -925,7 +929,7 @@ gst_bus_sync_signal_handler (GstBus * bus, GstMessage * message, gpointer data)
* gst_bus_enable_sync_message_emission:
* @bus: a #GstBus on which you want to receive the "sync-message" signal
*
* Instructs GStreamer to emit the sync-message signal after running the bus's
* Instructs GStreamer to emit the "sync-message" signal after running the bus's
* sync handler. This function is here so that code can ensure that they can
* synchronously receive messages without having to affect what the bin's sync
* handler is.
@ -936,9 +940,9 @@ gst_bus_sync_signal_handler (GstBus * bus, GstMessage * message, gpointer data)
*
* While this function looks similar to gst_bus_add_signal_watch(), it is not
* exactly the same -- this function enables <emphasis>synchronous</emphasis> emission of
* signals when messages arrive; gst_bus_add_signal_watch adds an idle callback
* signals when messages arrive; gst_bus_add_signal_watch() adds an idle callback
* to pop messages off the bus <emphasis>asynchronously</emphasis>. The sync-message signal
* comes from the thread of whatever object posted the message; the message
* comes from the thread of whatever object posted the message; the "message"
* signal is marshalled to the main thread via the main loop.
*
* MT safe.
@ -960,14 +964,14 @@ gst_bus_enable_sync_message_emission (GstBus * bus)
* @bus: a #GstBus on which you previously called
* gst_bus_enable_sync_message_emission()
*
* Instructs GStreamer to stop emitting the sync-message signal for this bus.
* Instructs GStreamer to stop emitting the "sync-message" signal for this bus.
* See gst_bus_enable_sync_message_emission() for more information.
*
* In the event that multiple pieces of code have called
* gst_bus_enable_sync_message_emission(), the sync-message emissions will only
* be stopped after all calls to gst_bus_enable_sync_message_emission() were
* "cancelled" by calling this function. In this way the semantics are exactly
* the same as gst_object_ref(); that which calls enable should also call
* the same as gst_object_ref() that which calls enable should also call
* disable.
*
* MT safe.
@ -992,8 +996,8 @@ gst_bus_disable_sync_message_emission (GstBus * bus)
* @priority: The priority of the watch.
*
* Adds a bus signal watch to the default main context with the given priority.
* After calling this statement, the bus will emit the message signal for each
* message posted on the bus.
* After calling this statement, the bus will emit the "message" signal for each
* message posted on the bus when the main loop is running.
*
* This function may be called multiple times. To clean up, the caller is
* responsible for calling gst_bus_remove_signal_watch() as many times as this
@ -1031,7 +1035,7 @@ done:
*
* Adds a bus signal watch to the default main context with the default
* priority.
* After calling this statement, the bus will emit the message signal for each
* After calling this statement, the bus will emit the "message" signal for each
* message posted on the bus.
*
* This function may be called multiple times. To clean up, the caller is

View file

@ -98,6 +98,9 @@ typedef GstBusSyncReply (*GstBusSyncHandler) (GstBus * bus, GstMessage * messag
* The message passed to the function will be unreffed after execution of this
* function so it should not be freed in the function.
*
* Note that this function is used as a GSourceFunc which means that returning
* FALSE will remove the GSource from the mainloop.
*
* Returns: %FALSE if the event source should be removed.
*/
typedef gboolean (*GstBusFunc) (GstBus * bus, GstMessage * message, gpointer data);

View file

@ -24,7 +24,7 @@
/**
* SECTION:gstclock
* @short_description: Abstract class for global clocks
* @see_also: #GstSystemClock
* @see_also: #GstSystemClock, #GstPipeline
*
* GStreamer uses a global clock to synchronize the plugins in a pipeline.
* Different clock implementations are possible by implementing this abstract
@ -35,10 +35,11 @@
* clock implementation but time is always expressed in nanoseconds. Since the
* baseline of the clock is undefined, the clock time returned is not
* meaningful in itself, what matters are the deltas between two clock times.
* The time returned by a clock is called the absolute time.
*
* The pipeline uses the clock to calculate the stream time. Usually all
* renderers synchronize to the global clock using the buffer timestamps, the
* newsegment events and the element's base time.
* newsegment events and the element's base time, see #GstPipeline.
*
* A clock implementation can support periodic and single shot clock
* notifications both synchronous and asynchronous.

View file

@ -25,9 +25,9 @@
* @short_description: Abstract base class for all pipeline elements
* @see_also: #GstElementFactory, #GstPad
*
* GstElement is the base class needed to construct an element that can be
* used in a GStreamer pipeline. As such, it is not a functional entity, and
* cannot do anything when placed in a pipeline.
* GstElement is the abstract base class needed to construct an element that
* can be used in a GStreamer pipeline. Please refer to the plugin writers
* guide for more information on creating #GstElement subclasses.
*
* The name of a #GstElement can be get with gst_element_get_name() and set with
* gst_element_set_name(). For speed, GST_ELEMENT_NAME() can be used in the
@ -73,7 +73,7 @@
* toplevel #GstPipeline so the clock functions are only to be used in very
* specific situations.
*
* Last reviewed on 2005-11-23 (0.9.5)
* Last reviewed on 2006-03-12 (0.10.5)
*/
#include "gst_private.h"

View file

@ -24,23 +24,59 @@
* SECTION:gstpipeline
* @short_description: Top-level bin with clocking and bus management
functionality.
* @see_also: #GstBin
* @see_also: #GstElement, #GstBin, #GstClock, #GstBus
*
* In almost all cases, you'll want to use a GstPipeline when creating a filter
* graph. The GstPipeline will manage the selection and distribution of a
* global
* clock as well as provide a GstBus to the application.
*
* The pipeline will also use the selected clock to calculate the stream time
* of the pipeline.
*
* When sending a seek event to a GstPipeline, it will make sure that the
* pipeline is properly PAUSED and resumed as well as update the new stream
* time after the seek.
* A #GstPipeline is a special #GstBin used as the toplevel container for
* the filter graph. The #GstPipeline will manage the selection and
* distribution of a global #GstClock as well as provide a #GstBus to the
* application. It will also implement a default behavour for managing
* seek events (see gst_element_seek()).
*
* gst_pipeline_new() is used to create a pipeline. when you are done with
* the pipeline, use gst_object_unref() to free its resources including all
* added #GstElement objects (if not otherwise referenced).
*
* Elements are added and removed from the pipeline using the #GstBin
* methods like gst_bin_add() and gst_bin_remove() (see #GstBin).
*
* Before changing the state of the #GstPipeline (see #GstElement) a #GstBus
* can be retrieved with gst_pipeline_get_bus(). This bus can then be
* used to receive #GstMessage from the elements in the pipeline.
*
* By default, a #GstPipeline will automatically flush the pending #GstBus
* messages when going to the NULL state to ensure that no circular
* references exist when no messages are read from the #GstBus. This
* behaviour can be changed with gst_pipeline_set_auto_flush_bus().
*
* When the #GstPipeline performs the PAUSED to PLAYING state change it will
* select a clock for the elements. The clock selection algorithm will by
* default select a clock provided by an element that is most upstream
* (closest to the source). For live pipelines (ones that return
* #GST_STATE_CHANGE_NO_PREROLL from the gst_element_set_state() call) this
* will select the clock provided by the live source. For normal pipelines
* this will select a clock provided by the sinks (most likely the audio
* sink). If no element provides a clock, a default #GstSystemClock is used.
*
* The clock selection can be controlled with the gst_pipeline_use_clock()
* method, which will enforce a given clock on the pipeline. With
* gst_pipeline_auto_clock() the default clock selection algorithm can be
* restored.
*
* A #GstPipeline maintains a stream time for the elements. The stream
* time is defined as the difference between the current clock time and
* the base time. When the pipeline goes to READY or a flushing seek is
* performed on it, the stream time is reset to 0. When the pipeline is
* set from PLAYING to PAUSED, the current clock time is sampled and used to
* configure the base time for the elements when the pipeline is set
* to PLAYING again. This default behaviour can be changed with the
* gst_pipeline_set_new_stream_time() method.
*
* When sending a flushing seek event to a GstPipeline (see
* gst_element_seek()), it will make sure that the pipeline is properly
* PAUSED and resumed as well as set the new stream time to 0 when the
* seek succeeded.
*
* Last reviewed on 2006-03-12 (0.10.5)
*/
#include "gst_private.h"
@ -51,6 +87,9 @@
#include "gstinfo.h"
#include "gstsystemclock.h"
GST_DEBUG_CATEGORY_STATIC (pipeline_debug);
#define GST_CAT_DEFAULT pipeline_debug
static GstElementDetails gst_pipeline_details =
GST_ELEMENT_DETAILS ("Pipeline object",
"Generic/Bin",
@ -80,6 +119,7 @@ enum
struct _GstPipelinePrivate
{
/* with LOCK */
gboolean auto_flush_bus;
};
@ -110,7 +150,7 @@ gst_pipeline_get_type (void)
{
static GType pipeline_type = 0;
if (!pipeline_type) {
if (G_UNLIKELY (pipeline_type == 0)) {
static const GTypeInfo pipeline_info = {
sizeof (GstPipelineClass),
gst_pipeline_base_init,
@ -126,6 +166,9 @@ gst_pipeline_get_type (void)
pipeline_type =
g_type_register_static (GST_TYPE_BIN, "GstPipeline", &pipeline_info, 0);
GST_DEBUG_CATEGORY_INIT (pipeline_debug, "pipeline", GST_DEBUG_BOLD,
"debugging info for the 'pipeline' container element");
}
return pipeline_type;
}
@ -152,21 +195,28 @@ gst_pipeline_class_init (gpointer g_class, gpointer class_data)
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pipeline_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pipeline_get_property);
/**
* GstPipeline:delay
*
* The expected delay needed for elements to spin up to the
* PLAYING state expressed in nanoseconds.
* see gst_pipeline_set_delay() for more information on this option.
**/
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DELAY,
g_param_spec_uint64 ("delay", "Delay",
"Expected delay needed for elements "
"to spin up to PLAYING in nanoseconds", 0, G_MAXUINT64, DEFAULT_DELAY,
G_PARAM_READWRITE));
/**
* GstPipeline:auto-flush-bus:
*
* Whether or not to automatically flush all messages on the
* pipeline's bus when going from READY to NULL state. Please see
* gst_pipeline_set_auto_flush_bus() for more information on this option.
*
* Since: 0.10.4
**/
/**
* GstPipeline:auto-flush-bus:
*
* Whether or not to automatically flush all messages on the
* pipeline's bus when going from READY to NULL state. Please see
* gst_pipeline_set_auto_flush_bus() for more information on this option.
*
* Since: 0.10.4
**/
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_AUTO_FLUSH_BUS,
g_param_spec_boolean ("auto-flush-bus", "Auto Flush Bus",
"Whether to automatically flush the pipeline's bus when going "
@ -189,14 +239,15 @@ gst_pipeline_init (GTypeInstance * instance, gpointer g_class)
GstBus *bus;
pipeline->priv = GST_PIPELINE_GET_PRIVATE (pipeline);
pipeline->priv->auto_flush_bus = DEFAULT_AUTO_FLUSH_BUS;
/* set default property values */
pipeline->priv->auto_flush_bus = DEFAULT_AUTO_FLUSH_BUS;
pipeline->delay = DEFAULT_DELAY;
/* create and set a default bus */
bus = gst_bus_new ();
gst_element_set_bus (GST_ELEMENT_CAST (pipeline), bus);
GST_DEBUG_OBJECT (pipeline, "set bus %" GST_PTR_FORMAT " on pipeline", bus);
gst_object_unref (bus);
}
@ -207,6 +258,7 @@ gst_pipeline_dispose (GObject * object)
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pipeline, "dispose");
/* clear and unref any fixed clock */
gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
G_OBJECT_CLASS (parent_class)->dispose (object);
@ -221,10 +273,10 @@ gst_pipeline_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (pipeline);
switch (prop_id) {
case PROP_DELAY:
pipeline->delay = g_value_get_uint64 (value);
gst_pipeline_set_delay (pipeline, g_value_get_uint64 (value));
break;
case PROP_AUTO_FLUSH_BUS:
pipeline->priv->auto_flush_bus = g_value_get_boolean (value);
gst_pipeline_set_auto_flush_bus (pipeline, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -242,10 +294,10 @@ gst_pipeline_get_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (pipeline);
switch (prop_id) {
case PROP_DELAY:
g_value_set_uint64 (value, pipeline->delay);
g_value_set_uint64 (value, gst_pipeline_get_delay (pipeline));
break;
case PROP_AUTO_FLUSH_BUS:
g_value_set_boolean (value, pipeline->priv->auto_flush_bus);
g_value_set_boolean (value, gst_pipeline_get_auto_flush_bus (pipeline));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -254,6 +306,16 @@ gst_pipeline_get_property (GObject * object, guint prop_id,
GST_OBJECT_UNLOCK (pipeline);
}
/* default pipeline seeking code:
*
* If the pipeline is PLAYING and a flushing seek is done, set
* the pipeline to PAUSED before doing the seek.
*
* A flushing seek also resets the stream time to 0 so that when
* we go back to PLAYING after the seek, the base_time is recalculated
* and redistributed to the elements.
*
*/
static gboolean
do_pipeline_seek (GstElement * element, GstEvent * event)
{
@ -263,10 +325,12 @@ do_pipeline_seek (GstElement * element, GstEvent * event)
gboolean was_playing = FALSE;
gboolean res;
/* we are only interested in the FLUSH flag of the seek event. */
gst_event_parse_seek (event, &rate, NULL, &flags, NULL, NULL, NULL, NULL);
flush = flags & GST_SEEK_FLAG_FLUSH;
/* if flushing seek, get the current state */
if (flush) {
GstState state;
@ -276,34 +340,39 @@ do_pipeline_seek (GstElement * element, GstEvent * event)
was_playing = state == GST_STATE_PLAYING;
if (was_playing) {
/* and PAUSE when the pipeline was PLAYING, we don't need
* to wait for the state change to complete since we are going
* to flush out any preroll sample anyway */
gst_element_set_state (element, GST_STATE_PAUSED);
}
}
/* let parent class implement the seek behaviour */
res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
if (flush && res) {
/* if flushing seek restore previous state */
if (flush) {
gboolean need_reset;
GST_OBJECT_LOCK (element);
need_reset = GST_PIPELINE (element)->stream_time != GST_CLOCK_TIME_NONE;
GST_OBJECT_UNLOCK (element);
/* need to reset the stream time to 0 after a flushing seek, unless the user
explicitly disabled this behavior by setting stream time to NONE */
if (need_reset)
/* need to reset the stream time to 0 after a successfull flushing seek,
* unless the user explicitly disabled this behavior by setting stream
* time to NONE */
if (need_reset && res)
gst_pipeline_set_new_stream_time (GST_PIPELINE (element), 0);
if (was_playing)
/* and continue playing */
/* and continue playing, this might return ASYNC in which case the
* application can wait for the PREROLL to complete after the seek.
*/
gst_element_set_state (element, GST_STATE_PLAYING);
}
return res;
}
/* sending a seek event on the pipeline pauses the pipeline if it
* was playing.
*/
static gboolean
gst_pipeline_send_event (GstElement * element, GstEvent * event)
{
@ -312,9 +381,11 @@ gst_pipeline_send_event (GstElement * element, GstEvent * event)
switch (event_type) {
case GST_EVENT_SEEK:
/* do the default seek handling */
res = do_pipeline_seek (element, event);
break;
default:
/* else parent implements the defaults */
res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
break;
}
@ -375,11 +446,14 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
GST_OBJECT_UNLOCK (element);
if (new_clock) {
/* now distribute the clock (which could be NULL I guess) */
/* now distribute the clock (which could be NULL). If some
* element refuses the clock, this will return FALSE and
* we effectively fail the state change. */
if (!gst_element_set_clock (element, clock))
goto invalid_clock;
/* if we selected a new clock, let the app know about it */
/* if we selected and distributed a new clock, let the app
* know about it */
gst_element_post_message (element,
gst_message_new_new_clock (GST_OBJECT_CAST (element), clock));
}
@ -403,6 +477,7 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
}
break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
case GST_STATE_CHANGE_READY_TO_NULL:
break;
@ -417,6 +492,8 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
{
gboolean need_reset;
/* only reset the stream time when the application did not
* specify a stream time explicitly */
GST_OBJECT_LOCK (element);
need_reset = pipeline->stream_time != GST_CLOCK_TIME_NONE;
GST_OBJECT_UNLOCK (element);
@ -467,8 +544,11 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
}
return result;
/* ERRORS */
invalid_clock:
{
/* we generate this error when the selected clock was not
* accepted by some element */
GST_ELEMENT_ERROR (pipeline, CORE, CLOCK,
(_("Selected clock cannot be used in pipeline.")),
("Pipeline cannot operate with selected clock"));
@ -480,11 +560,11 @@ invalid_clock:
/**
* gst_pipeline_get_bus:
* @pipeline: the pipeline
* @pipeline: a #GstPipeline
*
* Gets the #GstBus of this pipeline.
* Gets the #GstBus of @pipeline.
*
* Returns: a GstBus
* Returns: a #GstBus, unref after usage.
*
* MT safe.
*/
@ -496,11 +576,11 @@ gst_pipeline_get_bus (GstPipeline * pipeline)
/**
* gst_pipeline_set_new_stream_time:
* @pipeline: the pipeline
* @pipeline: a #GstPipeline
* @time: the new stream time to set
*
* Set the new stream time of the pipeline. The stream time is used to
* set the base time on the elements (see @gst_element_set_base_time())
* Set the new stream time of @pipeline to @time. The stream time is used to
* set the base time on the elements (see gst_element_set_base_time())
* in the PAUSED->PLAYING state transition.
*
* Setting @time to #GST_CLOCK_TIME_NONE will disable the pipeline's management
@ -529,14 +609,18 @@ gst_pipeline_set_new_stream_time (GstPipeline * pipeline, GstClockTime time)
/**
* gst_pipeline_get_last_stream_time:
* @pipeline: the pipeline
* @pipeline: a #GstPipeline
*
* Gets the last stream time of the pipeline. If the pipeline is PLAYING,
* the returned time is the stream time used to configure the elements
* in the PAUSED->PLAYING state. If the pipeline is PAUSED, the returned
* time is the stream time when the pipeline was paused.
* Gets the last stream time of @pipeline. If the pipeline is PLAYING,
* the returned time is the stream time used to configure the element's
* base time in the PAUSED->PLAYING state. If the pipeline is PAUSED, the
* returned time is the stream time when the pipeline was paused.
*
* Returns: a GstClockTime
* This function returns #GST_CLOCK_TIME_NONE if the pipeline was
* configured to not handle the management of the element's base time
* (see gst_pipeline_set_new_stream_time()).
*
* Returns: a #GstClockTime.
*
* MT safe.
*/
@ -571,6 +655,7 @@ gst_pipeline_provide_clock_func (GstElement * element)
clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
} else {
GST_OBJECT_UNLOCK (pipeline);
/* let the parent bin select a clock */
clock =
GST_ELEMENT_CLASS (parent_class)->
provide_clock (GST_ELEMENT (pipeline));
@ -590,11 +675,11 @@ gst_pipeline_provide_clock_func (GstElement * element)
/**
* gst_pipeline_get_clock:
* @pipeline: the pipeline
* @pipeline: a #GstPipeline
*
* Gets the current clock used by the pipeline.
* Gets the current clock used by @pipeline.
*
* Returns: a GstClock
* Returns: a #GstClock, unref after usage.
*/
GstClock *
gst_pipeline_get_clock (GstPipeline * pipeline)
@ -607,13 +692,16 @@ gst_pipeline_get_clock (GstPipeline * pipeline)
/**
* gst_pipeline_use_clock:
* @pipeline: the pipeline
* @pipeline: a #GstPipeline
* @clock: the clock to use
*
* Force the pipeline to use the given clock. The pipeline will
* Force @pipeline to use the given @clock. The pipeline will
* always use the given clock even if new clock providers are added
* to this pipeline.
*
* If @clock is NULL all clocking will be disabled which will make
* the pipeline run as fast as possible.
*
* MT safe.
*/
void
@ -634,13 +722,14 @@ gst_pipeline_use_clock (GstPipeline * pipeline, GstClock * clock)
/**
* gst_pipeline_set_clock:
* @pipeline: the pipeline
* @pipeline: a #GstPipeline
* @clock: the clock to set
*
* Set the clock for the pipeline. The clock will be distributed
* Set the clock for @pipeline. The clock will be distributed
* to all the elements managed by the pipeline.
*
* Returns: TRUE if the clock could be set on the pipeline.
* Returns: TRUE if the clock could be set on the pipeline. FALSE if
* some element did not accept the clock.
*
* MT safe.
*/
@ -656,9 +745,14 @@ gst_pipeline_set_clock (GstPipeline * pipeline, GstClock * clock)
/**
* gst_pipeline_auto_clock:
* @pipeline: the pipeline
* @pipeline: a #GstPipeline
*
* Let the pipeline select a clock automatically.
* Let @pipeline select a clock automatically. This is the default
* behaviour.
*
* Use this function if you previous forced a fixed clock with
* gst_pipeline_use_clock() and want to restore the default
* pipeline clock selection algorithm.
*
* MT safe.
*/
@ -677,6 +771,59 @@ gst_pipeline_auto_clock (GstPipeline * pipeline)
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using automatic clock");
}
/**
* gst_pipeline_set_delay:
* @pipeline: a #GstPipeline
* @delay: the delay
*
* Set the expected delay needed for all elements to perform the
* PAUSED to PLAYING state change. @delay will be added to the
* base time of the elements so that they wait an additional @delay
* amount of time before starting to process buffers.
*
* This option is used for tuning purposes and should normally not be
* used.
*
* MT safe.
*
* Since: 0.10.5
*/
void
gst_pipeline_set_delay (GstPipeline * pipeline, GstClockTime delay)
{
g_return_if_fail (GST_IS_PIPELINE (pipeline));
GST_OBJECT_LOCK (pipeline);
pipeline->delay = delay;
GST_OBJECT_UNLOCK (pipeline);
}
/**
* gst_pipeline_get_delay:
* @pipeline: a #GstPipeline
*
* Get the configured delay (see gst_pipeline_set_delay()).
*
* Returns: The configured delay.
*
* MT safe.
*
* Since: 0.10.5
*/
GstClockTime
gst_pipeline_get_delay (GstPipeline * pipeline)
{
GstClockTime res;
g_return_val_if_fail (GST_IS_PIPELINE (pipeline), GST_CLOCK_TIME_NONE);
GST_OBJECT_LOCK (pipeline);
res = pipeline->delay;
GST_OBJECT_UNLOCK (pipeline);
return res;
}
/**
* gst_pipeline_set_auto_flush_bus:
* @pipeline: a #GstPipeline
@ -685,12 +832,16 @@ gst_pipeline_auto_clock (GstPipeline * pipeline)
*
* Usually, when a pipeline goes from READY to NULL state, it automatically
* flushes all pending messages on the bus, which is done for refcounting
* purposes, to break circular references. This means that applications
* that update state using (async) bus messages (e.g. do certain things when a
* pipeline goes from PAUSED to READY) might not get to see messages when the
* pipeline is shut down, because they might be flushed before they can be
* dispatched in the main thread. This behaviour can be disabled using this
* function.
* purposes, to break circular references.
*
* This means that applications that update state using (async) bus messages
* (e.g. do certain things when a pipeline goes from PAUSED to READY) might
* not get to see messages when the pipeline is shut down, because they might
* be flushed before they can be dispatched in the main thread. This behaviour
* can be disabled using this function.
*
* It is important that all messages on the bus are handled when the
* automatic flushing is disabled else memory leaks will be introduced.
*
* MT safe.
*
@ -710,6 +861,9 @@ gst_pipeline_set_auto_flush_bus (GstPipeline * pipeline, gboolean auto_flush)
* gst_pipeline_get_auto_flush_bus:
* @pipeline: a #GstPipeline
*
* Check if @pipeline will automatically flush messages when going to
* the NULL state.
*
* Returns: whether the pipeline will automatically flush its bus when
* going from READY to NULL state or not.
*

View file

@ -72,6 +72,7 @@ struct _GstPipeline {
/*< private >*/
GstPipelinePrivate *priv;
gpointer _gst_reserved[GST_PADDING-1];
};
@ -95,6 +96,9 @@ gboolean gst_pipeline_set_clock (GstPipeline *pipeline, GstClock
GstClock* gst_pipeline_get_clock (GstPipeline *pipeline);
void gst_pipeline_auto_clock (GstPipeline *pipeline);
void gst_pipeline_set_delay (GstPipeline *pipeline, GstClockTime delay);
GstClockTime gst_pipeline_get_delay (GstPipeline *pipeline);
void gst_pipeline_set_auto_flush_bus (GstPipeline *pipeline, gboolean auto_flush);
gboolean gst_pipeline_get_auto_flush_bus (GstPipeline *pipeline);

View file

@ -64,7 +64,7 @@
* If the cur_type was different from GST_SEEK_TYPE_NONE, playback continues from
* the last_pos position, possibly with updated flags or rate.
*
* For elements that want to us #GstSegment to track the playback region, use
* For elements that want to use #GstSegment to track the playback region, use
* gst_segment_set_newsegment() to update the segment fields with the information from
* the newsegment event. The gst_segment_clip() method can be used to check and clip
* the media data to the segment boundaries.
@ -77,7 +77,7 @@
* gst_segment_to_stream_time() can be used to convert a timestamp and the segment
* info to stream time (which is always between 0 and the duration of the stream).
*
* Last reviewed on 2005-12-12 (0.10.0)
* Last reviewed on 2006-03-12 (0.10.5)
*/
static GstSegment *
@ -174,7 +174,7 @@ gst_segment_init (GstSegment * segment, GstFormat format)
* used by elements that perform seeking and know the total duration of the
* segment.
*
* This field should be set to allow seeking request relative to the
* This field should be set to allow seeking requests relative to the
* duration.
*/
void
@ -198,6 +198,9 @@ gst_segment_set_duration (GstSegment * segment, GstFormat format,
* @position: the position
*
* Set the last observed stop position in the segment to @position.
*
* This field should be set to allow seeking requests relative to the
* current playing position.
*/
void
gst_segment_set_last_stop (GstSegment * segment, GstFormat format,
@ -223,8 +226,7 @@ gst_segment_set_last_stop (GstSegment * segment, GstFormat format,
* @cur: the seek start value
* @stop_type: the seek method
* @stop: the seek stop value
* @update: boolean holding whether an update the current segment is
* needed.
* @update: boolean holding whether start or stop were updated.
*
* Update the segment structure with the field values of a seek event.
*
@ -450,11 +452,12 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
* @position: the position in the segment
*
* Translate @position to the total running time using the currently configured
* segment.
* and previously accumulated segments.
*
* This function is typically used by elements that need to synchronize to the
* global clock in a pipeline. The runnning time is a constantly increasing value
* starting from 0.
* starting from 0. When gst_segment_init() is called, this value will reset to
* 0.
*
* Returns: the position as the total running time.
*/
@ -491,8 +494,16 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
* Clip the given @start and @stop values to the segment boundaries given
* in @segment.
*
* Returns: TRUE if the given @start and @stop times fall partially in
* @segment, FALSE if the values are completely outside of the segment.
* If the function returns FALSE, @start and @stop are known to fall
* outside of @segment and @clip_start and @clip_stop are not updated.
*
* When the function returns TRUE, @clip_start and @clip_stop will be
* updated. If @clip_start or @clip_stop are different from @start or @stop
* respectively, the region fell partially in the segment.
*
* Returns: TRUE if the given @start and @stop times fall partially or
* completely in @segment, FALSE if the values are completely outside
* of the segment.
*/
gboolean
gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,