segment: take offset into account in _to_position()
[platform/upstream/gstreamer.git] / gst / gstsegment.c
index c663421..590218e 100644 (file)
@@ -268,7 +268,7 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
   if (segment->duration != -1)
     start = MIN (start, segment->duration);
   else
-    start = MAX (start, 0);
+    start = MAX ((gint64) start, 0);
 
   /* stop can be -1 if we have not configured a stop. */
   switch (stop_type) {
@@ -292,9 +292,9 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
   /* if we have a valid stop time, make sure it is clipped */
   if (stop != -1) {
     if (segment->duration != -1)
-      stop = CLAMP (stop, 0, segment->duration);
+      stop = CLAMP ((gint64) stop, 0, (gint64) segment->duration);
     else
-      stop = MAX (stop, 0);
+      stop = MAX ((gint64) stop, 0);
   }
 
   /* we can't have stop before start */
@@ -460,7 +460,7 @@ gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
  * segment. Position is a value between @segment start and stop time.
  *
  * This function is typically used by elements that need to synchronize to the
- * global clock in a pipeline. The runnning time is a constantly increasing value
+ * global clock in a pipeline. The running time is a constantly increasing value
  * starting from 0. When gst_segment_init() is called, this value will reset to
  * 0.
  *
@@ -651,7 +651,7 @@ gst_segment_to_position (const GstSegment * segment, GstFormat format,
 
   if (G_LIKELY (segment->rate > 0.0)) {
     /* bring to corrected position in segment */
-    result += start;
+    result += start + segment->offset;
 
     /* outside of the segment boundary stop */
     if (G_UNLIKELY (stop != -1 && result > stop))
@@ -663,12 +663,11 @@ gst_segment_to_position (const GstSegment * segment, GstFormat format,
       return -1;
 
     /* bring to corrected position in segment */
-    result = stop - result;
+    result = stop - result - segment->offset;
   }
   return result;
 }
 
-
 /**
  * gst_segment_set_running_time:
  * @segment: a #GstSegment structure.
@@ -713,3 +712,51 @@ gst_segment_set_running_time (GstSegment * segment, GstFormat format,
 
   return TRUE;
 }
+
+/**
+ * gst_segment_offset_running_time:
+ * @segment: a #GstSegment structure.
+ * @format: the format of the segment.
+ * @offset: the offset to apply in the segment
+ *
+ * Adjust the values in @segment so that @offset is applied to all
+ * future running-time calculations.
+ *
+ * Since: 1.4
+ *
+ * Returns: %TRUE if the segment could be updated successfully. If %FALSE is
+ * returned, @offset is not in @segment.
+ */
+gboolean
+gst_segment_offset_running_time (GstSegment * segment, GstFormat format,
+    gint64 offset)
+{
+  g_return_val_if_fail (segment != NULL, FALSE);
+  g_return_val_if_fail (segment->format == format, FALSE);
+
+  if (offset == 0)
+    return TRUE;
+
+  if (offset > 0) {
+    /* positive offset, we can simply apply to the base time */
+    segment->base += offset;
+  } else {
+    offset = -offset;
+    /* negative offset, first try to subtract from base */
+    if (segment->base > offset) {
+      segment->base -= offset;
+    } else {
+      guint64 position;
+
+      /* subtract all from segment.base, remainder in offset */
+      offset -= segment->base;
+      segment->base = 0;
+      position = gst_segment_to_position (segment, format, offset);
+      if (position == -1)
+        return FALSE;
+
+      segment->offset = position;
+    }
+  }
+  return TRUE;
+}