docs/design/part-states.txt: Some more docs.
authorWim Taymans <wim.taymans@gmail.com>
Tue, 11 Oct 2005 11:08:52 +0000 (11:08 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Tue, 11 Oct 2005 11:08:52 +0000 (11:08 +0000)
Original commit message from CVS:
* docs/design/part-states.txt:
Some more docs.

* gst/gstbin.c: (gst_bin_set_clock_func), (gst_bin_recalc_state),
(gst_bin_change_state_func), (bin_bus_handler):
Doc updates. Don't distribute the same clock over and over again.

* gst/gstclock.c:
* gst/gstclock.h:
Doc updates.

* gst/gstpad.c: (gst_flow_get_name), (gst_flow_to_quark),
(gst_pad_get_type), (gst_pad_push), (gst_pad_push_event),
(gst_pad_send_event):
* gst/gstpad.h:
Make probe emission threadsafe again.
Register quarks and move _get_name() from utils.
Doc updates.

* gst/gstpipeline.c: (gst_pipeline_class_init),
(gst_pipeline_change_state), (gst_pipeline_provide_clock_func):
Only redistribute the clock of it changed.

* gst/gstsystemclock.h:
Doc updates.

* gst/gstutils.c:
* gst/gstutils.h:
Moved the _flow_get_name() to GstPad.

12 files changed:
ChangeLog
docs/design/part-states.txt
gst/gstbin.c
gst/gstbin.h
gst/gstclock.c
gst/gstclock.h
gst/gstpad.c
gst/gstpad.h
gst/gstpipeline.c
gst/gstsystemclock.h
gst/gstutils.c
gst/gstutils.h

index 192e504..0e9d3b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2005-10-11  Wim Taymans  <wim@fluendo.com>
+
+       * docs/design/part-states.txt:
+       Some more docs.
+
+       * gst/gstbin.c: (gst_bin_set_clock_func), (gst_bin_recalc_state),
+       (gst_bin_change_state_func), (bin_bus_handler):
+       Doc updates. Don't distribute the same clock over and over again.
+
+       * gst/gstclock.c:
+       * gst/gstclock.h:
+       Doc updates.
+
+       * gst/gstpad.c: (gst_flow_get_name), (gst_flow_to_quark),
+       (gst_pad_get_type), (gst_pad_push), (gst_pad_push_event),
+       (gst_pad_send_event):
+       * gst/gstpad.h:
+       Make probe emission threadsafe again.
+       Register quarks and move _get_name() from utils.
+       Doc updates.
+
+       * gst/gstpipeline.c: (gst_pipeline_class_init),
+       (gst_pipeline_change_state), (gst_pipeline_provide_clock_func):
+       Only redistribute the clock of it changed.
+
+       * gst/gstsystemclock.h:
+       Doc updates. 
+
+       * gst/gstutils.c:
+       * gst/gstutils.h:
+       Moved the _flow_get_name() to GstPad.
+
 2005-10-11  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * check/gst-libs/gdp.c: (GST_START_TEST):
index a3bc711..b1d6b63 100644 (file)
@@ -286,6 +286,55 @@ Bin:
 Locking overview (element)
 --------------------------
 
+* Element commiting SUCCESS
+
+ - STATE_LOCK is taken in set_state
+ - change state is called if SUCCESS, commit state is called
+ - commit state calls change_state to next state change.
+ - if final state is reached, stack unwinds and result is returned to 
+   set_state and caller.
+
+
+ set_state(element)       change_state (element)   commit_state
+
+      |                         |                       |
+      |                         |                       |
+  STATE_LOCK                    |                       |
+      |                         |                       |
+      |------------------------>|                       | 
+      |                         |                       | 
+      |                         |                       | 
+      |                         | (do state change)     |
+      |                         |                       |
+      |                         |                       |
+      |                         | if SUCCESS            |
+      |                         |---------------------->|
+      |                         |                       | post message
+      |                         |                       |
+      |                         |<----------------------| if (!final) change_state (next)
+      |                         |                       | else SIGNAL
+      |                         |                       |
+      |                         |                       |
+      |                         |                       |
+      |<------------------------|                       |
+      |     SUCCESS               
+      | 
+  STATE_UNLOCK
+      |      
+    SUCCESS   
+           
+
+
+* Element commiting ASYNC
+
+ - STATE_LOCK is taken in set_state
+ - change state is called and returns ASYNC
+ - ASYNC returned to the caller.
+ - element takes STATE_LOCK in streaming thread.
+ - element calls commit_state in streaming thread.
+ - commit state calls change_state to next state change.
+
+
  set_state(element)       change_state (element)     stream_thread      commit_state (element)
 
       |                         |                          |                  |
@@ -298,19 +347,21 @@ Locking overview (element)
       |                         | (start_task)             |                  |
       |                         |                          |                  |
       |                         |                     STREAM_LOCK             |
-      |                         |                          |                  |
+      |                         |                          |...               |
       |<------------------------|                          |                  |
-      |     ASYNC                                          |                  |
+      |     ASYNC                                     STREAM_UNLOCK           |
   STATE_UNLOCK                                             |                  |       
       |                .....sync........               STATE_LOCK             |               
     ASYNC                                                  |----------------->|
                                                            |                  |
-                                                           |                  |---> post_message(ASYNC)
+                                                           |                  |---> post_message()
                                                            |                  |---> if (!final) change_state (next)
                                                            |                  |     else SIGNAL
                                                            |<-----------------|
                                                        STATE_UNLOCK
                                                            |
+                                                      STREAM_LOCK
+                                                           | ...
                                                       STREAM_UNLOCK
                                      
        
index aa10368..1f9bfa6 100644 (file)
@@ -51,7 +51,7 @@
  * bin. Likewise the "element_removed" signal is fired whenever an element is
  * removed from the bin.
  *
- * gst_bin_unref() is used to destroy the bin. 
+ * gst_object_unref() is used to destroy the bin. 
  */
 
 #include "gst_private.h"
 
 GST_DEBUG_CATEGORY_STATIC (bin_debug);
 #define GST_CAT_DEFAULT bin_debug
-#define GST_LOG_BIN_CONTENTS(bin, text) GST_LOG_OBJECT ((bin), \
-       text ": %d elements: %u PLAYING, %u PAUSED, %u READY, %u NULL, own state: %s", \
-       (bin)->numchildren, (guint) (bin)->child_states[3], \
-       (guint) (bin)->child_states[2], (bin)->child_states[1], \
-       (bin)->child_states[0], gst_element_state_get_name (GST_STATE (bin)))
 
 static GstElementDetails gst_bin_details = GST_ELEMENT_DETAILS ("Generic bin",
     "Generic/Bin",
@@ -351,10 +346,12 @@ gst_bin_set_clock_func (GstElement * element, GstClock * clock)
   bin = GST_BIN (element);
 
   GST_LOCK (bin);
-  for (children = bin->children; children; children = g_list_next (children)) {
-    GstElement *child = GST_ELEMENT (children->data);
+  if (element->clock != clock) {
+    for (children = bin->children; children; children = g_list_next (children)) {
+      GstElement *child = GST_ELEMENT (children->data);
 
-    gst_element_set_clock (child, clock);
+      gst_element_set_clock (child, clock);
+    }
   }
   GST_UNLOCK (bin);
 }
index bc95399..e90066f 100644 (file)
@@ -94,6 +94,7 @@ struct _GstBin {
 
   gboolean      polling;
   gboolean       state_dirty;
+
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
 };
index a25c9c9..695b6c9 100644 (file)
@@ -31,8 +31,8 @@
  *
  * The clock time is always measured in nanoseconds and always increases. The
  * pipeline uses the clock to calculate the stream time.
- * Usually all renderers sync to the global clock using the buffer timestamps
- * and the segment events.
+ * Usually all renderers sync to the global clock using the buffer timestamps,
+ * the newsegment events and the element's base time.
  *
  * The time of the clock in itself is not very usefull for an application.
  */
index cf5848d..4d8fb08 100644 (file)
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wtay@chello.be>
+ *                    2005 Wim Taymans <wim@fluendo.com>
  *
  * gstclock.h: Header for clock subsystem
  *
index 3475bc7..ca70a7e 100644 (file)
 #include "gstvalue.h"
 
 GST_DEBUG_CATEGORY_STATIC (debug_dataflow);
-#define DEBUG_DATA(obj,data,notice) G_STMT_START{\
-  if (!data) { \
-    GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "NULL data value"); \
-  } else if (GST_IS_EVENT (data)) { \
-    GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "%s event %p (type %d, refcount %d)", notice, data, \
-       GST_EVENT_TYPE (data), GST_DATA_REFCOUNT_VALUE (data)); \
-  } else { \
-    GST_CAT_LOG_OBJECT (debug_dataflow, obj, "%s buffer %p (size %u, refcount %d)", notice, data, \
-       GST_BUFFER_SIZE (data), GST_BUFFER_REFCOUNT_VALUE (data)); \
-  } \
-}G_STMT_END
 #define GST_CAT_DEFAULT GST_CAT_PADS
 
 /* Pad signals and args */
@@ -129,9 +118,71 @@ static xmlNodePtr gst_pad_save_thyself (GstObject * object, xmlNodePtr parent);
 static GstObjectClass *parent_class = NULL;
 static guint gst_pad_signals[LAST_SIGNAL] = { 0 };
 
+/* quarks for probe signals */
 static GQuark buffer_quark;
 static GQuark event_quark;
 
+typedef struct
+{
+  gint ret;
+  gchar *name;
+  GQuark quark;
+} GstFlowQuarks;
+
+static GstFlowQuarks flow_quarks[] = {
+  {GST_FLOW_RESEND, "resend", 0},
+  {GST_FLOW_OK, "ok", 0},
+  {GST_FLOW_NOT_LINKED, "not-linked", 0},
+  {GST_FLOW_WRONG_STATE, "wrong-state", 0},
+  {GST_FLOW_UNEXPECTED, "unexpected", 0},
+  {GST_FLOW_NOT_NEGOTIATED, "not-negotiated", 0},
+  {GST_FLOW_ERROR, "error", 0},
+  {GST_FLOW_NOT_SUPPORTED, "not-supported", 0},
+
+  {0, NULL, 0}
+};
+
+/**
+ * gst_flow_get_name:
+ * @ret: a #GstFlowReturn to get the name of.
+ *
+ * Gets a string representing the given flow return.
+ *
+ * Returns: a string with the name of the flow return.
+ */
+G_CONST_RETURN gchar *
+gst_flow_get_name (GstFlowReturn ret)
+{
+  gint i;
+
+  for (i = 0; flow_quarks[i].name; i++) {
+    if (ret == flow_quarks[i].ret)
+      return flow_quarks[i].name;
+  }
+  return "unknown";
+}
+
+/**
+ * gst_flow_to_quark:
+ * @ret: a #GstFlowReturn to get the quark of.
+ *
+ * Get the unique quark for the given GstFlowReturn.
+ *
+ * Returns: the quark associated with the flow return or 0 if an
+ * invalid return was specified.
+ */
+GQuark
+gst_flow_to_quark (GstFlowReturn ret)
+{
+  gint i;
+
+  for (i = 0; flow_quarks[i].name; i++) {
+    if (ret == flow_quarks[i].ret)
+      return flow_quarks[i].quark;
+  }
+  return 0;
+}
+
 GType
 gst_pad_get_type (void)
 {
@@ -143,6 +194,7 @@ gst_pad_get_type (void)
       0,
       (GInstanceInitFunc) gst_pad_init, NULL
     };
+    gint i;
 
     _gst_pad_type = g_type_register_static (GST_TYPE_OBJECT, "GstPad",
         &pad_info, 0);
@@ -150,6 +202,10 @@ gst_pad_get_type (void)
     buffer_quark = g_quark_from_static_string ("buffer");
     event_quark = g_quark_from_static_string ("event");
 
+    for (i = 0; flow_quarks[i].name; i++) {
+      flow_quarks[i].quark = g_quark_from_static_string (flow_quarks[i].name);
+    }
+
     GST_DEBUG_CATEGORY_INIT (debug_dataflow, "GST_DATAFLOW",
         GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "dataflow inside pads");
   }
@@ -3089,8 +3145,6 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
 {
   GstPad *peer;
   GstFlowReturn ret;
-  gboolean emit_signal;
-  gboolean signal_ret = TRUE;
 
   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC, GST_FLOW_ERROR);
@@ -3106,23 +3160,18 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
 
   /* we emit signals on the pad arg, the peer will have a chance to
    * emit in the _chain() function */
-  emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
-  GST_UNLOCK (pad);
+  if (G_UNLIKELY (GST_PAD_DO_BUFFER_SIGNALS (pad) > 0)) {
+    /* unlock before emitting */
+    GST_UNLOCK (pad);
 
-  if (G_UNLIKELY (emit_signal)) {
-    signal_ret = gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (buffer));
-  }
+    /* if the signal handler returned FALSE, it means we should just drop the
+     * buffer */
+    if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (buffer)))
+      goto dropped;
 
-  /* if the signal handler returned FALSE, it means we should just drop the
-   * buffer */
-  if (signal_ret == FALSE) {
-    gst_buffer_unref (buffer);
-    GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
-    return GST_FLOW_OK;
+    GST_LOCK (pad);
   }
 
-  GST_LOCK (pad);
-
   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto not_linked;
   gst_object_ref (peer);
@@ -3135,6 +3184,12 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
   return ret;
 
   /* ERROR recovery here */
+dropped:
+  {
+    gst_buffer_unref (buffer);
+    GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
+    return GST_FLOW_OK;
+  }
 not_linked:
   {
     gst_buffer_unref (buffer);
@@ -3382,25 +3437,20 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
 {
   GstPad *peerpad;
   gboolean result;
-  gboolean emit_signal;
-  gboolean signal_ret = TRUE;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
 
-  emit_signal = GST_PAD_DO_EVENT_SIGNALS (pad) > 0;
+  GST_LOCK (pad);
+  if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
+    GST_UNLOCK (pad);
 
-  if (G_UNLIKELY (emit_signal)) {
-    signal_ret = gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (event));
-  }
+    if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (event)))
+      goto dropping;
 
-  if (signal_ret == FALSE) {
-    GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return");
-    gst_event_unref (event);
-    return FALSE;
+    GST_LOCK (pad);
   }
-
-  GST_LOCK (pad);
   peerpad = GST_PAD_PEER (pad);
   if (peerpad == NULL)
     goto not_linked;
@@ -3415,6 +3465,12 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
   return result;
 
   /* ERROR handling */
+dropping:
+  {
+    GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return");
+    gst_event_unref (event);
+    return FALSE;
+  }
 not_linked:
   {
     gst_event_unref (event);
@@ -3444,7 +3500,6 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
   g_return_val_if_fail (event != NULL, FALSE);
 
   GST_LOCK (pad);
-
   if (GST_PAD_IS_SINK (pad) && !GST_EVENT_IS_DOWNSTREAM (event))
     goto wrong_direction;
   if (GST_PAD_IS_SRC (pad) && !GST_EVENT_IS_UPSTREAM (event))
@@ -3482,8 +3537,6 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
     goto no_function;
 
   emit_signal = GST_PAD_DO_EVENT_SIGNALS (pad) > 0;
-
-  gst_object_ref (pad);
   GST_UNLOCK (pad);
 
   if (G_UNLIKELY (emit_signal)) {
@@ -3493,8 +3546,6 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
 
   result = eventfunc (GST_PAD_CAST (pad), event);
 
-  gst_object_unref (pad);
-
   return result;
 
   /* ERROR handling */
@@ -3524,7 +3575,6 @@ flushing:
 dropping:
   {
     GST_DEBUG ("Dropping event after FALSE probe return");
-    gst_object_unref (pad);
     gst_event_unref (event);
     return FALSE;
   }
index 84444e3..31edaca 100644 (file)
@@ -76,7 +76,7 @@ typedef enum {
  * @ret: the #GstPadLinkReturn value
  *
  * Macro to test if the given #GstPadLinkReturn value indicates a failed
- * negotiation step (REFUSED/DELAYED).
+ * link step.
  */
 #define GST_PAD_LINK_FAILED(ret) ((ret) < GST_PAD_LINK_OK)
 
@@ -85,25 +85,47 @@ typedef enum {
  * @ret: the #GstPadLinkReturn value
  *
  * Macro to test if the given #GstPadLinkReturn value indicates a successfull
- * negotiation step (OK/DONE).
+ * link step.
  */
 #define GST_PAD_LINK_SUCCESSFUL(ret) ((ret) >= GST_PAD_LINK_OK)
 
+/**
+ * GstFlowReturn:
+ * GST_FLOW_RESEND:             Resend buffer, possibly with new caps.
+ * GST_FLOW_OK:                         Data passing was ok.
+ * GST_FLOW_NOT_LINKED:         Pad is not linked.
+ * GST_FLOW_WRONG_STATE:        Pad is in wrong state.
+ * GST_FLOW_UNEXPECTED:         Did not expect anything, like after EOS.
+ * GST_FLOW_NOT_NEGOTIATED:     Pad is not negotiated.
+ * GST_FLOW_ERROR:              Some (fatal) error occured.
+ *
+ * The result of passing data to a linked pad.
+ */
 typedef enum {
-  GST_FLOW_RESEND        =  1,         /* resend buffer, possibly with new caps */
-  GST_FLOW_OK            =  0,         /* data passing was ok */
+  GST_FLOW_RESEND        =  1,
+  GST_FLOW_OK            =  0,
   /* expected failures */
-  GST_FLOW_NOT_LINKED     = -1,                /* pad is not linked */
-  GST_FLOW_WRONG_STATE    = -2,                /* pad is in wrong state */
+  GST_FLOW_NOT_LINKED     = -1,
+  GST_FLOW_WRONG_STATE    = -2,
   /* error cases */
-  GST_FLOW_UNEXPECTED     = -3,                /* did not expect anything, like after EOS */
-  GST_FLOW_NOT_NEGOTIATED = -4,                /* pad is not negotiated */
-  GST_FLOW_ERROR         = -5,         /* some (fatal) error occured */
-  GST_FLOW_NOT_SUPPORTED  = -6         /* function not supported */
+  GST_FLOW_UNEXPECTED     = -3,
+  GST_FLOW_NOT_NEGOTIATED = -4,
+  GST_FLOW_ERROR         = -5,
+  GST_FLOW_NOT_SUPPORTED  = -6
 } GstFlowReturn;
 
+/**
+ * GST_FLOW_IS_FATAL:
+ * @ret: a #GstFlowReturn value
+ *
+ * Macro to test if the given #GstFlowReturn value indicates a fatal
+ * error.
+ */
 #define GST_FLOW_IS_FATAL(ret) ((ret) <= GST_FLOW_UNEXPECTED)
 
+G_CONST_RETURN gchar*  gst_flow_get_name       (GstFlowReturn ret);
+GQuark                 gst_flow_to_quark       (GstFlowReturn ret);
+
 typedef enum {
   GST_ACTIVATE_NONE,
   GST_ACTIVATE_PUSH,
index 2e8fc90..a001931 100644 (file)
@@ -324,10 +324,10 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
             GST_TIME_ARGS (start_time), GST_TIME_ARGS (element->base_time));
         GST_UNLOCK (element);
 
-        /* now distribute the clock */
-        gst_element_set_clock (element, clock);
-
         if (new_clock) {
+          /* now distribute the clock */
+          gst_element_set_clock (element, clock);
+
           /* if we selected a new clock, let the app know about it */
           gst_element_post_message (element,
               gst_message_new_new_clock (GST_OBJECT_CAST (element), clock));
index 4e02c1f..892b3f4 100644 (file)
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wtay@chello.be>
+ *                    2005 Wim Taymans <wim@fluendo.com>
  *
  * gstsystemclock.h: A clock implementation based on system time
  *
index 76d71ae..7c4fa17 100644 (file)
@@ -1784,41 +1784,6 @@ gst_pad_get_parent_element (GstPad * pad)
 }
 
 /**
- * gst_flow_get_name:
- * @ret: a #GstFlowReturn to get the name of.
- *
- * Gets a string representing the given flow return.
- *
- * Returns: a string with the name of the flow return.
- */
-G_CONST_RETURN gchar *
-gst_flow_get_name (GstFlowReturn ret)
-{
-  switch (ret) {
-    case GST_FLOW_RESEND:
-      return "RESEND_BUFFER";
-    case GST_FLOW_OK:
-      return "OK";
-      /* expected failures */
-    case GST_FLOW_NOT_LINKED:
-      return "NOT_LINKED";
-    case GST_FLOW_WRONG_STATE:
-      return "WRONG_STATE";
-      /* error cases */
-    case GST_FLOW_UNEXPECTED:
-      return "UNEXPECTED";
-    case GST_FLOW_NOT_NEGOTIATED:
-      return "NOT_NEGOTIATED";
-    case GST_FLOW_ERROR:
-      return "ERROR";
-    case GST_FLOW_NOT_SUPPORTED:
-      return "NOT_SUPPORTED";
-    default:
-      return "UNKNOWN error";
-  }
-}
-
-/**
  * gst_object_default_error:
  * @source: the #GstObject that initiated the error.
  * @error: the GError.
index 1a300c3..00194f2 100644 (file)
@@ -529,10 +529,6 @@ gboolean           gst_pad_proxy_setcaps           (GstPad * pad, GstCaps * caps);
 
 GstElement*            gst_pad_get_parent_element      (GstPad *pad);
 
-/* flow */
-G_CONST_RETURN gchar*   gst_flow_get_name              (GstFlowReturn ret);
-
-
 /* util query functions */
 gboolean                gst_pad_query_position          (GstPad *pad, GstFormat *format,
                                                         gint64 *cur, gint64 *end);