docs/design/: Some more docs in the works.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 18 Jul 2005 08:28:48 +0000 (08:28 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 18 Jul 2005 08:28:48 +0000 (08:28 +0000)
Original commit message from CVS:
* docs/design/part-dynamic.txt:
* docs/design/part-events.txt:
* docs/design/part-seeking.txt:
Some more docs in the works.

* gst/base/gstbasetransform.c: (gst_base_transform_transform_caps),
(gst_base_transform_getcaps), (gst_base_transform_configure_caps),
(gst_base_transform_setcaps), (gst_base_transform_get_size),
(gst_base_transform_buffer_alloc), (gst_base_transform_event),
(gst_base_transform_handle_buffer),
(gst_base_transform_sink_activate_push),
(gst_base_transform_src_activate_pull),
(gst_base_transform_set_passthrough),
(gst_base_transform_is_passthrough):
Refcounting fixes.

* gst/gstbus.c: (gst_bus_source_dispatch), (gst_bus_poll):
Cleanups.

* gst/gstevent.c: (gst_event_finalize):
Set SRC to NULL.

* gst/gstutils.c: (gst_element_unlink),
(gst_pad_get_parent_element), (gst_pad_proxy_getcaps),
(gst_pad_proxy_setcaps):
* gst/gstutils.h:
Add _get_parent_element() to get a pads parent as an element.

ChangeLog
docs/design/part-dynamic.txt [new file with mode: 0644]
docs/design/part-events.txt
docs/design/part-seeking.txt [new file with mode: 0644]
gst/base/gstbasetransform.c
gst/gstbus.c
gst/gstevent.c
gst/gstutils.c
gst/gstutils.h
libs/gst/base/gstbasetransform.c

index cf9f020..2fd5dcd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
 2005-07-18  Wim Taymans  <wim@fluendo.com>
 
+       * docs/design/part-dynamic.txt:
+       * docs/design/part-events.txt:
+       * docs/design/part-seeking.txt:
+       Some more docs in the works.
+
+       * gst/base/gstbasetransform.c: (gst_base_transform_transform_caps),
+       (gst_base_transform_getcaps), (gst_base_transform_configure_caps),
+       (gst_base_transform_setcaps), (gst_base_transform_get_size),
+       (gst_base_transform_buffer_alloc), (gst_base_transform_event),
+       (gst_base_transform_handle_buffer),
+       (gst_base_transform_sink_activate_push),
+       (gst_base_transform_src_activate_pull),
+       (gst_base_transform_set_passthrough),
+       (gst_base_transform_is_passthrough):
+       Refcounting fixes.
+
+       * gst/gstbus.c: (gst_bus_source_dispatch), (gst_bus_poll):
+       Cleanups.
+
+       * gst/gstevent.c: (gst_event_finalize):
+       Set SRC to NULL.
+
+       * gst/gstutils.c: (gst_element_unlink),
+       (gst_pad_get_parent_element), (gst_pad_proxy_getcaps),
+       (gst_pad_proxy_setcaps):
+       * gst/gstutils.h:
+       Add _get_parent_element() to get a pads parent as an element.
+
+2005-07-18  Wim Taymans  <wim@fluendo.com>
+
        * check/gst/gstbin.c: (GST_START_TEST):
        Remove bogus test.
 
diff --git a/docs/design/part-dynamic.txt b/docs/design/part-dynamic.txt
new file mode 100644 (file)
index 0000000..e605fde
--- /dev/null
@@ -0,0 +1,6 @@
+Dynamic pipelines
+-----------------
+
+This document describes many use cases for dynamically constructing and
+manipulating a running or paused pipeline and the features provided by
+GStreamer.
index 5fa6d64..03f83b3 100644 (file)
@@ -163,6 +163,9 @@ The general flow of executing the seek with FLUSH is as follows:
  6) start stopped tasks and unlock the STREAM_LOCK, dataflow will continue
     now from the new position.
 
+More information about the different seek types can be found in 
+part-seeking.txt.
+
 
 SIZE
 ----
diff --git a/docs/design/part-seeking.txt b/docs/design/part-seeking.txt
new file mode 100644 (file)
index 0000000..b2c81c4
--- /dev/null
@@ -0,0 +1,70 @@
+Seeking
+-------
+
+Seeking in GStreamer means configuring the pipeline for playback of the
+media between a certain start and stop time.
+
+Different kinds of seeking exist:
+
+ - immeditate seeking with low latency (FLUSH seek)
+ - seeking without flush, playback will start from the new
+   position after all the queues are emptied with old data.
+ - segment seeking with and without FLUSH, this can be used to
+   implement seamless looping or NLE functionality.
+
+Seeking can be performed in different formats such as time, frames
+or samples.
+
+Seeking can be performed to an absolute position or relative to the
+current playback position.
+
+For seeking to work reliably, all plugins in the pipeline need to follow
+the well-defined rules in this document.
+
+Non segment seeking will make the pipeline emit EOS when the configured 
+playback range has been played.
+
+Segment seeking will not emit an EOS at the end of the range but will
+post a SEGMENT_STOP message on the bus. This message is posted by the
+earliest element in the pipeline, typically a demuxer. After receiving
+the message, the application can reconnect the pipeline or issue other
+seek events in the pipeline.
+
+
+Generating seeking events
+-------------------------
+
+
+
+
+
+The different kinds of seeking methods and their internal workings are
+described below.
+
+
+FLUSH seeking
+-------------
+
+This is the most common way of performing a seek in a playback application.
+The application issues a seek on the pipeline and the new media is immediatly
+played after the seek calls returns.
+
+
+seeking without FLUSH
+---------------------
+
+This seek type is typically performed after issuing segment seeks to finish
+the playback of the pipeline.
+
+
+segment seeking with FLUSH
+--------------------------
+
+This seek is typically performed when starting seamless looping.
+
+
+segment seeking without FLUSH
+-----------------------------
+
+This seek is typically performed when continuing seamless looping.
+
index 375e316..4384ab4 100644 (file)
@@ -231,7 +231,7 @@ gst_base_transform_getcaps (GstPad * pad)
   GstPad *otherpad;
   GstCaps *caps;
 
-  trans = GST_BASE_TRANSFORM (GST_PAD_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
 
   otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
 
@@ -272,6 +272,8 @@ gst_base_transform_getcaps (GstPad * pad)
 done:
   GST_DEBUG ("returning  %" GST_PTR_FORMAT, caps);
 
+  gst_object_unref (trans);
+
   return caps;
 }
 
@@ -306,7 +308,7 @@ gst_base_transform_setcaps (GstPad * pad, GstCaps * caps)
   GstCaps *othercaps = NULL;
   gboolean ret = TRUE;
 
-  trans = GST_BASE_TRANSFORM (GST_PAD_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
@@ -408,6 +410,8 @@ done:
   if (othercaps)
     gst_caps_unref (othercaps);
 
+  gst_object_unref (trans);
+
   return ret;
 
   /* ERRORS */
@@ -479,7 +483,7 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
   gboolean ret = FALSE;
   gboolean unlock;
 
-  trans = GST_BASE_TRANSFORM (GST_PAD_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   if (bclass->event)
@@ -505,6 +509,8 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
   if (unlock)
     GST_STREAM_UNLOCK (pad);
 
+  gst_object_unref (trans);
+
   return ret;
 }
 
@@ -670,13 +676,14 @@ gst_base_transform_sink_activate_push (GstPad * pad, gboolean active)
   GstBaseTransform *trans;
   GstBaseTransformClass *bclass;
 
-  trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   if (active) {
     if (bclass->start)
       result = bclass->start (trans);
   }
+  gst_object_unref (trans);
 
   return result;
 }
@@ -688,7 +695,7 @@ gst_base_transform_src_activate_pull (GstPad * pad, gboolean active)
   GstBaseTransform *trans;
   GstBaseTransformClass *bclass;
 
-  trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   result = gst_pad_activate_pull (trans->sinkpad, active);
@@ -697,6 +704,7 @@ gst_base_transform_src_activate_pull (GstPad * pad, gboolean active)
     if (result && bclass->start)
       result &= bclass->start (trans);
   }
+  gst_object_unref (trans);
 
   return result;
 }
index 0509a12..1b4dbee 100644 (file)
@@ -420,28 +420,30 @@ gst_bus_source_dispatch (GSource * source, GSourceFunc callback,
   GstBusSource *bsource = (GstBusSource *) source;
   GstMessage *message;
   gboolean needs_pop = TRUE;
+  GstBus *bus;
+
+  g_return_val_if_fail (bsource != NULL, FALSE);
 
-  g_return_val_if_fail (GST_IS_BUS (bsource->bus), FALSE);
+  bus = bsource->bus;
 
-  message = gst_bus_peek (bsource->bus);
+  g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
+
+  message = gst_bus_peek (bus);
 
   GST_DEBUG ("have message %p", message);
 
   g_return_val_if_fail (message != NULL, TRUE);
 
-  if (!handler) {
-    g_warning ("GstBus watch dispatched without callback\n"
-        "You must call g_source_connect().");
-    return FALSE;
-  }
+  if (!handler)
+    goto no_handler;
 
   GST_DEBUG ("calling dispatch with %p", message);
 
-  needs_pop = handler (bsource->bus, message, user_data);
+  needs_pop = handler (bus, message, user_data);
 
   GST_DEBUG ("handler returns %d", needs_pop);
   if (needs_pop) {
-    message = gst_bus_pop (bsource->bus);
+    message = gst_bus_pop (bus);
     if (message) {
       gst_message_unref (message);
     } else {
@@ -452,8 +454,14 @@ gst_bus_source_dispatch (GSource * source, GSourceFunc callback,
       GST_DEBUG ("handler requested pop but no message on the bus");
     }
   }
-
   return TRUE;
+
+no_handler:
+  {
+    g_warning ("GstBus watch dispatched without callback\n"
+        "You must call g_source_connect().");
+    return FALSE;
+  }
 }
 
 static void
@@ -596,6 +604,8 @@ poll_timeout (GstBusPollData * poll_data)
  * specify a maximum time to poll with the @timeout parameter. If @timeout is
  * negative, this function will block indefinitely.
  *
+ * This function will enter the default mainloop while polling.
+ *
  * Returns: The type of the message that was received, or GST_MESSAGE_UNKNOWN if
  * the poll timed out. The message will remain in the bus queue; you will need
  * to gst_bus_pop() it off before entering gst_bus_poll() again.
@@ -603,28 +613,29 @@ poll_timeout (GstBusPollData * poll_data)
 GstMessageType
 gst_bus_poll (GstBus * bus, GstMessageType events, GstClockTimeDiff timeout)
 {
-  GstBusPollData *poll_data;
+  GstBusPollData poll_data;
   GstMessageType ret;
   guint id;
 
-  poll_data = g_new0 (GstBusPollData, 1);
   if (timeout >= 0)
-    poll_data->timeout_id = g_timeout_add (timeout / GST_MSECOND,
-        (GSourceFunc) poll_timeout, poll_data);
-  poll_data->loop = g_main_loop_new (NULL, FALSE);
-  poll_data->events = events;
-  poll_data->revent = GST_MESSAGE_UNKNOWN;
-
-  id = gst_bus_add_watch (bus, (GstBusHandler) poll_handler, poll_data);
-  g_main_loop_run (poll_data->loop);
+    poll_data.timeout_id = g_timeout_add (timeout / GST_MSECOND,
+        (GSourceFunc) poll_timeout, &poll_data);
+  else
+    poll_data.timeout_id = 0;
+
+  poll_data.loop = g_main_loop_new (NULL, FALSE);
+  poll_data.events = events;
+  poll_data.revent = GST_MESSAGE_UNKNOWN;
+
+  id = gst_bus_add_watch (bus, (GstBusHandler) poll_handler, &poll_data);
+  g_main_loop_run (poll_data.loop);
   g_source_remove (id);
 
-  ret = poll_data->revent;
+  ret = poll_data.revent;
 
-  if (poll_data->timeout_id)
-    g_source_remove (poll_data->timeout_id);
-  g_main_loop_unref (poll_data->loop);
-  g_free (poll_data);
+  if (poll_data.timeout_id)
+    g_source_remove (poll_data.timeout_id);
+  g_main_loop_unref (poll_data.loop);
 
   return ret;
 }
index 2020593..8aec188 100644 (file)
@@ -99,6 +99,7 @@ gst_event_finalize (GstEvent * event)
 
   if (GST_EVENT_SRC (event)) {
     gst_object_unref (GST_EVENT_SRC (event));
+    GST_EVENT_SRC (event) = NULL;
   }
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_TAG:
index 15023f5..2ef1b2a 100644 (file)
@@ -1443,7 +1443,9 @@ gst_element_unlink (GstElement * src, GstElement * dest)
           /* see if the pad is connected and is really a pad
            * of dest */
           if (peerpad) {
-            GstElement *peerelem = gst_pad_get_parent (peerpad);
+            GstElement *peerelem;
+
+            peerelem = gst_pad_get_parent_element (peerpad);
 
             if (peerelem == dest) {
               gst_pad_unlink (pad, peerpad);
@@ -1642,6 +1644,34 @@ done:
 }
 
 /**
+ * gst_pad_get_parent_element:
+ * @pad: a pad
+ *
+ * Gets the parent of @pad, cast to a #GstElement. If a @pad has no parent or
+ * its parent is not an element, return NULL.
+ *
+ * Returns: The parent of the pad. The caller has a reference on the parent, so
+ * unref when you're finished with it.
+ *
+ * MT safe.
+ */
+GstElement *
+gst_pad_get_parent_element (GstPad * pad)
+{
+  GstObject *p;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+
+  p = gst_object_get_parent (GST_OBJECT_CAST (pad));
+
+  if (p && !GST_IS_ELEMENT (p)) {
+    gst_object_unref (p);
+    p = NULL;
+  }
+  return GST_ELEMENT_CAST (p);
+}
+
+/**
  * gst_object_default_error:
  * @object: a #GObject that signalled the error.
  * @orig: the #GstObject that initiated the error.
@@ -1955,7 +1985,7 @@ gst_pad_proxy_getcaps (GstPad * pad)
 
   GST_DEBUG ("proxying getcaps for %s:%s", GST_DEBUG_PAD_NAME (pad));
 
-  element = gst_pad_get_parent (pad);
+  element = gst_pad_get_parent_element (pad);
   if (element == NULL)
     return NULL;
 
@@ -2027,7 +2057,7 @@ gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps)
 
   GST_DEBUG ("proxying pad link for %s:%s", GST_DEBUG_PAD_NAME (pad));
 
-  element = gst_pad_get_parent (pad);
+  element = gst_pad_get_parent_element (pad);
 
   iter = gst_element_iterate_pads (element);
 
index a5f78a3..048753c 100644 (file)
@@ -278,6 +278,8 @@ GstCaps*            gst_pad_get_fixed_caps_func     (GstPad *pad);
 GstCaps*               gst_pad_proxy_getcaps           (GstPad * pad);
 gboolean               gst_pad_proxy_setcaps           (GstPad * pad, GstCaps * caps);
 
+GstElement*            gst_pad_get_parent_element      (GstPad *pad);
+
 /* util query functions */
 gboolean                gst_pad_query_position          (GstPad *pad, GstFormat *format,
                                                         gint64 *cur, gint64 *end);
index 375e316..4384ab4 100644 (file)
@@ -231,7 +231,7 @@ gst_base_transform_getcaps (GstPad * pad)
   GstPad *otherpad;
   GstCaps *caps;
 
-  trans = GST_BASE_TRANSFORM (GST_PAD_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
 
   otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
 
@@ -272,6 +272,8 @@ gst_base_transform_getcaps (GstPad * pad)
 done:
   GST_DEBUG ("returning  %" GST_PTR_FORMAT, caps);
 
+  gst_object_unref (trans);
+
   return caps;
 }
 
@@ -306,7 +308,7 @@ gst_base_transform_setcaps (GstPad * pad, GstCaps * caps)
   GstCaps *othercaps = NULL;
   gboolean ret = TRUE;
 
-  trans = GST_BASE_TRANSFORM (GST_PAD_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
@@ -408,6 +410,8 @@ done:
   if (othercaps)
     gst_caps_unref (othercaps);
 
+  gst_object_unref (trans);
+
   return ret;
 
   /* ERRORS */
@@ -479,7 +483,7 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
   gboolean ret = FALSE;
   gboolean unlock;
 
-  trans = GST_BASE_TRANSFORM (GST_PAD_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   if (bclass->event)
@@ -505,6 +509,8 @@ gst_base_transform_event (GstPad * pad, GstEvent * event)
   if (unlock)
     GST_STREAM_UNLOCK (pad);
 
+  gst_object_unref (trans);
+
   return ret;
 }
 
@@ -670,13 +676,14 @@ gst_base_transform_sink_activate_push (GstPad * pad, gboolean active)
   GstBaseTransform *trans;
   GstBaseTransformClass *bclass;
 
-  trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   if (active) {
     if (bclass->start)
       result = bclass->start (trans);
   }
+  gst_object_unref (trans);
 
   return result;
 }
@@ -688,7 +695,7 @@ gst_base_transform_src_activate_pull (GstPad * pad, gboolean active)
   GstBaseTransform *trans;
   GstBaseTransformClass *bclass;
 
-  trans = GST_BASE_TRANSFORM (GST_OBJECT_PARENT (pad));
+  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   result = gst_pad_activate_pull (trans->sinkpad, active);
@@ -697,6 +704,7 @@ gst_base_transform_src_activate_pull (GstPad * pad, gboolean active)
     if (result && bclass->start)
       result &= bclass->start (trans);
   }
+  gst_object_unref (trans);
 
   return result;
 }