gst/interleave/interleave.c: Implement latency query.
authorSebastian Dröge <slomo@circular-chaos.org>
Wed, 28 May 2008 08:14:16 +0000 (08:14 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Wed, 28 May 2008 08:14:16 +0000 (08:14 +0000)
Original commit message from CVS:
* gst/interleave/interleave.c: (gst_interleave_src_query_duration),
(gst_interleave_src_query_latency), (gst_interleave_src_query):
Implement latency query.

gst/interleave/interleave.c

index b65f5a2..699a1f0 100644 (file)
@@ -643,6 +643,7 @@ gst_interleave_src_query_duration (GstInterleave * self, GstQuery * query)
       case GST_ITERATOR_RESYNC:
         max = -1;
         res = TRUE;
+        gst_iterator_resync (it);
         break;
       default:
         res = FALSE;
@@ -654,6 +655,8 @@ gst_interleave_src_query_duration (GstInterleave * self, GstQuery * query)
 
   if (res) {
     /* and store the max */
+    GST_DEBUG_OBJECT (self, "Total duration in format %s: %"
+        GST_TIME_FORMAT, gst_format_get_name (format), GST_TIME_ARGS (max));
     gst_query_set_duration (query, format, max);
   }
 
@@ -661,6 +664,89 @@ gst_interleave_src_query_duration (GstInterleave * self, GstQuery * query)
 }
 
 static gboolean
+gst_interleave_src_query_latency (GstInterleave * self, GstQuery * query)
+{
+  GstClockTime min, max;
+  gboolean live;
+  gboolean res;
+  GstIterator *it;
+  gboolean done;
+
+  res = TRUE;
+  done = FALSE;
+
+  live = FALSE;
+  min = 0;
+  max = GST_CLOCK_TIME_NONE;
+
+  /* Take maximum of all latency values */
+  it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (self));
+  while (!done) {
+    GstIteratorResult ires;
+    gpointer item;
+
+    ires = gst_iterator_next (it, &item);
+    switch (ires) {
+      case GST_ITERATOR_DONE:
+        done = TRUE;
+        break;
+      case GST_ITERATOR_OK:
+      {
+        GstPad *pad = GST_PAD_CAST (item);
+        GstQuery *peerquery;
+        GstClockTime min_cur, max_cur;
+        gboolean live_cur;
+
+        peerquery = gst_query_new_latency ();
+
+        /* Ask peer for latency */
+        res &= gst_pad_peer_query (pad, peerquery);
+
+        /* take max from all valid return values */
+        if (res) {
+          gst_query_parse_latency (peerquery, &live_cur, &min_cur, &max_cur);
+
+          if (min_cur > min)
+            min = min_cur;
+
+          if (max_cur != GST_CLOCK_TIME_NONE &&
+              ((max != GST_CLOCK_TIME_NONE && max_cur > max) ||
+                  (max == GST_CLOCK_TIME_NONE)))
+            max = max_cur;
+
+          live = live || live_cur;
+        }
+
+        gst_query_unref (peerquery);
+        break;
+      }
+      case GST_ITERATOR_RESYNC:
+        live = FALSE;
+        min = 0;
+        max = GST_CLOCK_TIME_NONE;
+        res = TRUE;
+        gst_iterator_resync (it);
+        break;
+      default:
+        res = FALSE;
+        done = TRUE;
+        break;
+    }
+  }
+  gst_iterator_free (it);
+
+  if (res) {
+    /* store the results */
+    GST_DEBUG_OBJECT (self, "Calculated total latency: live %s, min %"
+        GST_TIME_FORMAT ", max %" GST_TIME_FORMAT,
+        (live ? "yes" : "no"), GST_TIME_ARGS (min), GST_TIME_ARGS (max));
+    gst_query_set_latency (query, live, min, max);
+  }
+
+  return res;
+}
+
+static gboolean
 gst_interleave_src_query (GstPad * pad, GstQuery * query)
 {
   GstInterleave *self = GST_INTERLEAVE (gst_pad_get_parent (pad));
@@ -691,6 +777,9 @@ gst_interleave_src_query (GstPad * pad, GstQuery * query)
     case GST_QUERY_DURATION:
       res = gst_interleave_src_query_duration (self, query);
       break;
+    case GST_QUERY_LATENCY:
+      res = gst_interleave_src_query_latency (self, query);
+      break;
     default:
       /* FIXME, needs a custom query handler because we have multiple
        * sinkpads */