queue2: Avoid useless segment_to_running_time() calculations.
authorEdward Hervey <bilboed@bilboed.com>
Tue, 19 Oct 2010 15:40:13 +0000 (17:40 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Thu, 2 Dec 2010 18:04:56 +0000 (19:04 +0100)
* Cache src and sink time
* Use a boolean to known whether src/sink time needs to be recalculated

Avoids 50% of calls to gst_segment_to_running_time()

plugins/elements/gstqueue2.c
plugins/elements/gstqueue2.h

index 2789dd9..63e0210 100644 (file)
@@ -432,6 +432,11 @@ gst_queue2_init (GstQueue2 * queue, GstQueue2Class * g_class)
   gst_segment_init (&queue->sink_segment, GST_FORMAT_TIME);
   gst_segment_init (&queue->src_segment, GST_FORMAT_TIME);
 
+  queue->sinktime = GST_CLOCK_TIME_NONE;
+  queue->srctime = GST_CLOCK_TIME_NONE;
+  queue->sink_tainted = TRUE;
+  queue->src_tainted = TRUE;
+
   queue->srcresult = GST_FLOW_WRONG_STATE;
   queue->sinkresult = GST_FLOW_WRONG_STATE;
   queue->is_eos = FALSE;
@@ -673,20 +678,25 @@ gst_queue2_bufferalloc (GstPad * pad, guint64 offset, guint size,
 static void
 update_time_level (GstQueue2 * queue)
 {
-  gint64 sink_time, src_time;
-
-  sink_time =
-      gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
-      queue->sink_segment.last_stop);
+  if (queue->sink_tainted) {
+    queue->sinktime =
+        gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
+        queue->sink_segment.last_stop);
+    queue->sink_tainted = FALSE;
+  }
 
-  src_time = gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
-      queue->src_segment.last_stop);
+  if (queue->src_tainted) {
+    queue->srctime =
+        gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
+        queue->src_segment.last_stop);
+    queue->src_tainted = FALSE;
+  }
 
   GST_DEBUG_OBJECT (queue, "sink %" GST_TIME_FORMAT ", src %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (sink_time), GST_TIME_ARGS (src_time));
+      GST_TIME_ARGS (queue->sinktime), GST_TIME_ARGS (queue->srctime));
 
-  if (sink_time >= src_time)
-    queue->cur_level.time = sink_time - src_time;
+  if (queue->sinktime >= queue->srctime)
+    queue->cur_level.time = queue->sinktime - queue->srctime;
   else
     queue->cur_level.time = 0;
 }
@@ -694,7 +704,8 @@ update_time_level (GstQueue2 * queue)
 /* take a NEWSEGMENT event and apply the values to segment, updating the time
  * level of queue. */
 static void
-apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment)
+apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment,
+    gboolean is_sink)
 {
   gboolean update;
   GstFormat format;
@@ -736,13 +747,19 @@ apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment)
   GST_DEBUG_OBJECT (queue,
       "configured NEWSEGMENT %" GST_SEGMENT_FORMAT, segment);
 
+  if (is_sink)
+    queue->sink_tainted = TRUE;
+  else
+    queue->src_tainted = TRUE;
+
   /* segment can update the time level of the queue */
   update_time_level (queue);
 }
 
 /* take a buffer and update segment, updating the time level of the queue. */
 static void
-apply_buffer (GstQueue2 * queue, GstBuffer * buffer, GstSegment * segment)
+apply_buffer (GstQueue2 * queue, GstBuffer * buffer, GstSegment * segment,
+    gboolean is_sink)
 {
   GstClockTime duration, timestamp;
 
@@ -763,6 +780,11 @@ apply_buffer (GstQueue2 * queue, GstBuffer * buffer, GstSegment * segment)
 
   gst_segment_set_last_stop (segment, GST_FORMAT_TIME, timestamp);
 
+  if (is_sink)
+    queue->sink_tainted = TRUE;
+  else
+    queue->src_tainted = TRUE;
+
   /* calc diff with other end */
   update_time_level (queue);
 }
@@ -1449,6 +1471,8 @@ gst_queue2_locked_flush (GstQueue2 * queue)
   GST_QUEUE2_CLEAR_LEVEL (queue->cur_level);
   gst_segment_init (&queue->sink_segment, GST_FORMAT_TIME);
   gst_segment_init (&queue->src_segment, GST_FORMAT_TIME);
+  queue->sinktime = queue->srctime = GST_CLOCK_TIME_NONE;
+  queue->sink_tainted = queue->src_tainted = TRUE;
   if (queue->starting_segment != NULL)
     gst_event_unref (queue->starting_segment);
   queue->starting_segment = NULL;
@@ -1782,7 +1806,7 @@ gst_queue2_locked_enqueue (GstQueue2 * queue, gpointer item)
     queue->bytes_in += size;
 
     /* apply new buffer to segment stats */
-    apply_buffer (queue, buffer, &queue->sink_segment);
+    apply_buffer (queue, buffer, &queue->sink_segment, TRUE);
     /* update the byterate stats */
     update_in_rates (queue);
 
@@ -1803,7 +1827,7 @@ gst_queue2_locked_enqueue (GstQueue2 * queue, gpointer item)
         queue->is_eos = TRUE;
         break;
       case GST_EVENT_NEWSEGMENT:
-        apply_segment (queue, event, &queue->sink_segment);
+        apply_segment (queue, event, &queue->sink_segment, TRUE);
         /* This is our first new segment, we hold it
          * as we can't save it on the temp file */
         if (!QUEUE_IS_USING_QUEUE (queue)) {
@@ -1889,7 +1913,7 @@ gst_queue2_locked_dequeue (GstQueue2 * queue)
     }
     queue->bytes_out += size;
 
-    apply_buffer (queue, buffer, &queue->src_segment);
+    apply_buffer (queue, buffer, &queue->src_segment, FALSE);
     /* update the byterate stats */
     update_out_rates (queue);
     /* update the buffering */
@@ -1907,7 +1931,7 @@ gst_queue2_locked_dequeue (GstQueue2 * queue)
         GST_QUEUE2_CLEAR_LEVEL (queue->cur_level);
         break;
       case GST_EVENT_NEWSEGMENT:
-        apply_segment (queue, event, &queue->src_segment);
+        apply_segment (queue, event, &queue->src_segment, FALSE);
         break;
       default:
         break;
index 0a794f8..358b43a 100644 (file)
@@ -83,6 +83,11 @@ struct _GstQueue2
   GstSegment sink_segment;
   GstSegment src_segment;
 
+  /* Position of src/sink */
+  GstClockTime sinktime, srctime;
+  /* TRUE if either position needs to be recalculated */
+  gboolean sink_tainted, src_tainted;
+
   /* flowreturn when srcpad is paused */
   GstFlowReturn srcresult;
   GstFlowReturn sinkresult;