segment: add helper to get negative running-time
[platform/upstream/gstreamer.git] / tests / check / gst / gstsegment.c
1 /* GStreamer
2  * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
3  *               2009 Wim Taymans <wim.taymans@gmail.com>
4  *
5  * gstsegment.c: Unit test for segments
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 static void
26 check_times (GstSegment * segment, guint64 position, guint64 stream_time,
27     guint64 running_time)
28 {
29   guint64 st, rt;
30
31   st = gst_segment_to_stream_time (segment, segment->format, position);
32   rt = gst_segment_to_running_time (segment, segment->format, position);
33   GST_DEBUG ("position %" G_GUINT64_FORMAT ", st %" G_GUINT64_FORMAT ", rt %"
34       G_GUINT64_FORMAT, position, stream_time, running_time);
35
36   fail_unless_equals_int64 (st, stream_time);
37   fail_unless_equals_int64 (rt, running_time);
38 }
39
40 /* mess with the segment structure in the bytes format */
41 GST_START_TEST (segment_seek_nosize)
42 {
43   GstSegment segment;
44   gboolean res;
45   guint64 cstart, cstop;
46   gboolean update;
47
48   gst_segment_init (&segment, GST_FORMAT_BYTES);
49
50   /* configure segment to start 100 */
51   gst_segment_do_seek (&segment, 1.0,
52       GST_FORMAT_BYTES,
53       GST_SEEK_FLAG_NONE,
54       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
55   fail_unless (segment.start == 100);
56   fail_unless (segment.position == 100);
57   fail_unless (segment.stop == -1);
58   fail_unless (update == TRUE);
59   /* appended after current position 0 */
60   check_times (&segment, 100, 100, 0);
61
62   /* do some clipping on the open range */
63   /* completely outside */
64   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
65   fail_unless (res == FALSE);
66
67   /* touching lower bound, still outside of the segment */
68   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
69   fail_unless (res == FALSE);
70
71   /* partially inside */
72   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
73   fail_unless (res == TRUE);
74   fail_unless (cstart == 100);
75   fail_unless (cstop == 150);
76
77   /* inside, touching lower bound */
78   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
79       100, 150, &cstart, &cstop);
80   fail_unless (res == TRUE);
81   fail_unless (cstart == 100);
82   fail_unless (cstop == 150);
83
84   /* special case, 0 duration and outside segment */
85   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 90, 90, &cstart, &cstop);
86   fail_unless (res == FALSE);
87
88   /* special case, 0 duration and touching lower bound, i.e. inside segment */
89   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
90       100, 100, &cstart, &cstop);
91   fail_unless (res == TRUE);
92   fail_unless (cstart == 100);
93   fail_unless (cstop == 100);
94
95   /* special case, 0 duration and inside the segment */
96   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
97       120, 120, &cstart, &cstop);
98   fail_unless (res == TRUE);
99   fail_unless (cstart == 120);
100   fail_unless (cstop == 120);
101
102   /* completely inside */
103   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
104       150, 200, &cstart, &cstop);
105   fail_unless (res == TRUE);
106   fail_unless (cstart == 150);
107   fail_unless (cstop == 200);
108
109   /* invalid start */
110   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
111   fail_unless (res == FALSE);
112
113   /* start outside, we don't know the stop */
114   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
115   fail_unless (res == TRUE);
116   fail_unless (cstart == 100);
117   fail_unless (cstop == -1);
118
119   /* start on lower bound */
120   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
121   fail_unless (res == TRUE);
122   fail_unless (cstart == 100);
123   fail_unless (cstop == -1);
124
125   /* start inside */
126   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
127   fail_unless (res == TRUE);
128   fail_unless (cstart == 150);
129   fail_unless (cstop == -1);
130
131   /* move to 150, this is a running_time of 50 */
132   segment.position = 150;
133   check_times (&segment, 150, 150, 50);
134
135   /* add 100 to start, set stop to 300 */
136   gst_segment_do_seek (&segment, 1.0,
137       GST_FORMAT_BYTES,
138       GST_SEEK_FLAG_NONE,
139       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
140   fail_unless (segment.start == 200);
141   fail_unless (segment.position == 200);
142   fail_unless (segment.stop == 300);
143   fail_unless (segment.base == 50);
144   fail_unless (update == TRUE);
145   check_times (&segment, 200, 200, 50);
146   check_times (&segment, 250, 250, 100);
147
148   update = FALSE;
149   /* add 100 to start (to 300), set stop to 200, this is not allowed.
150    * nothing should be updated in the segment. A g_warning is
151    * emitted. */
152   ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
153           GST_FORMAT_BYTES,
154           GST_SEEK_FLAG_NONE,
155           GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update));
156   fail_unless (segment.start == 200);
157   fail_unless (segment.position == 200);
158   fail_unless (segment.stop == 300);
159   fail_unless (segment.base == 50);
160   /* update didn't change */
161   fail_unless (update == FALSE);
162   check_times (&segment, 200, 200, 50);
163   check_times (&segment, 250, 250, 100);
164
165   update = TRUE;
166   /* seek relative to end, should not do anything since size is
167    * unknown. */
168   gst_segment_do_seek (&segment, 1.0,
169       GST_FORMAT_BYTES,
170       GST_SEEK_FLAG_NONE,
171       GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
172   fail_unless (segment.start == 200);
173   fail_unless (segment.position == 200);
174   fail_unless (segment.stop == 300);
175   fail_unless (segment.base == 50);
176   fail_unless (update == FALSE);
177   check_times (&segment, 250, 250, 100);
178
179   /* completely outside */
180   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
181   fail_unless (res == FALSE);
182
183   /* touching lower bound */
184   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 200, &cstart, &cstop);
185   fail_unless (res == FALSE);
186
187   /* partially inside */
188   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 250, &cstart, &cstop);
189   fail_unless (res == TRUE);
190   fail_unless (cstart == 200);
191   fail_unless (cstop == 250);
192
193   /* inside, touching lower bound */
194   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
195       200, 250, &cstart, &cstop);
196   fail_unless (res == TRUE);
197   fail_unless (cstart == 200);
198   fail_unless (cstop == 250);
199
200   /* completely inside */
201   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
202       250, 290, &cstart, &cstop);
203   fail_unless (res == TRUE);
204   fail_unless (cstart == 250);
205   fail_unless (cstop == 290);
206
207   /* partially inside */
208   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
209       250, 350, &cstart, &cstop);
210   fail_unless (res == TRUE);
211   fail_unless (cstart == 250);
212   fail_unless (cstop == 300);
213
214   /* invalid start */
215   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
216   fail_unless (res == FALSE);
217
218   /* start outside */
219   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
220   fail_unless (res == TRUE);
221   fail_unless (cstart == 200);
222   fail_unless (cstop == 300);
223
224   /* start on lower bound */
225   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
226   fail_unless (res == TRUE);
227   fail_unless (cstart == 200);
228   fail_unless (cstop == 300);
229
230   /* start inside */
231   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
232   fail_unless (res == TRUE);
233   fail_unless (cstart == 250);
234   fail_unless (cstop == 300);
235
236   /* start outside on boundary */
237   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
238   fail_unless (res == FALSE);
239
240   /* start completely outside */
241   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 350, -1, &cstart, &cstop);
242   fail_unless (res == FALSE);
243 }
244
245 GST_END_TEST;
246
247 /* mess with the segment structure in the bytes format */
248 GST_START_TEST (segment_seek_size)
249 {
250   GstSegment segment;
251   gboolean res;
252   guint64 cstart, cstop;
253   gboolean update;
254
255   gst_segment_init (&segment, GST_FORMAT_BYTES);
256   segment.duration = 200;
257
258   /* configure segment to start 100 */
259   gst_segment_do_seek (&segment, 1.0,
260       GST_FORMAT_BYTES,
261       GST_SEEK_FLAG_NONE,
262       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
263   fail_unless (segment.start == 100);
264   fail_unless (segment.position == 100);
265   fail_unless (segment.stop == -1);
266   fail_unless (update == TRUE);
267   check_times (&segment, 100, 100, 0);
268
269   /* do some clipping on the open range */
270   /* completely outside */
271   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
272   fail_unless (res == FALSE);
273
274   /* touching lower bound */
275   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
276   fail_unless (res == FALSE);
277
278   /* partially inside */
279   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
280   fail_unless (res == TRUE);
281   fail_unless (cstart == 100);
282   fail_unless (cstop == 150);
283
284   /* inside, touching lower bound */
285   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
286       100, 150, &cstart, &cstop);
287   fail_unless (res == TRUE);
288   fail_unless (cstart == 100);
289   fail_unless (cstop == 150);
290
291   /* completely inside */
292   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
293       150, 200, &cstart, &cstop);
294   fail_unless (res == TRUE);
295   fail_unless (cstart == 150);
296   fail_unless (cstop == 200);
297
298   /* invalid start */
299   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
300   fail_unless (res == FALSE);
301
302   /* start outside */
303   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
304   fail_unless (res == TRUE);
305   fail_unless (cstart == 100);
306   fail_unless (cstop == -1);
307
308   /* start on lower bound */
309   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
310   fail_unless (res == TRUE);
311   fail_unless (cstart == 100);
312   fail_unless (cstop == -1);
313
314   /* start inside */
315   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
316   fail_unless (res == TRUE);
317   fail_unless (cstart == 150);
318   fail_unless (cstop == -1);
319
320   /* add 100 to start, set stop to 300, stop clips to 200 */
321   gst_segment_do_seek (&segment, 1.0,
322       GST_FORMAT_BYTES,
323       GST_SEEK_FLAG_NONE,
324       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
325   fail_unless (segment.start == 200);
326   fail_unless (segment.position == 200);
327   fail_unless (segment.stop == 200);
328   check_times (&segment, 200, 200, 0);
329
330   /* add 100 to start (to 300), set stop to 200, this clips start
331    * to duration */
332   gst_segment_do_seek (&segment, 1.0,
333       GST_FORMAT_BYTES,
334       GST_SEEK_FLAG_NONE,
335       GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update);
336   fail_unless (segment.start == 200);
337   fail_unless (segment.position == 200);
338   fail_unless (segment.stop == 200);
339   fail_unless (update == FALSE);
340   check_times (&segment, 200, 200, 0);
341
342   /* seek relative to end */
343   gst_segment_do_seek (&segment, 1.0,
344       GST_FORMAT_BYTES,
345       GST_SEEK_FLAG_NONE,
346       GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
347   fail_unless (segment.start == 100);
348   fail_unless (segment.position == 100);
349   fail_unless (segment.stop == 180);
350   fail_unless (update == TRUE);
351   check_times (&segment, 150, 150, 50);
352
353   /* completely outside */
354   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
355   fail_unless (res == FALSE);
356
357   /* touching lower bound */
358   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
359   fail_unless (res == FALSE);
360
361   /* partially inside */
362   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
363   fail_unless (res == TRUE);
364   fail_unless (cstart == 100);
365   fail_unless (cstop == 150);
366
367   /* inside, touching lower bound */
368   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
369       100, 150, &cstart, &cstop);
370   fail_unless (res == TRUE);
371   fail_unless (cstart == 100);
372   fail_unless (cstop == 150);
373
374   /* completely inside */
375   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
376       150, 170, &cstart, &cstop);
377   fail_unless (res == TRUE);
378   fail_unless (cstart == 150);
379   fail_unless (cstop == 170);
380
381   /* partially inside */
382   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
383       150, 250, &cstart, &cstop);
384   fail_unless (res == TRUE);
385   fail_unless (cstart == 150);
386   fail_unless (cstop == 180);
387
388   /* invalid start */
389   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
390   fail_unless (res == FALSE);
391
392   /* start outside */
393   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
394   fail_unless (res == TRUE);
395   fail_unless (cstart == 100);
396   fail_unless (cstop == 180);
397
398   /* start on lower bound */
399   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
400   fail_unless (res == TRUE);
401   fail_unless (cstart == 100);
402   fail_unless (cstop == 180);
403
404   /* start inside */
405   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
406   fail_unless (res == TRUE);
407   fail_unless (cstart == 150);
408   fail_unless (cstop == 180);
409
410   /* start outside on boundary */
411   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
412   fail_unless (res == FALSE);
413
414   /* start completely outside */
415   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
416   fail_unless (res == FALSE);
417 }
418
419 GST_END_TEST;
420
421 GST_START_TEST (segment_seek_reverse)
422 {
423   GstSegment segment;
424   gboolean update;
425
426   gst_segment_init (&segment, GST_FORMAT_BYTES);
427   segment.duration = 200;
428
429   /* configure segment to stop 100 */
430   gst_segment_do_seek (&segment, -1.0,
431       GST_FORMAT_BYTES,
432       GST_SEEK_FLAG_NONE,
433       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
434   fail_unless (segment.start == 0);
435   fail_unless (segment.stop == 100);
436   fail_unless (segment.time == 0);
437   fail_unless (segment.position == 100);
438   fail_unless (update == TRUE);
439   check_times (&segment, 100, 100, 0);
440   check_times (&segment, 50, 50, 50);
441   check_times (&segment, 0, 0, 100);
442
443   /* update */
444   gst_segment_do_seek (&segment, -1.0,
445       GST_FORMAT_BYTES,
446       GST_SEEK_FLAG_NONE,
447       GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_SET, 100 - 20, &update);
448   fail_unless (segment.start == 10);
449   fail_unless (segment.stop == 80);
450   fail_unless (segment.time == 10);
451   fail_unless (segment.position == 80);
452   fail_unless (update == TRUE);
453   check_times (&segment, 80, 80, 0);
454   check_times (&segment, 40, 40, 40);
455   check_times (&segment, 10, 10, 70);
456
457   gst_segment_do_seek (&segment, -1.0,
458       GST_FORMAT_BYTES,
459       GST_SEEK_FLAG_NONE,
460       GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
461   fail_unless (segment.start == 20);
462   fail_unless (segment.stop == 80);
463   fail_unless (segment.time == 20);
464   fail_unless (segment.position == 80);
465   fail_unless (update == FALSE);
466   check_times (&segment, 80, 80, 0);
467   check_times (&segment, 20, 20, 60);
468 }
469
470 GST_END_TEST;
471
472 /* mess with the segment structure in the bytes format */
473 GST_START_TEST (segment_seek_rate)
474 {
475   GstSegment segment;
476   gboolean update;
477
478   gst_segment_init (&segment, GST_FORMAT_BYTES);
479
480   /* configure segment to rate 2.0 */
481   gst_segment_do_seek (&segment, 2.0,
482       GST_FORMAT_BYTES,
483       GST_SEEK_FLAG_NONE,
484       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
485   fail_unless (segment.format == GST_FORMAT_BYTES);
486   fail_unless (segment.start == 0);
487   fail_unless (segment.position == 0);
488   fail_unless (segment.stop == -1);
489   fail_unless (segment.rate == 2.0);
490   fail_unless (update == FALSE);
491   check_times (&segment, 50, 50, 25);
492
493   /* set a real stop position, this must happen in bytes */
494   gst_segment_do_seek (&segment, 3.0,
495       GST_FORMAT_BYTES,
496       GST_SEEK_FLAG_NONE,
497       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
498   fail_unless (segment.format == GST_FORMAT_BYTES);
499   fail_unless (segment.start == 0);
500   fail_unless (segment.stop == 100);
501   fail_unless (segment.rate == 3.0);
502   /* no seek should happen, we just updated the stop position in forward
503    * playback mode.*/
504   fail_unless (update == FALSE);
505   check_times (&segment, 60, 60, 20);
506
507   /* set some duration, stop -1 END seeks will now work with the
508    * duration, if the formats match */
509   segment.duration = 200;
510   fail_unless (segment.duration == 200);
511
512   /* seek to end with 0 should set the stop to the duration */
513   gst_segment_do_seek (&segment, 2.0,
514       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
515       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
516   fail_unless (segment.stop == 200);
517   fail_unless (segment.duration == 200);
518
519   /* subtract 100 from the end */
520   gst_segment_do_seek (&segment, 2.0,
521       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
522       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
523   fail_unless (segment.stop == 100);
524   fail_unless (segment.duration == 200);
525
526   /* add 100 to the duration, this should be clamped to the duration */
527   gst_segment_do_seek (&segment, 2.0,
528       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
529       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
530   fail_unless (segment.stop == 200);
531   fail_unless (segment.duration == 200);
532 }
533
534 GST_END_TEST;
535
536 GST_START_TEST (segment_copy)
537 {
538   GstSegment *copy;
539   GstSegment segment = { 0.0, };
540
541   /* this is a boxed type copy function, we support copying NULL */
542   fail_unless (gst_segment_copy (NULL) == NULL);
543
544   gst_segment_init (&segment, GST_FORMAT_TIME);
545
546   segment.rate = -1.0;
547   segment.applied_rate = 1.0;
548   segment.start = 0;
549   segment.stop = 200;
550   segment.time = 0;
551
552   copy = gst_segment_copy (&segment);
553   fail_unless (copy != NULL);
554   /* we inited the struct on the stack to zeroes, so direct comparison should
555    * be ok here despite the padding field and regardless of implementation */
556   fail_unless (memcmp (copy, &segment, sizeof (GstSegment)) == 0);
557   gst_segment_free (copy);
558 }
559
560 GST_END_TEST;
561
562 /* mess with the segment structure in the bytes format */
563 GST_START_TEST (segment_seek_noupdate)
564 {
565   GstSegment segment;
566   gboolean update;
567
568   gst_segment_init (&segment, GST_FORMAT_TIME);
569
570   segment.start = 0;
571   segment.position = 50;
572   segment.stop = 200;
573   segment.time = 0;
574
575   /* doesn't change anything */
576   gst_segment_do_seek (&segment, 1.0,
577       GST_FORMAT_TIME,
578       GST_SEEK_FLAG_NONE,
579       GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
580   fail_unless (update == FALSE);
581   fail_unless (segment.format == GST_FORMAT_TIME);
582   fail_unless (segment.start == 0);
583   fail_unless (segment.stop == 200);
584   fail_unless (segment.time == 0);
585   fail_unless (segment.position == 50);
586   fail_unless (segment.base == 50);
587   fail_unless (segment.offset == 50);
588
589   gst_segment_do_seek (&segment, 2.0,
590       GST_FORMAT_TIME,
591       GST_SEEK_FLAG_NONE,
592       GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
593   fail_unless (update == FALSE);
594   fail_unless (segment.format == GST_FORMAT_TIME);
595   fail_unless (segment.start == 0);
596   fail_unless (segment.stop == 200);
597   fail_unless (segment.time == 0);
598   fail_unless (segment.position == 50);
599   fail_unless (segment.base == 50);
600   fail_unless_equals_int (segment.offset, 50);
601
602   gst_segment_do_seek (&segment, 1.0,
603       GST_FORMAT_TIME,
604       GST_SEEK_FLAG_FLUSH,
605       GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
606   fail_unless (update == FALSE);
607   fail_unless (segment.format == GST_FORMAT_TIME);
608   fail_unless (segment.start == 0);
609   fail_unless (segment.stop == 200);
610   fail_unless (segment.time == 0);
611   fail_unless (segment.position == 50);
612   fail_unless (segment.base == 0);
613   fail_unless (segment.offset == 50);
614 }
615
616 GST_END_TEST;
617
618 GST_START_TEST (segment_offset)
619 {
620   GstSegment segment;
621
622   gst_segment_init (&segment, GST_FORMAT_TIME);
623
624   segment.start = 0;
625   segment.position = 50;
626   segment.stop = 200;
627   segment.time = 0;
628
629   check_times (&segment, 20, 20, 20);
630   check_times (&segment, 220, -1, -1);
631
632   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
633           0) == TRUE);
634   fail_unless (segment.start == 0);
635   fail_unless (segment.stop == 200);
636   fail_unless (segment.time == 0);
637   fail_unless (segment.position == 50);
638   fail_unless (segment.base == 0);
639   fail_unless (segment.offset == 0);
640   check_times (&segment, 20, 20, 20);
641
642   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
643           100) == TRUE);
644   fail_unless (segment.start == 0);
645   fail_unless (segment.stop == 200);
646   fail_unless (segment.time == 0);
647   fail_unless (segment.position == 50);
648   fail_unless (segment.base == 100);
649   fail_unless (segment.offset == 0);
650   check_times (&segment, 20, 20, 120);
651
652   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
653           -50) == TRUE);
654   fail_unless (segment.start == 0);
655   fail_unless (segment.stop == 200);
656   fail_unless (segment.time == 0);
657   fail_unless (segment.position == 50);
658   fail_unless (segment.base == 50);
659   fail_unless (segment.offset == 0);
660   check_times (&segment, 20, 20, 70);
661
662   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
663           -100) == TRUE);
664   fail_unless (segment.start == 0);
665   fail_unless (segment.stop == 200);
666   fail_unless (segment.time == 0);
667   fail_unless (segment.position == 50);
668   fail_unless (segment.base == 0);
669   fail_unless (segment.offset == 50);
670   check_times (&segment, 20, 20, -1);
671   check_times (&segment, 200, 200, 150);
672
673   /* can go negative */
674   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
675           -151) == FALSE);
676   fail_unless (segment.start == 0);
677   fail_unless (segment.stop == 200);
678   fail_unless (segment.time == 0);
679   fail_unless (segment.position == 50);
680   fail_unless (segment.base == 0);
681   fail_unless (segment.offset == 50);
682   check_times (&segment, 100, 100, 50);
683   check_times (&segment, 200, 200, 150);
684
685   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
686           -150) == TRUE);
687   fail_unless (segment.start == 0);
688   fail_unless (segment.stop == 200);
689   fail_unless (segment.time == 0);
690   fail_unless (segment.position == 50);
691   fail_unless (segment.base == 0);
692   fail_unless (segment.offset == 200);
693   check_times (&segment, 200, 200, 0);
694
695   gst_segment_init (&segment, GST_FORMAT_TIME);
696
697   segment.start = 20;
698   segment.position = 50;
699   segment.stop = 220;
700   segment.time = 0;
701
702   check_times (&segment, 40, 20, 20);
703   check_times (&segment, 240, -1, -1);
704
705   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
706           0) == TRUE);
707   fail_unless (segment.start == 20);
708   fail_unless (segment.stop == 220);
709   fail_unless (segment.time == 0);
710   fail_unless (segment.position == 50);
711   fail_unless (segment.base == 0);
712   fail_unless (segment.offset == 0);
713   check_times (&segment, 40, 20, 20);
714
715   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
716           100) == TRUE);
717   fail_unless (segment.start == 20);
718   fail_unless (segment.stop == 220);
719   fail_unless (segment.time == 0);
720   fail_unless (segment.position == 50);
721   fail_unless (segment.base == 100);
722   fail_unless (segment.offset == 0);
723   check_times (&segment, 40, 20, 120);
724
725   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
726           -50) == TRUE);
727   fail_unless (segment.start == 20);
728   fail_unless (segment.stop == 220);
729   fail_unless (segment.time == 0);
730   fail_unless (segment.position == 50);
731   fail_unless (segment.base == 50);
732   fail_unless (segment.offset == 0);
733   check_times (&segment, 40, 20, 70);
734
735   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
736           -100) == TRUE);
737   fail_unless (segment.start == 20);
738   fail_unless (segment.stop == 220);
739   fail_unless (segment.time == 0);
740   fail_unless (segment.position == 50);
741   fail_unless (segment.base == 0);
742   fail_unless (segment.offset == 50);
743   check_times (&segment, 40, 20, -1);
744   check_times (&segment, 220, 200, 150);
745 }
746
747 GST_END_TEST;
748
749 GST_START_TEST (segment_full)
750 {
751   GstSegment segment;
752   guint64 rt;
753
754   gst_segment_init (&segment, GST_FORMAT_TIME);
755
756   segment.start = 50;
757   segment.position = 150;
758   segment.stop = 200;
759   segment.time = 0;
760
761   check_times (&segment, 100, 50, 50);
762   check_times (&segment, 220, -1, -1);
763
764   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
765           50, &rt) == GST_SEGMENT_RESULT_OK);
766   fail_unless (rt == 0);
767   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
768           200, &rt) == GST_SEGMENT_RESULT_OK);
769   fail_unless (rt == 150);
770   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
771           40, &rt) == GST_SEGMENT_RESULT_BEFORE);
772   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
773           49, &rt) == GST_SEGMENT_RESULT_BEFORE);
774   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
775           201, &rt) == GST_SEGMENT_RESULT_AFTER);
776
777   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
778           -50) == TRUE);
779   fail_unless (segment.offset == 50);
780
781   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
782           50, &rt) == GST_SEGMENT_RESULT_NEGATIVE);
783   GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
784   fail_unless (rt == 50);
785 }
786
787 GST_END_TEST;
788
789 static Suite *
790 gst_segment_suite (void)
791 {
792   Suite *s = suite_create ("GstSegment");
793   TCase *tc_chain = tcase_create ("segments");
794
795   tcase_set_timeout (tc_chain, 20);
796
797   suite_add_tcase (s, tc_chain);
798   tcase_add_test (tc_chain, segment_seek_nosize);
799   tcase_add_test (tc_chain, segment_seek_size);
800   tcase_add_test (tc_chain, segment_seek_reverse);
801   tcase_add_test (tc_chain, segment_seek_rate);
802   tcase_add_test (tc_chain, segment_copy);
803   tcase_add_test (tc_chain, segment_seek_noupdate);
804   tcase_add_test (tc_chain, segment_offset);
805   tcase_add_test (tc_chain, segment_full);
806
807   return s;
808 }
809
810 GST_CHECK_MAIN (gst_segment);