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