gst/: Move latency query from GstPipeline to GstBin so that we can also use it when...
authorWim Taymans <wim.taymans@gmail.com>
Thu, 13 Sep 2007 21:27:33 +0000 (21:27 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 13 Sep 2007 21:27:33 +0000 (21:27 +0000)
Original commit message from CVS:
* gst/gstbin.c: (gst_bin_class_init), (clear_queue),
(do_bin_latency), (gst_bin_change_state_func):
* gst/gstpipeline.c: (gst_pipeline_change_state):
Move latency query from GstPipeline to GstBin so that we can also
use it when async-handling is enabled on bins.

ChangeLog
gst/gstbin.c
gst/gstpipeline.c

index 07f36d6..6631ee5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2007-09-13  Wim Taymans  <wim.taymans@gmail.com>
 
+       * gst/gstbin.c: (gst_bin_class_init), (clear_queue),
+       (do_bin_latency), (gst_bin_change_state_func):
+       * gst/gstpipeline.c: (gst_pipeline_change_state):
+       Move latency query from GstPipeline to GstBin so that we can also
+       use it when async-handling is enabled on bins.
+
+2007-09-13  Wim Taymans  <wim.taymans@gmail.com>
+
        * libs/gst/base/gstbasesrc.c: (gst_base_src_query_latency),
        (gst_base_src_do_sync), (gst_base_src_change_state):
        Update docs.
index 0909990..c7ba5b7 100644 (file)
@@ -395,7 +395,7 @@ gst_bin_class_init (GstBinClass * klass)
    *
    * If set to #TRUE, the bin will handle asynchronous state changes.
    * This should be used only if the bin subclass is modifying the state
-   * of its childs on its own.
+   * of its children on its own.
    *
    * Since: 0.10.13
    */
@@ -1603,7 +1603,6 @@ clear_queue (GQueue * queue)
 
   while ((p = g_queue_pop_head (queue)))
     gst_object_unref (p);
-
 }
 
 /* set all degrees to 0. Elements marked as a sink are
@@ -2017,6 +2016,58 @@ failed:
     return FALSE;
   }
 }
+
+static gboolean
+do_bin_latency (GstElement * element)
+{
+  GstQuery *query;
+  GstClockTime min_latency, max_latency;
+  gboolean res;
+
+  GST_DEBUG_OBJECT (element, "querying latency");
+
+  query = gst_query_new_latency ();
+  if ((res = gst_element_query (element, query))) {
+    gboolean live;
+
+    gst_query_parse_latency (query, &live, &min_latency, &max_latency);
+
+    GST_DEBUG_OBJECT (element,
+        "got min latency %" GST_TIME_FORMAT ", max latency %"
+        GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
+        GST_TIME_ARGS (max_latency), live);
+
+    if (max_latency < min_latency) {
+      /* this is an impossible situation, some parts of the pipeline might not
+       * work correctly. We post a warning for now. */
+      GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
+          ("Impossible to configure latency: max %" GST_TIME_FORMAT " < min %"
+              GST_TIME_FORMAT ". Add queues or other buffering elements.",
+              GST_TIME_ARGS (max_latency), GST_TIME_ARGS (min_latency)));
+    }
+
+    /* configure latency on elements */
+    res = gst_element_send_event (element, gst_event_new_latency (min_latency));
+    if (res) {
+      GST_INFO_OBJECT (element, "configured latency of %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (min_latency));
+    } else {
+      GST_WARNING_OBJECT (element,
+          "failed to configure latency of %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (min_latency));
+      GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
+          ("Failed to configure latency of %" GST_TIME_FORMAT,
+              GST_TIME_ARGS (min_latency)));
+    }
+  } else {
+    /* this is not a real problem, we just don't configure any latency. */
+    GST_WARNING_OBJECT (element, "failed to query latency");
+  }
+  gst_query_unref (query);
+
+  return res;
+}
+
 static GstStateChangeReturn
 gst_bin_change_state_func (GstElement * element, GstStateChange transition)
 {
@@ -2040,6 +2091,18 @@ gst_bin_change_state_func (GstElement * element, GstStateChange transition)
   bin = GST_BIN_CAST (element);
 
   switch (next) {
+    case GST_STATE_PLAYING:
+    {
+      gboolean toplevel;
+
+      GST_OBJECT_LOCK (bin);
+      toplevel = BIN_IS_TOPLEVEL (bin);
+      GST_OBJECT_UNLOCK (bin);
+
+      if (toplevel)
+        do_bin_latency (element);
+      break;
+    }
     case GST_STATE_PAUSED:
       /* Clear EOS list on next PAUSED */
       GST_OBJECT_LOCK (bin);
@@ -2350,6 +2413,7 @@ bin_push_state_continue (BinContinueData * data)
 
 /* an element started an async state change, if we were not busy with a state
  * change, we perform a lost state.
+ * This function is called with the OBJECT lock.
  */
 static void
 bin_handle_async_start (GstBin * bin, gboolean new_base_time)
@@ -2433,7 +2497,9 @@ was_no_preroll:
 }
 
 /* this function is called when there are no more async elements in the bin. We
- * post a state changed message and an ASYNC_DONE message. */
+ * post a state changed message and an ASYNC_DONE message.
+ * This function is called with the OBJECT lock.
+ */
 static void
 bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret)
 {
index 079be69..a8a73ca 100644 (file)
@@ -371,11 +371,8 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
     {
       GstClockTime new_base_time;
-      GstQuery *query;
-      GstClockTime min_latency, max_latency;
       GstClockTime start_time, stream_time, delay;
       gboolean new_clock, update_stream_time, update_clock;
-      gboolean res;
       GstClock *cur_clock;
 
       GST_DEBUG_OBJECT (element, "selecting clock and base_time");
@@ -457,40 +454,6 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
 
       if (cur_clock)
         gst_object_unref (cur_clock);
-
-      /* determine latency in this pipeline */
-      GST_DEBUG_OBJECT (element, "querying pipeline latency");
-      query = gst_query_new_latency ();
-      if (gst_element_query (element, query)) {
-        gboolean live;
-
-        gst_query_parse_latency (query, &live, &min_latency, &max_latency);
-
-        GST_DEBUG_OBJECT (element,
-            "configuring min latency %" GST_TIME_FORMAT ", max latency %"
-            GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
-            GST_TIME_ARGS (max_latency), live);
-
-        /* configure latency on elements */
-        res =
-            gst_element_send_event (element,
-            gst_event_new_latency (min_latency));
-        if (res) {
-          GST_INFO_OBJECT (element, "configured latency of %" GST_TIME_FORMAT,
-              GST_TIME_ARGS (min_latency));
-        } else {
-          GST_WARNING_OBJECT (element,
-              "failed to configure latency of %" GST_TIME_FORMAT,
-              GST_TIME_ARGS (min_latency));
-          GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
-              ("Failed to configure latency of %" GST_TIME_FORMAT,
-                  GST_TIME_ARGS (min_latency)));
-        }
-      } else {
-        /* this is not a real problem, we just don't configure any latency. */
-        GST_WARNING_OBJECT (element, "failed to query pipeline latency");
-      }
-      gst_query_unref (query);
       break;
     }
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED: