libs/gst/base/gstbasesink.c: Refactor adjusting the running_time with latency and...
authorWim Taymans <wim.taymans@gmail.com>
Mon, 19 May 2008 11:11:49 +0000 (11:11 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 19 May 2008 11:11:49 +0000 (11:11 +0000)
Original commit message from CVS:
* libs/gst/base/gstbasesink.c: (gst_base_sink_adjust_time),
(gst_base_sink_wait_clock), (gst_base_sink_wait_eos),
(gst_base_sink_do_sync), (gst_base_sink_chain_unlocked):
Refactor adjusting the running_time with latency and offset into a
separate method.
When doing clipping, we still want to use the subclass get_times method,
just in case the DURATION or TIMESTAMP are not set.

ChangeLog
libs/gst/base/gstbasesink.c

index 9a0260c..b653c3b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-05-19  Wim Taymans  <wim.taymans@collabora.co.uk>
+
+       * libs/gst/base/gstbasesink.c: (gst_base_sink_adjust_time),
+       (gst_base_sink_wait_clock), (gst_base_sink_wait_eos),
+       (gst_base_sink_do_sync), (gst_base_sink_chain_unlocked):
+       Refactor adjusting the running_time with latency and offset into a
+       separate method.
+       When doing clipping, we still want to use the subclass get_times method,
+       just in case the DURATION or TIMESTAMP are not set.
+
 2008-05-19  Tim-Philipp Müller  <tim.muller at collabora co uk>
 
        * docs/gst/gstreamer-sections.txt:
index 34f62c4..258ac38 100644 (file)
@@ -1396,6 +1396,33 @@ out_of_segment:
 }
 
 /* with STREAM_LOCK, PREROLL_LOCK
+ * adjust a timestamp with the latency and timestamp offset */
+static GstClockTime
+gst_base_sink_adjust_time (GstBaseSink * basesink, GstClockTime time)
+{
+  GstClockTimeDiff ts_offset;
+
+  /* don't do anything funny with invalid timestamps */
+  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time)))
+    return time;
+
+  time += basesink->priv->latency;
+
+  /* apply offset, be carefull for underflows */
+  ts_offset = basesink->priv->ts_offset;
+  if (ts_offset < 0) {
+    ts_offset = -ts_offset;
+    if (ts_offset < time)
+      time -= ts_offset;
+    else
+      time = 0;
+  } else
+    time += ts_offset;
+
+  return time;
+}
+
+/* with STREAM_LOCK, PREROLL_LOCK
  *
  * Waits for the clock to reach @time. If @time is not valid, no
  * synchronisation is done and BADTIME is returned. 
@@ -1406,7 +1433,8 @@ out_of_segment:
  * so we can unlock the entry at any time. While we are blocking, we 
  * release the PREROLL_LOCK so that other threads can interrupt the entry.
  *
- * @time is expressed in running time.
+ * @time is expressed in running time and must be compensated for latency and
+ * other offsets by the caller.
  */
 static GstClockReturn
 gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time,
@@ -1415,7 +1443,6 @@ gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time,
   GstClockID id;
   GstClockReturn ret;
   GstClock *clock;
-  GstClockTimeDiff ts_offset;
 
   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time)))
     goto invalid_time;
@@ -1427,20 +1454,8 @@ gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time,
   if (G_UNLIKELY ((clock = GST_ELEMENT_CLOCK (basesink)) == NULL))
     goto no_clock;
 
-  /* add base time and latency */
+  /* add base_time, latency and ts_offset */
   time += GST_ELEMENT_CAST (basesink)->base_time;
-  time += basesink->priv->latency;
-
-  /* apply offset, be carefull for underflows */
-  ts_offset = basesink->priv->ts_offset;
-  if (ts_offset < 0) {
-    ts_offset = -ts_offset;
-    if (ts_offset < time)
-      time -= ts_offset;
-    else
-      time = 0;
-  } else
-    time += ts_offset;
 
   id = gst_clock_new_single_shot_id (clock, time);
   GST_OBJECT_UNLOCK (basesink);
@@ -1542,6 +1557,8 @@ gst_base_sink_wait_eos (GstBaseSink * sink, GstClockTime time,
   GstFlowReturn ret;
 
   do {
+    GstClockTime stime;
+
     GST_DEBUG_OBJECT (sink, "checking preroll");
 
     /* first wait for the playing state before we can continue */
@@ -1557,7 +1574,8 @@ gst_base_sink_wait_eos (GstBaseSink * sink, GstClockTime time,
 
     /* wait for the clock, this can be interrupted because we got shut down or 
      * we PAUSED. */
-    status = gst_base_sink_wait_clock (sink, time, jitter);
+    stime = gst_base_sink_adjust_time (sink, time);
+    status = gst_base_sink_wait_clock (sink, stime, jitter);
 
     GST_DEBUG_OBJECT (sink, "clock returned %d", status);
 
@@ -1614,7 +1632,7 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstPad * pad,
   GstClockTimeDiff jitter;
   gboolean syncable;
   GstClockReturn status = GST_CLOCK_OK;
-  GstClockTime rstart, rstop, sstart, sstop;
+  GstClockTime rstart, rstop, sstart, sstop, stime;
   gboolean do_sync;
   GstBaseSinkPrivate *priv;
 
@@ -1679,7 +1697,8 @@ again:
 
   /* this function will return immediatly if start == -1, no clock
    * or sync is disabled with GST_CLOCK_BADTIME. */
-  status = gst_base_sink_wait_clock (basesink, rstart, &jitter);
+  stime = gst_base_sink_adjust_time (basesink, rstart);
+  status = gst_base_sink_wait_clock (basesink, stime, &jitter);
 
   GST_DEBUG_OBJECT (basesink, "clock returned %d", status);
 
@@ -2496,6 +2515,7 @@ static GstFlowReturn
 gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
     GstBuffer * buf)
 {
+  GstBaseSinkClass *bclass;
   GstFlowReturn result;
   GstClockTime start = GST_CLOCK_TIME_NONE, end = GST_CLOCK_TIME_NONE;
   GstSegment *clip_segment;
@@ -2527,10 +2547,18 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
     basesink->segment.stop = -1;
   }
 
-  /* check if the buffer needs to be dropped */
-  /* we don't use the subclassed method as it may not return
-   * valid values for our purpose here */
-  gst_base_sink_get_times (basesink, buf, &start, &end);
+  bclass = GST_BASE_SINK_GET_CLASS (basesink);
+
+  /* check if the buffer needs to be dropped, we first ask the subclass for the
+   * start and end */
+  if (bclass->get_times)
+    bclass->get_times (basesink, buf, &start, &end);
+
+  if (start == -1) {
+    /* if the subclass does not want sync, we use our own values so that we at
+     * least clip the buffer to the segment */
+    gst_base_sink_get_times (basesink, buf, &start, &end);
+  }
 
   GST_DEBUG_OBJECT (basesink, "got times start: %" GST_TIME_FORMAT
       ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));