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