gstsegment: Handle positions before the segment properly
[platform/upstream/gstreamer.git] / tests / check / gst / gstsegment.c
index ecd8b06..f160462 100644 (file)
  *
  * You should have received a copy of the GNU Library General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include <gst/check/gstcheck.h>
 
+#define check_times(segment, position, stream_time, running_time) G_STMT_START { \
+  guint64 st, rt, pos; \
+  \
+  st = gst_segment_to_stream_time ((segment), (segment)->format, (position)); \
+  rt = gst_segment_to_running_time ((segment), (segment)->format, (position)); \
+  GST_DEBUG ("position %" G_GUINT64_FORMAT ", st %" G_GUINT64_FORMAT ", rt %" \
+      G_GUINT64_FORMAT, (guint64) (position), (guint64) (stream_time), (guint64) (running_time)); \
+  \
+  fail_unless_equals_int64 (st, (stream_time)); \
+  fail_unless_equals_int64 (rt, (running_time)); \
+  if ((stream_time) != -1) { \
+    pos = gst_segment_position_from_stream_time ((segment), (segment)->format, st); \
+    fail_unless_equals_int64 (pos, (position)); \
+  } \
+  \
+  if ((running_time) != -1) { \
+    pos = gst_segment_position_from_running_time ((segment), (segment)->format, rt); \
+    fail_unless_equals_int64 (pos, (position)); \
+  } \
+} G_STMT_END;
+
 /* mess with the segment structure in the bytes format */
 GST_START_TEST (segment_seek_nosize)
 {
@@ -37,21 +61,12 @@ GST_START_TEST (segment_seek_nosize)
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == -1);
+  fail_unless_equals_uint64 (segment.start, 100);
+  fail_unless_equals_uint64 (segment.position, 100);
+  fail_unless_equals_uint64 (segment.stop, -1);
   fail_unless (update == TRUE);
-
-#if 0
-  /* configure segment to stop relative, should not do anything since 
-   * size is unknown. */
-  gst_segment_do_seek (&segment, 1.0,
-      GST_FORMAT_BYTES,
-      GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == -1);
-  fail_unless (update == FALSE);
-#endif
+  /* appended after current position 0 */
+  check_times (&segment, 100, 100, 0);
 
   /* do some clipping on the open range */
   /* completely outside */
@@ -65,15 +80,15 @@ GST_START_TEST (segment_seek_nosize)
   /* partially inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 150);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 150);
 
   /* inside, touching lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       100, 150, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 150);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 150);
 
   /* special case, 0 duration and outside segment */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 90, 90, &cstart, &cstop);
@@ -83,22 +98,22 @@ GST_START_TEST (segment_seek_nosize)
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       100, 100, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 100);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 100);
 
   /* special case, 0 duration and inside the segment */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       120, 120, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 120);
-  fail_unless (cstop == 120);
+  fail_unless_equals_uint64 (cstart, 120);
+  fail_unless_equals_uint64 (cstop, 120);
 
   /* completely inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       150, 200, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 150);
-  fail_unless (cstop == 200);
+  fail_unless_equals_uint64 (cstart, 150);
+  fail_unless_equals_uint64 (cstop, 200);
 
   /* invalid start */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
@@ -107,42 +122,54 @@ GST_START_TEST (segment_seek_nosize)
   /* start outside, we don't know the stop */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == -1);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_int64 (cstop, -1);
 
   /* start on lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == -1);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_int64 (cstop, -1);
 
   /* start inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 150);
-  fail_unless (cstop == -1);
+  fail_unless_equals_uint64 (cstart, 150);
+  fail_unless_equals_int64 (cstop, -1);
+
+  /* move to 150, this is a running_time of 50 */
+  segment.position = 150;
+  check_times (&segment, 150, 150, 50);
 
   /* add 100 to start, set stop to 300 */
   gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
-  fail_unless (segment.start == 200);
-  fail_unless (segment.stop == 300);
+  fail_unless_equals_uint64 (segment.start, 200);
+  fail_unless_equals_uint64 (segment.position, 200);
+  fail_unless_equals_uint64 (segment.stop, 300);
+  fail_unless_equals_uint64 (segment.base, 50);
   fail_unless (update == TRUE);
+  check_times (&segment, 200, 200, 50);
+  check_times (&segment, 250, 250, 100);
 
   update = FALSE;
   /* add 100 to start (to 300), set stop to 200, this is not allowed.
    * nothing should be updated in the segment. A g_warning is
-   * emited. */
+   * emitted. */
   ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
           GST_FORMAT_BYTES,
           GST_SEEK_FLAG_NONE,
           GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update));
-  fail_unless (segment.start == 200);
-  fail_unless (segment.stop == 300);
+  fail_unless_equals_uint64 (segment.start, 200);
+  fail_unless_equals_uint64 (segment.position, 200);
+  fail_unless_equals_uint64 (segment.stop, 300);
+  fail_unless_equals_uint64 (segment.base, 50);
   /* update didn't change */
   fail_unless (update == FALSE);
+  check_times (&segment, 200, 200, 50);
+  check_times (&segment, 250, 250, 100);
 
   update = TRUE;
   /* seek relative to end, should not do anything since size is
@@ -151,9 +178,12 @@ GST_START_TEST (segment_seek_nosize)
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
-  fail_unless (segment.start == 200);
-  fail_unless (segment.stop == 300);
+  fail_unless_equals_uint64 (segment.start, 200);
+  fail_unless_equals_uint64 (segment.position, 200);
+  fail_unless_equals_uint64 (segment.stop, 300);
+  fail_unless_equals_uint64 (segment.base, 50);
   fail_unless (update == FALSE);
+  check_times (&segment, 250, 250, 100);
 
   /* completely outside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
@@ -166,29 +196,29 @@ GST_START_TEST (segment_seek_nosize)
   /* partially inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 250, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 200);
-  fail_unless (cstop == 250);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 250);
 
   /* inside, touching lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       200, 250, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 200);
-  fail_unless (cstop == 250);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 250);
 
   /* completely inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       250, 290, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 250);
-  fail_unless (cstop == 290);
+  fail_unless_equals_uint64 (cstart, 250);
+  fail_unless_equals_uint64 (cstop, 290);
 
   /* partially inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       250, 350, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 250);
-  fail_unless (cstop == 300);
+  fail_unless_equals_uint64 (cstart, 250);
+  fail_unless_equals_uint64 (cstop, 300);
 
   /* invalid start */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
@@ -197,20 +227,20 @@ GST_START_TEST (segment_seek_nosize)
   /* start outside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 200);
-  fail_unless (cstop == 300);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 300);
 
   /* start on lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 200);
-  fail_unless (cstop == 300);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 300);
 
   /* start inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 250);
-  fail_unless (cstop == 300);
+  fail_unless_equals_uint64 (cstart, 250);
+  fail_unless_equals_uint64 (cstop, 300);
 
   /* start outside on boundary */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
@@ -239,9 +269,11 @@ GST_START_TEST (segment_seek_size)
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == -1);
+  fail_unless_equals_uint64 (segment.start, 100);
+  fail_unless_equals_uint64 (segment.position, 100);
+  fail_unless_equals_int64 (segment.stop, -1);
   fail_unless (update == TRUE);
+  check_times (&segment, 100, 100, 0);
 
   /* do some clipping on the open range */
   /* completely outside */
@@ -255,22 +287,22 @@ GST_START_TEST (segment_seek_size)
   /* partially inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 150);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 150);
 
   /* inside, touching lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       100, 150, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 150);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 150);
 
   /* completely inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       150, 200, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 150);
-  fail_unless (cstop == 200);
+  fail_unless_equals_uint64 (cstart, 150);
+  fail_unless_equals_uint64 (cstop, 200);
 
   /* invalid start */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
@@ -279,28 +311,30 @@ GST_START_TEST (segment_seek_size)
   /* start outside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == -1);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_int64 (cstop, -1);
 
   /* start on lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == -1);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, -1);
 
   /* start inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 150);
-  fail_unless (cstop == -1);
+  fail_unless_equals_uint64 (cstart, 150);
+  fail_unless_equals_uint64 (cstop, -1);
 
   /* add 100 to start, set stop to 300, stop clips to 200 */
   gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
-  fail_unless (segment.start == 200);
-  fail_unless (segment.stop == 200);
+  fail_unless_equals_uint64 (segment.start, 200);
+  fail_unless_equals_uint64 (segment.position, 200);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  check_times (&segment, 200, 200, 0);
 
   /* add 100 to start (to 300), set stop to 200, this clips start
    * to duration */
@@ -308,18 +342,78 @@ GST_START_TEST (segment_seek_size)
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update);
-  fail_unless (segment.start == 200);
-  fail_unless (segment.stop == 200);
+  fail_unless_equals_uint64 (segment.start, 200);
+  fail_unless_equals_uint64 (segment.position, 200);
+  fail_unless_equals_uint64 (segment.stop, 200);
   fail_unless (update == FALSE);
+  check_times (&segment, 200, 200, 0);
+
+  /* special case, segment's start and stop are identical */
+  /* completely outside */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
+  fail_unless (res == FALSE);
+
+  /* completely outside also */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
+      250, 300, &cstart, &cstop);
+  fail_unless (res == FALSE);
+
+  /* stop at boundary point. it's outside because stop is exclusive */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
+      100, 200, &cstart, &cstop);
+  fail_unless (res == FALSE);
+
+  /* touching boundary point. it's inside because start at segment start */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
+      200, 300, &cstart, &cstop);
+  fail_unless (res == TRUE);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 200);
+
+  /* completely inside */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
+      200, 200, &cstart, &cstop);
+  fail_unless (res == TRUE);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 200);
+
+  /* exclusively cover boundary point */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
+      150, 250, &cstart, &cstop);
+  fail_unless (res == TRUE);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 200);
+
+  /* invalid start */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 200, &cstart, &cstop);
+  fail_unless (res == FALSE);
+
+  /* start outside */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
+  fail_unless (res == TRUE);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 200);
+
+  /* start on boundary point */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
+  fail_unless (res == TRUE);
+  fail_unless_equals_uint64 (cstart, 200);
+  fail_unless_equals_uint64 (cstop, 200);
+
+  /* start completely outside */
+  res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
+  fail_unless (res == FALSE);
 
   /* seek relative to end */
   gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == 180);
+  fail_unless_equals_uint64 (segment.start, 100);
+  fail_unless_equals_uint64 (segment.position, 100);
+  fail_unless_equals_uint64 (segment.stop, 180);
   fail_unless (update == TRUE);
+  check_times (&segment, 150, 150, 50);
 
   /* completely outside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
@@ -332,29 +426,29 @@ GST_START_TEST (segment_seek_size)
   /* partially inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 150);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 150);
 
   /* inside, touching lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       100, 150, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 150);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 150);
 
   /* completely inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       150, 170, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 150);
-  fail_unless (cstop == 170);
+  fail_unless_equals_uint64 (cstart, 150);
+  fail_unless_equals_uint64 (cstop, 170);
 
   /* partially inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
       150, 250, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 150);
-  fail_unless (cstop == 180);
+  fail_unless_equals_uint64 (cstart, 150);
+  fail_unless_equals_uint64 (cstop, 180);
 
   /* invalid start */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
@@ -363,20 +457,20 @@ GST_START_TEST (segment_seek_size)
   /* start outside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 180);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 180);
 
   /* start on lower bound */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 100);
-  fail_unless (cstop == 180);
+  fail_unless_equals_uint64 (cstart, 100);
+  fail_unless_equals_uint64 (cstop, 180);
 
   /* start inside */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
   fail_unless (res == TRUE);
-  fail_unless (cstart == 150);
-  fail_unless (cstop == 180);
+  fail_unless_equals_uint64 (cstart, 150);
+  fail_unless_equals_uint64 (cstop, 180);
 
   /* start outside on boundary */
   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
@@ -402,32 +496,40 @@ GST_START_TEST (segment_seek_reverse)
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 100);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 100);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 100);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 100);
   fail_unless (update == TRUE);
+  check_times (&segment, 100, 100, 0);
+  check_times (&segment, 50, 50, 50);
+  check_times (&segment, 0, 0, 100);
 
   /* update */
   gst_segment_do_seek (&segment, -1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_SET, 100 - 20, &update);
-  fail_unless (segment.start == 10);
-  fail_unless (segment.stop == 80);
-  fail_unless (segment.time == 10);
-  fail_unless (segment.position == 80);
+  fail_unless_equals_uint64 (segment.start, 10);
+  fail_unless_equals_uint64 (segment.stop, 80);
+  fail_unless_equals_uint64 (segment.time, 10);
+  fail_unless_equals_uint64 (segment.position, 80);
   fail_unless (update == TRUE);
+  check_times (&segment, 80, 80, 0);
+  check_times (&segment, 40, 40, 40);
+  check_times (&segment, 10, 10, 70);
 
   gst_segment_do_seek (&segment, -1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
-  fail_unless (segment.start == 20);
-  fail_unless (segment.stop == 80);
-  fail_unless (segment.time == 20);
-  fail_unless (segment.position == 80);
+  fail_unless_equals_uint64 (segment.start, 20);
+  fail_unless_equals_uint64 (segment.stop, 80);
+  fail_unless_equals_uint64 (segment.time, 20);
+  fail_unless_equals_uint64 (segment.position, 80);
   fail_unless (update == FALSE);
+  check_times (&segment, 80, 80, 0);
+  check_times (&segment, 20, 20, 60);
 }
 
 GST_END_TEST;
@@ -446,47 +548,12 @@ GST_START_TEST (segment_seek_rate)
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
   fail_unless (segment.format == GST_FORMAT_BYTES);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == -1);
-  fail_unless (segment.rate == 2.0);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.position, 0);
+  fail_unless_equals_int64 (segment.stop, -1);
+  fail_unless_equals_float (segment.rate, 2.0);
   fail_unless (update == FALSE);
-
-#if 0
-  /* 0 is the same in all formats and should not fail */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1, &update);
-  fail_unless (segment.format == GST_FORMAT_BYTES);
-
-  /* set to -1 means start from 0 */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_SET, -1, GST_SEEK_TYPE_NONE, -1, &update);
-  fail_unless (segment.format == GST_FORMAT_BYTES);
-  fail_unless (segment.start == 0);
-
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_CUR, 0, GST_SEEK_TYPE_NONE, -1, &update);
-
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_END, 0, GST_SEEK_TYPE_NONE, -1, &update);
-
-  /* -1 for end is fine too in all formats */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
-
-  /* 0 as relative end is fine too */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
-
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
-#endif
+  check_times (&segment, 50, 50, 25);
 
   /* set a real stop position, this must happen in bytes */
   gst_segment_do_seek (&segment, 3.0,
@@ -494,1256 +561,573 @@ GST_START_TEST (segment_seek_rate)
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
   fail_unless (segment.format == GST_FORMAT_BYTES);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 100);
-  fail_unless (segment.rate == 3.0);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 100);
+  fail_unless_equals_float (segment.rate, 3.0);
   /* no seek should happen, we just updated the stop position in forward
    * playback mode.*/
   fail_unless (update == FALSE);
-
-#if 0
-  /* 0 as relative end is fine too */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
-  fail_unless (segment.stop == 100);
-
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
-  fail_unless (segment.stop == 100);
-
-  /* -1 for end is fine too in all formats */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
-  fail_unless (segment.stop == -1);
-#endif
+  check_times (&segment, 60, 60, 20);
 
   /* set some duration, stop -1 END seeks will now work with the
    * duration, if the formats match */
   segment.duration = 200;
-  fail_unless (segment.duration == 200);
 
   /* seek to end with 0 should set the stop to the duration */
   gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.duration == 200);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.duration, 200);
 
   /* subtract 100 from the end */
   gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
-  fail_unless (segment.stop == 100);
-  fail_unless (segment.duration == 200);
+  fail_unless_equals_uint64 (segment.stop, 100);
+  fail_unless_equals_uint64 (segment.duration, 200);
 
   /* add 100 to the duration, this should be clamped to the duration */
   gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.duration == 200);
-
-#if 0
-  /* add 300 to the start, this should be clamped to the duration */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_CUR, 300, GST_SEEK_TYPE_END, 0, &update);
-  fail_unless (segment.start == 200);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.duration == 200);
-
-  /* subtract 300 from the start, this should be clamped to 0 */
-  gst_segment_do_seek (&segment, 2.0,
-      GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
-      GST_SEEK_TYPE_CUR, -300, GST_SEEK_TYPE_END, 0, &update);
-  GST_DEBUG ("%" G_GINT64_FORMAT, segment.start);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.duration == 200);
-#endif
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.duration, 200);
 }
 
 GST_END_TEST;
 
-#if 0
-/* mess with the segment structure in the bytes format */
-GST_START_TEST (segment_newsegment_open)
+GST_START_TEST (segment_copy)
 {
-  GstSegment segment;
-
-  gst_segment_init (&segment, GST_FORMAT_BYTES);
-
-  /* time should also work for starting from 0 */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, -1,
-      0);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_BYTES);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == -1);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* we set stop but in the wrong format, stop stays open. */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0,
-      200, 0);
-
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == -1);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-
-  /* update, nothing changes */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 0, -1,
-      0);
-
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == -1);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-
-  /* update */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
-      GST_FORMAT_BYTES, 100, -1, 100);
-
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == -1);
-  fail_unless (segment.time == 100);
-  fail_unless (segment.base == 100);
-  fail_unless (segment.position == 100);
-
-  /* last_stop 0, base does not change */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
-      -1, 0);
-
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == -1);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 100);
+  GstSegment *copy;
+  GstSegment segment = { 0.0, };
 
-  gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 200);
+  /* this is a boxed type copy function, we support copying NULL */
+  fail_unless (gst_segment_copy (NULL) == NULL);
 
-  fail_unless (segment.position == 200);
+  gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  /* last_stop 200, base changes */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
-      -1, 0);
+  segment.rate = -1.0;
+  segment.applied_rate = 1.0;
+  segment.start = 0;
+  segment.stop = 200;
+  segment.time = 0;
 
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == -1);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 300);
-  fail_unless (segment.position == 0);
+  copy = gst_segment_copy (&segment);
+  fail_unless (copy != NULL);
+  /* we inited the struct on the stack to zeroes, so direct comparison should
+   * be ok here despite the padding field and regardless of implementation */
+  fail_unless (memcmp (copy, &segment, sizeof (GstSegment)) == 0);
+  gst_segment_free (copy);
 }
 
 GST_END_TEST;
 
-
 /* mess with the segment structure in the bytes format */
-GST_START_TEST (segment_newsegment_closed)
+GST_START_TEST (segment_seek_noupdate)
 {
   GstSegment segment;
-
-  gst_segment_init (&segment, GST_FORMAT_BYTES);
-
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_BYTES, 0, 200, 0);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_BYTES);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* assume we advanced to position 40 */
-  gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 40);
-  fail_unless (segment.position == 40);
-
-  /* do an update to the start, last_stop is unchanged because it's bigger */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 20,
-      200, 20);
-
-  fail_unless (segment.start == 20);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 20);
-  fail_unless (segment.base == 20);
-  fail_unless (segment.position == 40);
-
-  /* do an update past our last_stop, it should be updated now */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 50,
-      300, 50);
-
-  fail_unless (segment.start == 50);
-  fail_unless (segment.stop == 300);
-  fail_unless (segment.time == 50);
-  fail_unless (segment.base == 50);
-  fail_unless (segment.position == 50);
-
-  /* and a new accumulated one */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_BYTES, 100, 400, 300);
-
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == 400);
-  fail_unless (segment.time == 300);
-  fail_unless (segment.base == 300);
-
-  /* and a new updated one */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
-      GST_FORMAT_BYTES, 100, 500, 300);
-
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == 500);
-  fail_unless (segment.time == 300);
-  fail_unless (segment.base == 300);
-
-  /* and a new partially updated one */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
-      GST_FORMAT_BYTES, 200, 500, 400);
-
-  fail_unless (segment.start == 200);
-  fail_unless (segment.stop == 500);
-  fail_unless (segment.time == 400);
-  fail_unless (segment.base == 400);
-}
-
-GST_END_TEST;
-
-/* mess with the segment structure in the time format */
-GST_START_TEST (segment_newsegment_streamtime)
-{
-  GstSegment segment;
-  guint64 result;
+  gboolean update;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  /***************************
-   * Normal segment
-   ***************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 0);
+  segment.start = 0;
+  segment.position = 50;
+  segment.stop = 200;
+  segment.time = 0;
 
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == 1.0);
+  /* doesn't change anything */
+  gst_segment_do_seek (&segment, 1.0,
+      GST_FORMAT_TIME,
+      GST_SEEK_FLAG_NONE,
+      GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
+  fail_unless (update == FALSE);
   fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 200);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /*********************
-   * time shifted by 500
-   *********************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 500);
-
-  fail_unless (segment.base == 200);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 500);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 600);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 500);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /*********************
-   * time offset by 500
-   *********************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_TIME, 500, 700, 0);
-
-  fail_unless (segment.base == 400);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* before segment is invalid */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 500);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 600);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 700);
-  fail_unless (result == 200);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 800);
-  fail_unless (result == -1);
-
-  /*************************************
-   * time offset by 500, shifted by 200
-   *************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_TIME, 500, 700, 200);
-
-  fail_unless (segment.base == 600);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* before segment is invalid */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 500);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 600);
-  fail_unless (result == 300);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 700);
-  fail_unless (result == 400);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 800);
-  fail_unless (result == -1);
-}
-
-GST_END_TEST;
-
-/* mess with the segment structure in the time format */
-GST_START_TEST (segment_newsegment_streamtime_rate)
-{
-  GstSegment segment;
-  guint64 result;
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 50);
+  fail_unless_equals_uint64 (segment.offset, 50);
 
-  gst_segment_init (&segment, GST_FORMAT_TIME);
-
-  /***************************
-   * Normal segment rate 2.0
-   ***************************/
-  gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 0);
-
-  fail_unless (segment.rate == 2.0);
-  fail_unless (segment.applied_rate == 1.0);
+  gst_segment_do_seek (&segment, 2.0,
+      GST_FORMAT_TIME,
+      GST_SEEK_FLAG_NONE,
+      GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
+  fail_unless (update == FALSE);
   fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 150);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 200);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***************************************
-   * Normal segment rate 2.0, offset
-   ***************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
-      GST_FORMAT_TIME, 100, 300, 0);
-
-  fail_unless (segment.base == 100);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 250);
-  fail_unless (result == 150);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == 200);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
-
-  /***************************************
-   * Normal segment rate -1.0, offset
-   ***************************************/
-
-  /* buffers will arrive from 300 to 100 in a sink, stream time
-   * calculation is unaffected by the rate */
-  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
-      GST_FORMAT_TIME, 100, 300, 0);
-
-  fail_unless (segment.base == 200);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 100);
-
-  /***********************************************
-   * Normal segment rate -1.0, offset, time = 200
-   ***********************************************/
-  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
-      GST_FORMAT_TIME, 100, 300, 200);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 50);
+  fail_unless_equals_uint64 (segment.offset, 50);
 
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 300);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == 400);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
+  gst_segment_do_seek (&segment, 1.0,
+      GST_FORMAT_TIME,
+      GST_SEEK_FLAG_FLUSH,
+      GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
+  fail_unless (update == FALSE);
+  fail_unless (segment.format == GST_FORMAT_TIME);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 0);
+  fail_unless_equals_uint64 (segment.offset, 50);
 }
 
 GST_END_TEST;
 
-/* mess with the segment structure in the time format */
-GST_START_TEST (segment_newsegment_streamtime_applied_rate)
+GST_START_TEST (segment_offset)
 {
   GstSegment segment;
-  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  /***********************************************************
-   * Normal segment rate 1.0, applied rate -1.0
-   * This means the timestamps represents a stream going backwards
-   * starting from @time to 0.
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, -1.0,
-      GST_FORMAT_TIME, 0, 200, 200);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == -1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 200);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* we count backwards from 200 */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 50);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 0);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***********************************************************
-   * Normal segment rate 1.0, applied rate 2.0
-   * This means the timestamps represents a stream at twice the
-   * normal rate
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 2.0,
-      GST_FORMAT_TIME, 0, 200, 0);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == 2.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 200);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 0);
-
-  /* the stream prepresents a stream going twice as fast, the position 
-   * in the segment is therefore scaled by the applied rate */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 300);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 400);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***********************************************************
-   * Normal segment rate 1.0, applied rate -2.0
-   * This means the timestamps represents a stream at twice the
-   * reverse rate
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, -2.0,
-      GST_FORMAT_TIME, 0, 200, 400);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == -2.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 400);
-  /* previous segment lasted 200, rate of 2.0 was already applied */
-  fail_unless (segment.base == 400);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* we count backwards from 400 */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 400);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 0);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***********************************************************
-   * Normal segment rate 1.0, applied rate -2.0
-   * This means the timestamps represents a stream at twice the
-   * reverse rate, start time cannot compensate the complete
-   * duration of the segment so we stop at 0
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, -2.0,
-      GST_FORMAT_TIME, 0, 200, 200);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == -2.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 200);
-  fail_unless (segment.base == 600);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* we count backwards from 200 */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 0);
-
-  /* clamp at 0 */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 0);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-}
-
-GST_END_TEST;
+  segment.start = 0;
+  segment.position = 50;
+  segment.stop = 200;
+  segment.time = 0;
 
-/* mess with the segment structure in the time format */
-GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
-{
-  GstSegment segment;
-  guint64 result;
+  check_times (&segment, 20, 20, 20);
+  check_times (&segment, 220, -1, -1);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          0) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 0);
+  fail_unless_equals_uint64 (segment.offset, 0);
+  check_times (&segment, 20, 20, 20);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          100) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 100);
+  fail_unless_equals_uint64 (segment.offset, 0);
+  check_times (&segment, 20, 20, 120);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          -50) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 50);
+  fail_unless_equals_uint64 (segment.offset, 0);
+  check_times (&segment, 20, 20, 70);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          -100) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 0);
+  fail_unless_equals_uint64 (segment.offset, 50);
+  check_times (&segment, 20, 20, -1);
+  check_times (&segment, 200, 200, 150);
+
+  /* can go negative */
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          -151) == FALSE);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 0);
+  fail_unless_equals_uint64 (segment.offset, 50);
+  check_times (&segment, 100, 100, 50);
+  check_times (&segment, 200, 200, 150);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          -150) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 0);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 0);
+  fail_unless_equals_uint64 (segment.offset, 200);
+  check_times (&segment, 200, 200, 0);
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  /***********************************************************
-   * Segment rate 2.0, applied rate 2.0
-   * this means we have a double speed stream that we should
-   * speed up by a factor of 2.0 some more. the resulting
-   * stream will be played at four times the speed. 
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 2.0, 2.0,
-      GST_FORMAT_TIME, 0, 200, 0);
-
-  fail_unless (segment.rate == 2.0);
-  fail_unless (segment.applied_rate == 2.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* only applied rate affects our calculation of the stream time */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 300);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 400);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***********************************************************
-   * Segment rate 2.0, applied rate -1.0
-   * this means we have a reverse stream that we should
-   * speed up by a factor of 2.0
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 2.0, -1.0,
-      GST_FORMAT_TIME, 0, 200, 200);
-
-  fail_unless (segment.rate == 2.0);
-  fail_unless (segment.applied_rate == -1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 200);
-  /* previous segment lasted 100 */
-  fail_unless (segment.base == 100);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* only applied rate affects our calculation of the stream time */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 50);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 0);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***********************************************************
-   * Segment rate -1.0, applied rate -1.0
-   * this means we have a reverse stream that we should
-   * reverse to get the normal stream again.
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, -1.0, -1.0,
-      GST_FORMAT_TIME, 0, 200, 200);
-
-  fail_unless (segment.rate == -1.0);
-  fail_unless (segment.applied_rate == -1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 200);
-  /* accumulated 100 of previous segment to make 200 */
-  fail_unless (segment.base == 200);
-  fail_unless (segment.position == 200);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* only applied rate affects our calculation of the stream time */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 50);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 0);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***********************************************************
-   * Segment rate -1.0, applied rate -1.0
-   * this means we have a reverse stream that we should
-   * reverse to get the normal stream again.
-   ************************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, -1.0, 2.0,
-      GST_FORMAT_TIME, 0, 200, 0);
-
-  fail_unless (segment.rate == -1.0);
-  fail_unless (segment.applied_rate == 2.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 400);
-  fail_unless (segment.position == 200);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* only applied rate affects our calculation of the stream time */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 300);
-
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 400);
-
-  /* outside of the segment */
-  result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
+  segment.start = 20;
+  segment.position = 50;
+  segment.stop = 220;
+  segment.time = 0;
+
+  check_times (&segment, 40, 20, 20);
+  check_times (&segment, 240, -1, -1);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          0) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 20);
+  fail_unless_equals_uint64 (segment.stop, 220);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 0);
+  fail_unless_equals_uint64 (segment.offset, 0);
+  check_times (&segment, 40, 20, 20);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          100) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 20);
+  fail_unless_equals_uint64 (segment.stop, 220);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 100);
+  fail_unless_equals_uint64 (segment.offset, 0);
+  check_times (&segment, 40, 20, 120);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          -50) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 20);
+  fail_unless_equals_uint64 (segment.stop, 220);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 50);
+  fail_unless_equals_uint64 (segment.offset, 0);
+  check_times (&segment, 40, 20, 70);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          -100) == TRUE);
+  fail_unless_equals_uint64 (segment.start, 20);
+  fail_unless_equals_uint64 (segment.stop, 220);
+  fail_unless_equals_uint64 (segment.time, 0);
+  fail_unless_equals_uint64 (segment.position, 50);
+  fail_unless_equals_uint64 (segment.base, 0);
+  fail_unless_equals_uint64 (segment.offset, 50);
+  check_times (&segment, 40, 20, -1);
+  check_times (&segment, 220, 200, 150);
 }
 
 GST_END_TEST;
 
-/* mess with the segment structure in the time format */
-GST_START_TEST (segment_newsegment_runningtime)
+GST_START_TEST (segment_full)
 {
   GstSegment segment;
-  guint64 result;
+  guint64 rt, pos;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  /***************************
-   * Normal segment
-   ***************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 0);
+  segment.start = 50;
+  segment.position = 150;
+  segment.stop = 200;
+  segment.time = 0;
 
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 0);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 0);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 100);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 100);
-
-  /* at edge is exactly the segment duration */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 200);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 200);
-
-  /* outside of the segment */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 300);
-  fail_unless (result == -1);
-
-  /***********************************************************
-   * time shifted by 500, check if accumulation worked.
-   * Rate convert to twice the speed which means scaling down
-   * all positions by 2.0 in this segment.
-   * Then time argument is not used at all here.
-   ***********************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 500);
-
-  /* normal speed gives elapsed of 200 */
-  fail_unless (segment.base == 200);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 0);
-  fail_unless (result == 200);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 0);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 250);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 100);
-
-  /* outside of the segment */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 310);
-  fail_unless (result == -1);
-
-  /********************************************
-   * time offset by 500
-   * applied rate is not used for running time
-   ********************************************/
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 2.0,
-      GST_FORMAT_TIME, 500, 700, 0);
-
-  /* previous segment played at double speed gives elapsed time of
-   * 100 added to previous accum of 200 gives 300. */
-  fail_unless (segment.base == 300);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* before segment is invalid */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
-  fail_unless (result == 300);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 500);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
-  fail_unless (result == 400);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 600);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
-  fail_unless (result == 500);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 700);
-
-  /* outside of the segment */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 600);
-  fail_unless (result == -1);
-
-  /**********************************************************
-   * time offset by 500, shifted by 200
-   * Negative rate makes the running time go backwards 
-   * relative to the segment stop position. again time
-   * is ignored.
-   **********************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
-      GST_FORMAT_TIME, 500, 700, 200);
-
-  fail_unless (segment.base == 500);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* before segment is invalid */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
-  fail_unless (result == 700);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 500);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
-  fail_unless (result == 600);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 600);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
-  fail_unless (result == 500);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 700);
-
-  /* outside of the segment */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 800);
-  fail_unless (result == -1);
-
-  /**********************************************************
-   * time offset by 500, shifted by 200
-   * Negative rate makes the running time go backwards at
-   * twice speed relative to the segment stop position. again 
-   * time is ignored.
-   **********************************************************/
-  gst_segment_set_newsegment (&segment, FALSE, -2.0, -2.0,
-      GST_FORMAT_TIME, 500, 700, 200);
-
-  fail_unless (segment.base == 700);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  /* before segment is invalid */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 600);
-  fail_unless (result == -1);
-
-  /* total scaled segment time is 100, accum is 700, so we get 800 */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
-  fail_unless (result == 800);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 500);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
-  fail_unless (result == 750);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 600);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
-  fail_unless (result == 700);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 700);
-
-  /* outside of the segment */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 900);
-  fail_unless (result == -1);
-
-  /* see if negative rate closed segment correctly */
-  gst_segment_set_newsegment (&segment, FALSE, -2.0, -1.0,
-      GST_FORMAT_TIME, 500, 700, 200);
-
-  /* previous segment lasted 100, and was at 700 so we should get 800 */
-  fail_unless (segment.base == 800);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 800);
-  fail_unless (result == 700);
+  check_times (&segment, 100, 50, 50);
+  check_times (&segment, 220, -1, -1);
+
+  fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
+          50, &rt) == 1);
+  fail_unless (rt == 0);
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, rt, &pos) == 1);
+  fail_unless (pos == 50);
+  fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
+          200, &rt) == 1);
+  fail_unless (rt == 150);
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, rt, &pos) == 1);
+  fail_unless (pos == 200);
+  fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 40, 40, NULL,
+          NULL));
+  fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 40,
+          &rt) == -1);
+  fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 49, 49, NULL,
+          NULL));
+  fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 49,
+          &rt) == -1);
+  fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 201, 201, NULL,
+          NULL));
+  fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 201,
+          &rt) == 1);
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, rt, &pos) == 1);
+  fail_unless (pos == 201);
+
+  fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
+          -50) == TRUE);
+  fail_unless (segment.offset == 50);
+
+  fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
+          50, &rt) == -1);
+  GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
+  fail_unless (rt == 50);
+
+  segment.start = 50;
+  segment.stop = 300;
+  segment.position = 150;
+  segment.time = 0;
+  segment.offset = 0;
+  gst_segment_set_running_time (&segment, GST_FORMAT_TIME, 100);
+  fail_unless_equals_int (segment.base, 100);
+
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 70, &pos) == 1);
+  fail_unless_equals_int (pos, 120);
+
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 140, &pos) == 1);
+  fail_unless_equals_int (pos, 190);
+
+  /* Test a non-1.0 rate that lands right before the segment, but still +ve */
+  segment.rate = 1.1;
+  segment.start = 100;
+  segment.offset = 0;
+  segment.stop = 500;
+  segment.position = 40;
+  segment.base = 150;
+  segment.time = 10000;
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 140, &pos) == 1);
+  fail_unless (pos == 89);
+  /* And now one that should give a position < 0 */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 0, &pos) == -1);
+  fail_unless (pos == 65);
+
+  /* Test a non-1.0 negative rate that lands right after the (reversed) segment, but still +ve position */
+  segment.rate = -2.0;
+  segment.start = 100;
+  segment.offset = 0;
+  segment.stop = 500;
+  segment.position = 150;
+  segment.base = 133;
+  segment.time = 10000;
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 200 + 133 + 20, &pos) == 1);
+  fail_unless (pos == 60);
+  /* And now one that should give a position < 0, reported as a negated value */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 200 + 133 + 70, &pos) == -1);
+  fail_unless (pos == 40);
+
+  /* Test gst_segment_position_from_running_time_full() with offsets */
+  segment.rate = 2.0;
+  segment.start = 100;
+  segment.offset = 100;
+  segment.stop = 500;
+  segment.position = 150;
+  segment.base = 175;
+  segment.time = 10000;
+  /* Position before the segment but >= 0 */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 75, &pos) == 1);
+  fail_unless (pos == 0);
+  fail_unless (gst_segment_position_from_running_time (&segment,
+          GST_FORMAT_TIME, 75) == -1);
+
+  /* Position before the segment and < 0 */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 65, &pos) == -1);
+  fail_unless (pos == 20);      /* Actually -20 */
+  fail_unless (gst_segment_position_from_running_time (&segment,
+          GST_FORMAT_TIME, 65) == -1);
+
+  /* After the segment */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 175 + 150 + 10, &pos) == 1);
+  fail_unless (pos == 520);
+  fail_unless (gst_segment_position_from_running_time (&segment,
+          GST_FORMAT_TIME, 175 + 150 + 10) == -1);
+
+  /* And with negative rate, so the segment is reversed */
+  segment.rate = -2.0;
+
+  /* Before the segment */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 75, &pos) == 1);
+  fail_unless (pos == 600);
+  fail_unless (gst_segment_position_from_running_time (&segment,
+          GST_FORMAT_TIME, 75) == -1);
+
+  /* Position after the segment and < 0 */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 400, &pos) == -1);
+  fail_unless (pos == 50);      /* Actually -50 */
+  fail_unless (gst_segment_position_from_running_time (&segment,
+          GST_FORMAT_TIME, 400) == -1);
+
+  /* Position after the segment and >= 0 */
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 325 + 10, &pos) == 1);
+  fail_unless (pos == 80);
+  fail_unless (gst_segment_position_from_running_time (&segment,
+          GST_FORMAT_TIME, 325 + 10) == -1);
+
+  /* Big offset can clip away an entire reversed segment and produce a negative position anyway */
+  segment.offset = 1000;
+  fail_unless (gst_segment_position_from_running_time_full (&segment,
+          GST_FORMAT_TIME, 75, &pos) == -1);
+  fail_unless (pos == 300);     /* Actually -300 */
 }
 
 GST_END_TEST;
 
-/* mess with the segment structure in the time format */
-GST_START_TEST (segment_newsegment_accum)
+GST_START_TEST (segment_stream_time_full)
 {
   GstSegment segment;
-  guint64 result;
+  guint64 st, pos;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  /***************************
-   * Normal reverse segment
-   ***************************/
-  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 0);
-
-  fail_unless (segment.rate == -1.0);
-  fail_unless (segment.applied_rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 200);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 0);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 50);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 150);
-
-  /* update segment, this accumulates 50 from the previous segment. */
-  gst_segment_set_newsegment (&segment, TRUE, -2.0, 1.0,
-      GST_FORMAT_TIME, 0, 150, 0);
-
-  fail_unless (segment.rate == -2.0);
-  fail_unless (segment.applied_rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 150);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 50);
-  fail_unless (segment.position == 150);
-  fail_unless (segment.duration == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 50);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 150);
-
-  /* 50 accumulated + 50 / 2 */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 75);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 100);
-
-  /* update segment, this does not accumulate anything. */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
-      GST_FORMAT_TIME, 100, 200, 100);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 100);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 100);
-  fail_unless (segment.base == 50);
-  fail_unless (segment.position == 150);
-  fail_unless (segment.duration == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
-  fail_unless (result == 50);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 100);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 100);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 150);
+  segment.start = 50;
+  segment.stop = 200;
+  segment.time = 30;
+  segment.position = 0;
+
+  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
+          0, &st) == -1);
+  fail_unless_equals_int (st, 20);
+  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
+          20, &st) == 1);
+  fail_unless_equals_int (st, 0);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 0, &pos) == 1);
+  fail_unless_equals_int (pos, 20);
+  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
+          10, &st) == -1);
+  fail_unless_equals_int (st, 10);
+  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
+          40, &st) == 1);
+  fail_unless_equals_int (st, 20);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, st, &pos) == 1);
+  fail_unless_equals_int (pos, 40);
+  segment.time = 100;
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 40, &pos) == -1);
+  fail_unless_equals_int (pos, 10);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 60, &pos) == 1);
+  fail_unless_equals_int (pos, 10);
+
+  segment.start = 50;
+  segment.position = 150;
+  segment.stop = 200;
+  segment.time = 0;
+  segment.applied_rate = -1;
+  segment.rate = -1;
+
+  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
+          0, &st) == 1);
+  fail_unless_equals_int (st, 200);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 200, &pos) == 1);
+  fail_unless_equals_int (pos, 0);
+  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
+          250, &st) == -1);
+  fail_unless_equals_int (st, 50);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 200, &pos) == 1);
+  fail_unless_equals_int (pos, 0);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 250, &pos) == -1);
+  fail_unless_equals_int (pos, 50);
+
+  segment.time = 70;
+  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
+          250, &st) == 1);
+  fail_unless_equals_int (st, 20);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 50, &pos) == 1);
+  fail_unless_equals_int (pos, 220);
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 90, &pos) == 1);
+  fail_unless_equals_int (pos, 180);
+
+  segment.stop = 60;
+  fail_unless (gst_segment_position_from_stream_time_full (&segment,
+          GST_FORMAT_TIME, 5, &pos) == 1);
+  fail_unless_equals_int (pos, 125);
 }
 
 GST_END_TEST;
 
-/* mess with the segment structure in the time format */
-GST_START_TEST (segment_newsegment_accum2)
+GST_START_TEST (segment_negative_rate)
 {
   GstSegment segment;
-  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  /***************************
-   * Normal reverse segment
-   ***************************/
-  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 0);
-
-  fail_unless (segment.rate == -1.0);
-  fail_unless (segment.applied_rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 200);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 0);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 200);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 50);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 150);
-
-  /* close segment, this accumulates nothing. */
-  gst_segment_set_newsegment (&segment, TRUE, -1.0, 1.0,
-      GST_FORMAT_TIME, 150, 200, 0);
-
-  fail_unless (segment.rate == -1.0);
-  fail_unless (segment.applied_rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 150);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.position == 200);
-  fail_unless (segment.duration == -1);
-
-  /* new segment, this accumulates 50. */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
-      GST_FORMAT_TIME, 150, 300, 150);
-
-  fail_unless (segment.rate == 1.0);
-  fail_unless (segment.applied_rate == 1.0);
-  fail_unless (segment.format == GST_FORMAT_TIME);
-  fail_unless (segment.flags == 0);
-  fail_unless (segment.start == 150);
-  fail_unless (segment.stop == 300);
-  fail_unless (segment.time == 150);
-  fail_unless (segment.base == 50);
-  fail_unless (segment.position == 150);
-  fail_unless (segment.duration == -1);
-
-  /* invalid time gives invalid result */
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
-  fail_unless (result == -1);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
-  fail_unless (result == 50);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 150);
-
-  result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
-  fail_unless (result == 100);
-  result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
-  fail_unless (result == 200);
+  segment.start = 50;
+  segment.position = 150;
+  segment.stop = 200;
+  segment.time = 0;
+  segment.applied_rate = -1;
+  segment.rate = -1;
+
+  /* somewhere in the middle */
+  check_times (&segment, 100, 100, 100);
+  /* after stop */
+  check_times (&segment, 220, -1, -1);
+  /* before start */
+  check_times (&segment, 10, -1, -1);
+  /* at segment start */
+  check_times (&segment, 50, 150, 150);
+  /* another place in the middle */
+  check_times (&segment, 150, 50, 50);
+  /* at segment stop */
+  check_times (&segment, 200, 0, 0);
+
+  segment.time = 100;
+  segment.base = 100;
+  /* somewhere in the middle */
+  check_times (&segment, 100, 200, 200);
+  /* at segment start */
+  check_times (&segment, 50, 250, 250);
+  /* another place in the middle */
+  check_times (&segment, 150, 150, 150);
+  /* at segment stop */
+  check_times (&segment, 200, 100, 100);
 }
 
 GST_END_TEST;
-#endif
 
-GST_START_TEST (segment_copy)
+GST_START_TEST (segment_negative_applied_rate)
 {
-  GstSegment *copy;
-  GstSegment segment = { 0.0, };
-
-  /* this is a boxed type copy function, we support copying NULL */
-  fail_unless (gst_segment_copy (NULL) == NULL);
+  GstSegment segment;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  segment.rate = -1.0;
-  segment.applied_rate = 1.0;
-  segment.start = 0;
+  segment.start = 50;
+  segment.position = 150;
   segment.stop = 200;
   segment.time = 0;
-
-  copy = gst_segment_copy (&segment);
-  fail_unless (copy != NULL);
-  /* we inited the struct on the stack to zeroes, so direct comparison should
-   * be ok here despite the padding field and regardless of implementation */
-  fail_unless (memcmp (copy, &segment, sizeof (GstSegment)) == 0);
-  gst_segment_free (copy);
+  segment.applied_rate = -1;
+  segment.rate = 1;
+
+  /* somewhere in the middle */
+  check_times (&segment, 100, 100, 50);
+  /* after stop */
+  check_times (&segment, 220, -1, -1);
+  /* before start */
+  check_times (&segment, 10, -1, -1);
+  /* at segment start */
+  check_times (&segment, 50, 150, 0);
+  /* another place in the middle */
+  check_times (&segment, 150, 50, 100);
+  /* at segment stop */
+  check_times (&segment, 200, 0, 150);
+
+  segment.time = 100;
+  segment.base = 100;
+  /* somewhere in the middle */
+  check_times (&segment, 100, 200, 150);
+  /* at segment start */
+  check_times (&segment, 50, 250, 100);
+  /* another place in the middle */
+  check_times (&segment, 150, 150, 200);
+  /* at segment stop */
+  check_times (&segment, 200, 100, 250);
 }
 
 GST_END_TEST;
@@ -1761,18 +1145,13 @@ gst_segment_suite (void)
   tcase_add_test (tc_chain, segment_seek_size);
   tcase_add_test (tc_chain, segment_seek_reverse);
   tcase_add_test (tc_chain, segment_seek_rate);
-#if 0
-  tcase_add_test (tc_chain, segment_newsegment_open);
-  tcase_add_test (tc_chain, segment_newsegment_closed);
-  tcase_add_test (tc_chain, segment_newsegment_streamtime);
-  tcase_add_test (tc_chain, segment_newsegment_streamtime_rate);
-  tcase_add_test (tc_chain, segment_newsegment_streamtime_applied_rate);
-  tcase_add_test (tc_chain, segment_newsegment_streamtime_applied_rate_rate);
-  tcase_add_test (tc_chain, segment_newsegment_runningtime);
-  tcase_add_test (tc_chain, segment_newsegment_accum);
-  tcase_add_test (tc_chain, segment_newsegment_accum2);
-#endif
   tcase_add_test (tc_chain, segment_copy);
+  tcase_add_test (tc_chain, segment_seek_noupdate);
+  tcase_add_test (tc_chain, segment_offset);
+  tcase_add_test (tc_chain, segment_full);
+  tcase_add_test (tc_chain, segment_negative_rate);
+  tcase_add_test (tc_chain, segment_negative_applied_rate);
+  tcase_add_test (tc_chain, segment_stream_time_full);
 
   return s;
 }