gstsegment: Handle positions before the segment properly
[platform/upstream/gstreamer.git] / tests / check / gst / gstsegment.c
index f3433e8..f160462 100644 (file)
@@ -19,6 +19,9 @@
  * 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>
 
@@ -58,9 +61,9 @@ 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.position == 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);
   /* appended after current position 0 */
   check_times (&segment, 100, 100, 0);
@@ -77,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);
@@ -95,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);
@@ -119,20 +122,20 @@ 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;
@@ -143,10 +146,10 @@ GST_START_TEST (segment_seek_nosize)
       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.position == 200);
-  fail_unless (segment.stop == 300);
-  fail_unless (segment.base == 50);
+  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);
@@ -159,10 +162,10 @@ GST_START_TEST (segment_seek_nosize)
           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.position == 200);
-  fail_unless (segment.stop == 300);
-  fail_unless (segment.base == 50);
+  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);
@@ -175,10 +178,10 @@ 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.position == 200);
-  fail_unless (segment.stop == 300);
-  fail_unless (segment.base == 50);
+  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);
 
@@ -193,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);
@@ -224,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);
@@ -266,9 +269,9 @@ 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.position == 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);
 
@@ -284,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);
@@ -308,29 +311,29 @@ 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.position == 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
@@ -339,20 +342,76 @@ 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.position == 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.position == 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);
 
@@ -367,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);
@@ -398,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);
@@ -437,10 +496,10 @@ 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);
@@ -451,10 +510,10 @@ GST_START_TEST (segment_seek_reverse)
       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);
@@ -464,10 +523,10 @@ GST_START_TEST (segment_seek_reverse)
       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);
@@ -489,10 +548,10 @@ 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.position == 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);
   check_times (&segment, 50, 50, 25);
 
@@ -502,9 +561,9 @@ 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);
@@ -513,28 +572,27 @@ GST_START_TEST (segment_seek_rate)
   /* 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);
+  fail_unless_equals_uint64 (segment.stop, 200);
+  fail_unless_equals_uint64 (segment.duration, 200);
 }
 
 GST_END_TEST;
@@ -585,12 +643,12 @@ GST_START_TEST (segment_seek_noupdate)
       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.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 50);
-  fail_unless (segment.offset == 50);
+  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_do_seek (&segment, 2.0,
       GST_FORMAT_TIME,
@@ -598,12 +656,12 @@ GST_START_TEST (segment_seek_noupdate)
       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.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 50);
-  fail_unless_equals_int (segment.offset, 50);
+  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_do_seek (&segment, 1.0,
       GST_FORMAT_TIME,
@@ -611,12 +669,12 @@ GST_START_TEST (segment_seek_noupdate)
       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.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.offset == 50);
+  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;
@@ -637,65 +695,65 @@ GST_START_TEST (segment_offset)
 
   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
           0) == TRUE);
-  fail_unless (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.offset == 0);
+  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 (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 100);
-  fail_unless (segment.offset == 0);
+  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 (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 50);
-  fail_unless (segment.offset == 0);
+  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 (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.offset == 50);
+  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 (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.offset == 50);
+  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 (segment.start == 0);
-  fail_unless (segment.stop == 200);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.offset == 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, 0);
+  fail_unless_equals_uint64 (segment.offset, 200);
   check_times (&segment, 200, 200, 0);
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
@@ -710,42 +768,42 @@ GST_START_TEST (segment_offset)
 
   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
           0) == TRUE);
-  fail_unless (segment.start == 20);
-  fail_unless (segment.stop == 220);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.offset == 0);
+  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 (segment.start == 20);
-  fail_unless (segment.stop == 220);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 100);
-  fail_unless (segment.offset == 0);
+  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 (segment.start == 20);
-  fail_unless (segment.stop == 220);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 50);
-  fail_unless (segment.offset == 0);
+  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 (segment.start == 20);
-  fail_unless (segment.stop == 220);
-  fail_unless (segment.time == 0);
-  fail_unless (segment.position == 50);
-  fail_unless (segment.base == 0);
-  fail_unless (segment.offset == 50);
+  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);
 }
@@ -811,11 +869,105 @@ GST_START_TEST (segment_full)
   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);
+          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;