Documentation updates.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 13 Mar 2006 11:04:38 +0000 (11:04 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 13 Mar 2006 11:04:38 +0000 (11:04 +0000)
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.

ChangeLog
docs/gst/gstreamer-sections.txt
gst/gstbin.c
gst/gstbin.h
gst/gstbus.c
gst/gstbus.h
gst/gstclock.c
gst/gstelement.c
gst/gstpipeline.c
gst/gstpipeline.h
gst/gstsegment.c

index b16dfe3f6f2f3fc218c166f864ba034b98c6ab53..6ef9122ee33e233dda2499968657f3b1a5596c61 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
index 24b6b9eec0e7bbe4cf5680391b5caba794c2b09c..c91c4a93059101860947bf560cdf93fe77815180 100644 (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_get_clock
+
 gst_pipeline_use_clock
+gst_pipeline_auto_clock
+
+gst_pipeline_set_new_stream_time
+gst_pipeline_get_last_stream_time
 
-gst_pipeline_get_auto_flush_bus
 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
index 995ff430a2ddd0ee0aa85a612f15e015f39fb644..bc7af2e7a36208cb4eee0ad57de5b2e241625443 100644 (file)
  *     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>
  * </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)
 {
index 215ec9f5c1cf10633cb68d5e516d4b7a2a4e162f..939a6bae6c86ffb739f3dc1c6a951eef25e8c646 100644 (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
index b9ee671e7e67eb7bf911a8ef4814ea8ee9e8f353..0e7f7a08e237fbc4111d563eee7e86f29719691f 100644 (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
index d8e336964d78547e2acb5b448852135d6384fef6..3aa599128b5709801450bcd150a87405e1698114 100644 (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);
index 931b24b4680398a54caf32b3d99e677192ad3e12..5fccbdb74c5136f97e56b7c18f2488819912118c 100644 (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
  * 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.
index 900030279babbe518a90757afd2ead33b3cdccc0..355af897154ea29ac6b0abbb35de839dde871b74 100644 (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"
index 96b74a30b79b1f05fc22b3c6c0d25e7758b5149e..5d792350b9dd33d2be0fcec690e6c58a1824f375 100644 (file)
  * 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.
  *
index 6fcbf38dcba50a4f49e17e4f1fa1fb84790f3c65..5355a04aa3422735a077105191b3357e09cc8d91 100644 (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);
 
index e2f987d6e1efe750e93899cfdb0d05c38111b833..2cb761d8c4b5c973a15f6bd821fd7a136dd296fd 100644 (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,