And correct even more valid sparse warnings.
[platform/upstream/gstreamer.git] / tests / check / gst / gstsegment.c
1 /* GStreamer
2  * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
3  *
4  * gstsegment.c: Unit test for segments
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <gst/check/gstcheck.h>
23
24 /* mess with the segment structure in the bytes format */
25 GST_START_TEST (segment_seek_nosize)
26 {
27   GstSegment segment;
28   gboolean res;
29   gint64 cstart, cstop;
30   gboolean update;
31
32   gst_segment_init (&segment, GST_FORMAT_BYTES);
33
34   /* configure segment to start 100 */
35   gst_segment_set_seek (&segment, 1.0,
36       GST_FORMAT_BYTES,
37       GST_SEEK_FLAG_NONE,
38       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
39   fail_unless (segment.start == 100);
40   fail_unless (segment.stop == -1);
41   fail_unless (update == TRUE);
42
43   /* configure segment to stop relative, should not do anything since 
44    * size is unknown. */
45   gst_segment_set_seek (&segment, 1.0,
46       GST_FORMAT_BYTES,
47       GST_SEEK_FLAG_NONE,
48       GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
49   fail_unless (segment.start == 100);
50   fail_unless (segment.stop == -1);
51   fail_unless (update == FALSE);
52
53   /* do some clipping on the open range */
54   /* completely outside */
55   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
56   fail_unless (res == FALSE);
57
58   /* touching lower bound, still outside of the segment */
59   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
60   fail_unless (res == FALSE);
61
62   /* partially inside */
63   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
64   fail_unless (res == TRUE);
65   fail_unless (cstart == 100);
66   fail_unless (cstop == 150);
67
68   /* inside, touching lower bound */
69   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
70       100, 150, &cstart, &cstop);
71   fail_unless (res == TRUE);
72   fail_unless (cstart == 100);
73   fail_unless (cstop == 150);
74
75   /* special case, 0 duration */
76   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
77       100, 100, &cstart, &cstop);
78   fail_unless (res == TRUE);
79   fail_unless (cstart == 100);
80   fail_unless (cstop == 100);
81
82   /* completely inside */
83   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
84       150, 200, &cstart, &cstop);
85   fail_unless (res == TRUE);
86   fail_unless (cstart == 150);
87   fail_unless (cstop == 200);
88
89   /* invalid start */
90   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
91   fail_unless (res == FALSE);
92
93   /* start outside, we don't know the stop */
94   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
95   fail_unless (res == TRUE);
96   fail_unless (cstart == 100);
97   fail_unless (cstop == -1);
98
99   /* start on lower bound */
100   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
101   fail_unless (res == TRUE);
102   fail_unless (cstart == 100);
103   fail_unless (cstop == -1);
104
105   /* start inside */
106   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
107   fail_unless (res == TRUE);
108   fail_unless (cstart == 150);
109   fail_unless (cstop == -1);
110
111   /* add 100 to start, set stop to 300 */
112   gst_segment_set_seek (&segment, 1.0,
113       GST_FORMAT_BYTES,
114       GST_SEEK_FLAG_NONE,
115       GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
116   fail_unless (segment.start == 200);
117   fail_unless (segment.stop == 300);
118   fail_unless (update == TRUE);
119
120   update = FALSE;
121   /* add 100 to start (to 300), set stop to 200, this is not allowed. 
122    * nothing should be updated in the segment. A g_warning is
123    * emited. */
124   ASSERT_CRITICAL (gst_segment_set_seek (&segment, 1.0,
125           GST_FORMAT_BYTES,
126           GST_SEEK_FLAG_NONE,
127           GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update));
128   fail_unless (segment.start == 200);
129   fail_unless (segment.stop == 300);
130   /* update didn't change */
131   fail_unless (update == FALSE);
132
133   update = TRUE;
134   /* seek relative to end, should not do anything since size is
135    * unknown. */
136   gst_segment_set_seek (&segment, 1.0,
137       GST_FORMAT_BYTES,
138       GST_SEEK_FLAG_NONE,
139       GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
140   fail_unless (segment.start == 200);
141   fail_unless (segment.stop == 300);
142   fail_unless (update == FALSE);
143
144   /* completely outside */
145   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
146   fail_unless (res == FALSE);
147
148   /* touching lower bound */
149   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 200, &cstart, &cstop);
150   fail_unless (res == FALSE);
151
152   /* partially inside */
153   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 250, &cstart, &cstop);
154   fail_unless (res == TRUE);
155   fail_unless (cstart == 200);
156   fail_unless (cstop == 250);
157
158   /* inside, touching lower bound */
159   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
160       200, 250, &cstart, &cstop);
161   fail_unless (res == TRUE);
162   fail_unless (cstart == 200);
163   fail_unless (cstop == 250);
164
165   /* completely inside */
166   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
167       250, 290, &cstart, &cstop);
168   fail_unless (res == TRUE);
169   fail_unless (cstart == 250);
170   fail_unless (cstop == 290);
171
172   /* partially inside */
173   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
174       250, 350, &cstart, &cstop);
175   fail_unless (res == TRUE);
176   fail_unless (cstart == 250);
177   fail_unless (cstop == 300);
178
179   /* invalid start */
180   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
181   fail_unless (res == FALSE);
182
183   /* start outside */
184   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
185   fail_unless (res == TRUE);
186   fail_unless (cstart == 200);
187   fail_unless (cstop == 300);
188
189   /* start on lower bound */
190   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
191   fail_unless (res == TRUE);
192   fail_unless (cstart == 200);
193   fail_unless (cstop == 300);
194
195   /* start inside */
196   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
197   fail_unless (res == TRUE);
198   fail_unless (cstart == 250);
199   fail_unless (cstop == 300);
200
201   /* start outside on boundary */
202   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
203   fail_unless (res == FALSE);
204
205   /* start completely outside */
206   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 350, -1, &cstart, &cstop);
207   fail_unless (res == FALSE);
208 }
209
210 GST_END_TEST;
211
212 /* mess with the segment structure in the bytes format */
213 GST_START_TEST (segment_seek_size)
214 {
215   GstSegment segment;
216   gboolean res;
217   gint64 cstart, cstop;
218   gboolean update;
219
220   gst_segment_init (&segment, GST_FORMAT_BYTES);
221   gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
222
223   /* configure segment to start 100 */
224   gst_segment_set_seek (&segment, 1.0,
225       GST_FORMAT_BYTES,
226       GST_SEEK_FLAG_NONE,
227       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
228   fail_unless (segment.start == 100);
229   fail_unless (segment.stop == -1);
230   fail_unless (update == TRUE);
231
232   /* configure segment to stop relative, does not update stop
233    * since we did not set it before. */
234   gst_segment_set_seek (&segment, 1.0,
235       GST_FORMAT_BYTES,
236       GST_SEEK_FLAG_NONE,
237       GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
238   fail_unless (segment.start == 100);
239   fail_unless (segment.stop == -1);
240   fail_unless (update == FALSE);
241
242   /* do some clipping on the open range */
243   /* completely outside */
244   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
245   fail_unless (res == FALSE);
246
247   /* touching lower bound */
248   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
249   fail_unless (res == FALSE);
250
251   /* partially inside */
252   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
253   fail_unless (res == TRUE);
254   fail_unless (cstart == 100);
255   fail_unless (cstop == 150);
256
257   /* inside, touching lower bound */
258   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
259       100, 150, &cstart, &cstop);
260   fail_unless (res == TRUE);
261   fail_unless (cstart == 100);
262   fail_unless (cstop == 150);
263
264   /* completely inside */
265   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
266       150, 200, &cstart, &cstop);
267   fail_unless (res == TRUE);
268   fail_unless (cstart == 150);
269   fail_unless (cstop == 200);
270
271   /* partially inside, clip to size */
272   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
273       150, 300, &cstart, &cstop);
274   fail_unless (res == TRUE);
275   fail_unless (cstart == 150);
276   fail_unless (cstop == 200);
277
278   /* invalid start */
279   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
280   fail_unless (res == FALSE);
281
282   /* start outside */
283   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
284   fail_unless (res == TRUE);
285   fail_unless (cstart == 100);
286   fail_unless (cstop == -1);
287
288   /* start on lower bound */
289   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
290   fail_unless (res == TRUE);
291   fail_unless (cstart == 100);
292   fail_unless (cstop == -1);
293
294   /* start inside */
295   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
296   fail_unless (res == TRUE);
297   fail_unless (cstart == 150);
298   fail_unless (cstop == -1);
299
300   /* add 100 to start, set stop to 300, stop clips to 200 */
301   gst_segment_set_seek (&segment, 1.0,
302       GST_FORMAT_BYTES,
303       GST_SEEK_FLAG_NONE,
304       GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
305   fail_unless (segment.start == 200);
306   fail_unless (segment.stop == 200);
307
308   /* add 100 to start (to 300), set stop to 200, this clips start
309    * to duration */
310   gst_segment_set_seek (&segment, 1.0,
311       GST_FORMAT_BYTES,
312       GST_SEEK_FLAG_NONE,
313       GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update);
314   fail_unless (segment.start == 200);
315   fail_unless (segment.stop == 200);
316   fail_unless (update == FALSE);
317
318   /* seek relative to end */
319   gst_segment_set_seek (&segment, 1.0,
320       GST_FORMAT_BYTES,
321       GST_SEEK_FLAG_NONE,
322       GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
323   fail_unless (segment.start == 100);
324   fail_unless (segment.stop == 180);
325   fail_unless (update == TRUE);
326
327   /* completely outside */
328   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
329   fail_unless (res == FALSE);
330
331   /* touching lower bound */
332   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
333   fail_unless (res == FALSE);
334
335   /* partially inside */
336   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
337   fail_unless (res == TRUE);
338   fail_unless (cstart == 100);
339   fail_unless (cstop == 150);
340
341   /* inside, touching lower bound */
342   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
343       100, 150, &cstart, &cstop);
344   fail_unless (res == TRUE);
345   fail_unless (cstart == 100);
346   fail_unless (cstop == 150);
347
348   /* completely inside */
349   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
350       150, 170, &cstart, &cstop);
351   fail_unless (res == TRUE);
352   fail_unless (cstart == 150);
353   fail_unless (cstop == 170);
354
355   /* partially inside */
356   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
357       150, 250, &cstart, &cstop);
358   fail_unless (res == TRUE);
359   fail_unless (cstart == 150);
360   fail_unless (cstop == 180);
361
362   /* invalid start */
363   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
364   fail_unless (res == FALSE);
365
366   /* start outside */
367   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
368   fail_unless (res == TRUE);
369   fail_unless (cstart == 100);
370   fail_unless (cstop == 180);
371
372   /* start on lower bound */
373   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
374   fail_unless (res == TRUE);
375   fail_unless (cstart == 100);
376   fail_unless (cstop == 180);
377
378   /* start inside */
379   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
380   fail_unless (res == TRUE);
381   fail_unless (cstart == 150);
382   fail_unless (cstop == 180);
383
384   /* start outside on boundary */
385   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
386   fail_unless (res == FALSE);
387
388   /* start completely outside */
389   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
390   fail_unless (res == FALSE);
391 }
392
393 GST_END_TEST;
394
395 GST_START_TEST (segment_seek_reverse)
396 {
397   GstSegment segment;
398   gboolean update;
399
400   gst_segment_init (&segment, GST_FORMAT_BYTES);
401   gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
402
403   /* configure segment to stop 100 */
404   gst_segment_set_seek (&segment, -1.0,
405       GST_FORMAT_BYTES,
406       GST_SEEK_FLAG_NONE,
407       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
408   fail_unless (segment.start == 0);
409   fail_unless (segment.stop == 100);
410   fail_unless (segment.time == 0);
411   fail_unless (segment.last_stop == 100);
412   fail_unless (update == TRUE);
413
414   /* update */
415   gst_segment_set_seek (&segment, -1.0,
416       GST_FORMAT_BYTES,
417       GST_SEEK_FLAG_NONE,
418       GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_CUR, -20, &update);
419   fail_unless (segment.start == 10);
420   fail_unless (segment.stop == 80);
421   fail_unless (segment.time == 10);
422   fail_unless (segment.last_stop == 80);
423   fail_unless (update == TRUE);
424
425   gst_segment_set_seek (&segment, -1.0,
426       GST_FORMAT_BYTES,
427       GST_SEEK_FLAG_NONE,
428       GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
429   fail_unless (segment.start == 20);
430   fail_unless (segment.stop == 80);
431   fail_unless (segment.time == 20);
432   fail_unless (segment.last_stop == 80);
433   fail_unless (update == FALSE);
434 }
435
436 GST_END_TEST;
437
438 /* mess with the segment structure in the bytes format */
439 GST_START_TEST (segment_seek_rate)
440 {
441   GstSegment segment;
442   gboolean update;
443
444   gst_segment_init (&segment, GST_FORMAT_BYTES);
445
446   /* configure segment to rate 2.0, format does not matter when we don't specify
447    * a start or stop position. */
448   gst_segment_set_seek (&segment, 2.0,
449       GST_FORMAT_UNDEFINED,
450       GST_SEEK_FLAG_NONE,
451       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
452   fail_unless (segment.format == GST_FORMAT_BYTES);
453   fail_unless (segment.start == 0);
454   fail_unless (segment.stop == -1);
455   fail_unless (segment.rate == 2.0);
456   fail_unless (update == FALSE);
457
458   /* 0 is the same in all formats and should not fail */
459   gst_segment_set_seek (&segment, 2.0,
460       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
461       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1, &update);
462   fail_unless (segment.format == GST_FORMAT_BYTES);
463
464   /* set to -1 means start from 0 */
465   gst_segment_set_seek (&segment, 2.0,
466       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
467       GST_SEEK_TYPE_SET, -1, GST_SEEK_TYPE_NONE, -1, &update);
468   fail_unless (segment.format == GST_FORMAT_BYTES);
469   fail_unless (segment.start == 0);
470
471   gst_segment_set_seek (&segment, 2.0,
472       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
473       GST_SEEK_TYPE_CUR, 0, GST_SEEK_TYPE_NONE, -1, &update);
474
475   gst_segment_set_seek (&segment, 2.0,
476       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
477       GST_SEEK_TYPE_END, 0, GST_SEEK_TYPE_NONE, -1, &update);
478
479   /* -1 for end is fine too in all formats */
480   gst_segment_set_seek (&segment, 2.0,
481       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
482       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
483
484   /* 0 as relative end is fine too */
485   gst_segment_set_seek (&segment, 2.0,
486       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
487       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
488
489   gst_segment_set_seek (&segment, 2.0,
490       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
491       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
492
493   /* set a real stop position, this must happen in bytes */
494   gst_segment_set_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
506   /* 0 as relative end is fine too */
507   gst_segment_set_seek (&segment, 2.0,
508       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
509       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
510   fail_unless (segment.stop == 100);
511
512   gst_segment_set_seek (&segment, 2.0,
513       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
514       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
515   fail_unless (segment.stop == 100);
516
517   /* -1 for end is fine too in all formats */
518   gst_segment_set_seek (&segment, 2.0,
519       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
520       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
521   fail_unless (segment.stop == -1);
522
523   /* set some duration, stop -1 END seeks will now work with the
524    * duration, if the formats match */
525   gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
526   fail_unless (segment.duration == 200);
527
528   /* seek to end in any format with 0 should set the stop to the
529    * duration */
530   gst_segment_set_seek (&segment, 2.0,
531       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
532       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
533   fail_unless (segment.stop == 200);
534   fail_unless (segment.duration == 200);
535
536   /* subtract 100 from the end */
537   gst_segment_set_seek (&segment, 2.0,
538       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
539       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
540   fail_unless (segment.stop == 100);
541   fail_unless (segment.duration == 200);
542
543   /* add 100 to the duration, this should be clamped to the duration */
544   gst_segment_set_seek (&segment, 2.0,
545       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
546       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
547   fail_unless (segment.stop == 200);
548   fail_unless (segment.duration == 200);
549
550   /* add 300 to the start, this should be clamped to the duration */
551   gst_segment_set_seek (&segment, 2.0,
552       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
553       GST_SEEK_TYPE_CUR, 300, GST_SEEK_TYPE_END, 0, &update);
554   fail_unless (segment.start == 200);
555   fail_unless (segment.stop == 200);
556   fail_unless (segment.duration == 200);
557
558   /* subtract 300 from the start, this should be clamped to 0 */
559   gst_segment_set_seek (&segment, 2.0,
560       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
561       GST_SEEK_TYPE_CUR, -300, GST_SEEK_TYPE_END, 0, &update);
562   fail_unless (segment.start == 0);
563   fail_unless (segment.stop == 200);
564   fail_unless (segment.duration == 200);
565 }
566
567 GST_END_TEST;
568
569 /* mess with the segment structure in the bytes format */
570 GST_START_TEST (segment_newsegment_open)
571 {
572   GstSegment segment;
573
574   gst_segment_init (&segment, GST_FORMAT_BYTES);
575
576   /* time should also work for starting from 0 */
577   gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0);
578
579   fail_unless (segment.rate == 1.0);
580   fail_unless (segment.format == GST_FORMAT_BYTES);
581   fail_unless (segment.flags == 0);
582   fail_unless (segment.start == 0);
583   fail_unless (segment.stop == -1);
584   fail_unless (segment.time == 0);
585   fail_unless (segment.accum == 0);
586   fail_unless (segment.last_stop == 0);
587   fail_unless (segment.duration == -1);
588
589   /* we set stop but in the wrong format, stop stays open. */
590   gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_TIME, 0, 200, 0);
591
592   fail_unless (segment.start == 0);
593   fail_unless (segment.stop == -1);
594   fail_unless (segment.time == 0);
595   fail_unless (segment.accum == 0);
596
597   /* update, nothing changes */
598   gst_segment_set_newsegment (&segment, TRUE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
599
600   fail_unless (segment.start == 0);
601   fail_unless (segment.stop == -1);
602   fail_unless (segment.time == 0);
603   fail_unless (segment.accum == 0);
604
605   /* update */
606   gst_segment_set_newsegment (&segment, TRUE, 1.0,
607       GST_FORMAT_BYTES, 100, -1, 100);
608
609   fail_unless (segment.start == 100);
610   fail_unless (segment.stop == -1);
611   fail_unless (segment.time == 100);
612   fail_unless (segment.accum == 100);
613
614   /* last_stop 0, accum does not change */
615   gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
616
617   fail_unless (segment.start == 0);
618   fail_unless (segment.stop == -1);
619   fail_unless (segment.time == 0);
620   fail_unless (segment.accum == 100);
621
622   gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 200);
623
624   /* last_stop 200, accum changes */
625   gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
626
627   fail_unless (segment.start == 0);
628   fail_unless (segment.stop == -1);
629   fail_unless (segment.time == 0);
630   fail_unless (segment.accum == 300);
631
632 }
633
634 GST_END_TEST;
635
636
637 /* mess with the segment structure in the bytes format */
638 GST_START_TEST (segment_newsegment_closed)
639 {
640   GstSegment segment;
641
642   gst_segment_init (&segment, GST_FORMAT_BYTES);
643
644   gst_segment_set_newsegment (&segment, FALSE, 1.0,
645       GST_FORMAT_BYTES, 0, 200, 0);
646
647   fail_unless (segment.rate == 1.0);
648   fail_unless (segment.format == GST_FORMAT_BYTES);
649   fail_unless (segment.flags == 0);
650   fail_unless (segment.start == 0);
651   fail_unless (segment.stop == 200);
652   fail_unless (segment.time == 0);
653   fail_unless (segment.accum == 0);
654   fail_unless (segment.last_stop == 0);
655   fail_unless (segment.duration == -1);
656
657   /* do an update */
658   gst_segment_set_newsegment (&segment, TRUE, 1.0, GST_FORMAT_BYTES, 0, 300, 0);
659
660   fail_unless (segment.start == 0);
661   fail_unless (segment.stop == 300);
662   fail_unless (segment.time == 0);
663   fail_unless (segment.accum == 0);
664
665   /* and a new accumulated one */
666   gst_segment_set_newsegment (&segment, FALSE, 1.0,
667       GST_FORMAT_BYTES, 100, 400, 300);
668
669   fail_unless (segment.start == 100);
670   fail_unless (segment.stop == 400);
671   fail_unless (segment.time == 300);
672   fail_unless (segment.accum == 300);
673
674   /* and a new updated one */
675   gst_segment_set_newsegment (&segment, TRUE, 1.0,
676       GST_FORMAT_BYTES, 100, 500, 300);
677
678   fail_unless (segment.start == 100);
679   fail_unless (segment.stop == 500);
680   fail_unless (segment.time == 300);
681   fail_unless (segment.accum == 300);
682
683   /* and a new partially updated one */
684   gst_segment_set_newsegment (&segment, TRUE, 1.0,
685       GST_FORMAT_BYTES, 200, 500, 400);
686
687   fail_unless (segment.start == 200);
688   fail_unless (segment.stop == 500);
689   fail_unless (segment.time == 400);
690   fail_unless (segment.accum == 400);
691 }
692
693 GST_END_TEST;
694
695 /* mess with the segment structure in the time format */
696 GST_START_TEST (segment_newsegment_streamtime)
697 {
698   GstSegment segment;
699   gint64 result;
700
701   gst_segment_init (&segment, GST_FORMAT_TIME);
702
703   /***************************
704    * Normal segment
705    ***************************/
706   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
707       GST_FORMAT_TIME, 0, 200, 0);
708
709   fail_unless (segment.rate == 1.0);
710   fail_unless (segment.applied_rate == 1.0);
711   fail_unless (segment.format == GST_FORMAT_TIME);
712   fail_unless (segment.flags == 0);
713   fail_unless (segment.start == 0);
714   fail_unless (segment.stop == 200);
715   fail_unless (segment.time == 0);
716   fail_unless (segment.accum == 0);
717   fail_unless (segment.last_stop == 0);
718   fail_unless (segment.duration == -1);
719
720   /* invalid time gives invalid result */
721   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
722   fail_unless (result == -1);
723
724   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
725   fail_unless (result == 0);
726
727   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
728   fail_unless (result == 100);
729
730   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
731   fail_unless (result == 200);
732
733   /* outside of the segment */
734   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
735   fail_unless (result == -1);
736
737   /*********************
738    * time shifted by 500
739    *********************/
740   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
741       GST_FORMAT_TIME, 0, 200, 500);
742
743   fail_unless (segment.accum == 200);
744
745   /* invalid time gives invalid result */
746   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
747   fail_unless (result == -1);
748
749   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
750   fail_unless (result == 500);
751
752   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
753   fail_unless (result == 600);
754
755   /* outside of the segment */
756   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 500);
757   fail_unless (result == -1);
758
759   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
760   fail_unless (result == -1);
761
762   /*********************
763    * time offset by 500
764    *********************/
765   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
766       GST_FORMAT_TIME, 500, 700, 0);
767
768   fail_unless (segment.accum == 400);
769
770   /* invalid time gives invalid result */
771   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
772   fail_unless (result == -1);
773
774   /* before segment is invalid */
775   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
776   fail_unless (result == -1);
777
778   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 500);
779   fail_unless (result == 0);
780
781   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 600);
782   fail_unless (result == 100);
783
784   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 700);
785   fail_unless (result == 200);
786
787   /* outside of the segment */
788   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 800);
789   fail_unless (result == -1);
790
791   /*************************************
792    * time offset by 500, shifted by 200
793    *************************************/
794   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
795       GST_FORMAT_TIME, 500, 700, 200);
796
797   fail_unless (segment.accum == 600);
798
799   /* invalid time gives invalid result */
800   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
801   fail_unless (result == -1);
802
803   /* before segment is invalid */
804   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
805   fail_unless (result == -1);
806
807   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 500);
808   fail_unless (result == 200);
809
810   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 600);
811   fail_unless (result == 300);
812
813   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 700);
814   fail_unless (result == 400);
815
816   /* outside of the segment */
817   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 800);
818   fail_unless (result == -1);
819 }
820
821 GST_END_TEST;
822
823 /* mess with the segment structure in the time format */
824 GST_START_TEST (segment_newsegment_streamtime_rate)
825 {
826   GstSegment segment;
827   gint64 result;
828
829   gst_segment_init (&segment, GST_FORMAT_TIME);
830
831   /***************************
832    * Normal segment rate 2.0
833    ***************************/
834   gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 1.0,
835       GST_FORMAT_TIME, 0, 200, 0);
836
837   fail_unless (segment.rate == 2.0);
838   fail_unless (segment.applied_rate == 1.0);
839   fail_unless (segment.format == GST_FORMAT_TIME);
840   fail_unless (segment.flags == 0);
841   fail_unless (segment.start == 0);
842   fail_unless (segment.stop == 200);
843   fail_unless (segment.time == 0);
844   fail_unless (segment.accum == 0);
845   fail_unless (segment.last_stop == 0);
846   fail_unless (segment.duration == -1);
847
848   /* invalid time gives invalid result */
849   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
850   fail_unless (result == -1);
851
852   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
853   fail_unless (result == 0);
854
855   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
856   fail_unless (result == 100);
857
858   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
859   fail_unless (result == 150);
860
861   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
862   fail_unless (result == 200);
863
864   /* outside of the segment */
865   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
866   fail_unless (result == -1);
867
868   /***************************************
869    * Normal segment rate 2.0, offset
870    ***************************************/
871   gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 1.0,
872       GST_FORMAT_TIME, 100, 300, 0);
873
874   fail_unless (segment.accum == 100);
875
876   /* invalid time gives invalid result */
877   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
878   fail_unless (result == -1);
879
880   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
881   fail_unless (result == 0);
882
883   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
884   fail_unless (result == 100);
885
886   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 250);
887   fail_unless (result == 150);
888
889   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
890   fail_unless (result == 200);
891
892   /* outside of the segment */
893   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
894   fail_unless (result == -1);
895
896   /***************************************
897    * Normal segment rate -1.0, offset
898    ***************************************/
899
900   /* buffers will arrive from 300 to 100 in a sink, stream time
901    * calculation is unaffected by the rate */
902   gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
903       GST_FORMAT_TIME, 100, 300, 0);
904
905   fail_unless (segment.accum == 200);
906
907   /* invalid time gives invalid result */
908   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
909   fail_unless (result == -1);
910
911   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
912   fail_unless (result == 0);
913
914   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
915   fail_unless (result == 100);
916
917   /***********************************************
918    * Normal segment rate -1.0, offset, time = 200
919    ***********************************************/
920   gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
921       GST_FORMAT_TIME, 100, 300, 200);
922
923   /* invalid time gives invalid result */
924   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
925   fail_unless (result == -1);
926
927   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
928   fail_unless (result == 200);
929
930   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
931   fail_unless (result == 300);
932
933   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
934   fail_unless (result == 400);
935
936   /* outside of the segment */
937   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 400);
938   fail_unless (result == -1);
939 }
940
941 GST_END_TEST;
942
943 /* mess with the segment structure in the time format */
944 GST_START_TEST (segment_newsegment_streamtime_applied_rate)
945 {
946   GstSegment segment;
947   gint64 result;
948
949   gst_segment_init (&segment, GST_FORMAT_TIME);
950
951   /***********************************************************
952    * Normal segment rate 1.0, applied rate -1.0
953    * This means the timestamps represents a stream going backwards
954    * starting from @time to 0.
955    ************************************************************/
956   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, -1.0,
957       GST_FORMAT_TIME, 0, 200, 200);
958
959   fail_unless (segment.rate == 1.0);
960   fail_unless (segment.applied_rate == -1.0);
961   fail_unless (segment.format == GST_FORMAT_TIME);
962   fail_unless (segment.flags == 0);
963   fail_unless (segment.start == 0);
964   fail_unless (segment.stop == 200);
965   fail_unless (segment.time == 200);
966   fail_unless (segment.accum == 0);
967   fail_unless (segment.last_stop == 0);
968   fail_unless (segment.duration == -1);
969
970   /* invalid time gives invalid result */
971   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
972   fail_unless (result == -1);
973
974   /* we count backwards from 200 */
975   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
976   fail_unless (result == 200);
977
978   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
979   fail_unless (result == 100);
980
981   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
982   fail_unless (result == 50);
983
984   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
985   fail_unless (result == 0);
986
987   /* outside of the segment */
988   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
989   fail_unless (result == -1);
990
991   /***********************************************************
992    * Normal segment rate 1.0, applied rate 2.0
993    * This means the timestamps represents a stream at twice the
994    * normal rate
995    ************************************************************/
996   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 2.0,
997       GST_FORMAT_TIME, 0, 200, 0);
998
999   fail_unless (segment.rate == 1.0);
1000   fail_unless (segment.applied_rate == 2.0);
1001   fail_unless (segment.format == GST_FORMAT_TIME);
1002   fail_unless (segment.flags == 0);
1003   fail_unless (segment.start == 0);
1004   fail_unless (segment.stop == 200);
1005   fail_unless (segment.time == 0);
1006   fail_unless (segment.accum == 200);
1007   fail_unless (segment.last_stop == 0);
1008   fail_unless (segment.duration == -1);
1009
1010   /* invalid time gives invalid result */
1011   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
1012   fail_unless (result == -1);
1013
1014   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
1015   fail_unless (result == 0);
1016
1017   /* the stream prepresents a stream going twice as fast, the position 
1018    * in the segment is therefore scaled by the applied rate */
1019   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
1020   fail_unless (result == 200);
1021
1022   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
1023   fail_unless (result == 300);
1024
1025   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
1026   fail_unless (result == 400);
1027
1028   /* outside of the segment */
1029   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
1030   fail_unless (result == -1);
1031
1032   /***********************************************************
1033    * Normal segment rate 1.0, applied rate -2.0
1034    * This means the timestamps represents a stream at twice the
1035    * reverse rate
1036    ************************************************************/
1037   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, -2.0,
1038       GST_FORMAT_TIME, 0, 200, 400);
1039
1040   fail_unless (segment.rate == 1.0);
1041   fail_unless (segment.applied_rate == -2.0);
1042   fail_unless (segment.format == GST_FORMAT_TIME);
1043   fail_unless (segment.flags == 0);
1044   fail_unless (segment.start == 0);
1045   fail_unless (segment.stop == 200);
1046   fail_unless (segment.time == 400);
1047   /* previous segment lasted 200, rate of 2.0 was already applied */
1048   fail_unless (segment.accum == 400);
1049   fail_unless (segment.last_stop == 0);
1050   fail_unless (segment.duration == -1);
1051
1052   /* invalid time gives invalid result */
1053   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
1054   fail_unless (result == -1);
1055
1056   /* we count backwards from 400 */
1057   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
1058   fail_unless (result == 400);
1059
1060   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
1061   fail_unless (result == 200);
1062
1063   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
1064   fail_unless (result == 100);
1065
1066   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
1067   fail_unless (result == 0);
1068
1069   /* outside of the segment */
1070   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
1071   fail_unless (result == -1);
1072
1073   /***********************************************************
1074    * Normal segment rate 1.0, applied rate -2.0
1075    * This means the timestamps represents a stream at twice the
1076    * reverse rate, start time cannot compensate the complete
1077    * duration of the segment so we stop at 0
1078    ************************************************************/
1079   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, -2.0,
1080       GST_FORMAT_TIME, 0, 200, 200);
1081
1082   fail_unless (segment.rate == 1.0);
1083   fail_unless (segment.applied_rate == -2.0);
1084   fail_unless (segment.format == GST_FORMAT_TIME);
1085   fail_unless (segment.flags == 0);
1086   fail_unless (segment.start == 0);
1087   fail_unless (segment.stop == 200);
1088   fail_unless (segment.time == 200);
1089   fail_unless (segment.accum == 600);
1090   fail_unless (segment.last_stop == 0);
1091   fail_unless (segment.duration == -1);
1092
1093   /* invalid time gives invalid result */
1094   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
1095   fail_unless (result == -1);
1096
1097   /* we count backwards from 200 */
1098   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
1099   fail_unless (result == 200);
1100
1101   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
1102   fail_unless (result == 0);
1103
1104   /* clamp at 0 */
1105   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
1106   fail_unless (result == 0);
1107
1108   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
1109   fail_unless (result == 0);
1110
1111   /* outside of the segment */
1112   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
1113   fail_unless (result == -1);
1114 }
1115
1116 GST_END_TEST;
1117
1118 /* mess with the segment structure in the time format */
1119 GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
1120 {
1121   GstSegment segment;
1122   gint64 result;
1123
1124   gst_segment_init (&segment, GST_FORMAT_TIME);
1125
1126   /***********************************************************
1127    * Segment rate 2.0, applied rate 2.0
1128    * this means we have a double speed stream that we should
1129    * speed up by a factor of 2.0 some more. the resulting
1130    * stream will be played at four times the speed. 
1131    ************************************************************/
1132   gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 2.0,
1133       GST_FORMAT_TIME, 0, 200, 0);
1134
1135   fail_unless (segment.rate == 2.0);
1136   fail_unless (segment.applied_rate == 2.0);
1137   fail_unless (segment.format == GST_FORMAT_TIME);
1138   fail_unless (segment.flags == 0);
1139   fail_unless (segment.start == 0);
1140   fail_unless (segment.stop == 200);
1141   fail_unless (segment.time == 0);
1142   fail_unless (segment.accum == 0);
1143   fail_unless (segment.last_stop == 0);
1144   fail_unless (segment.duration == -1);
1145
1146   /* invalid time gives invalid result */
1147   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
1148   fail_unless (result == -1);
1149
1150   /* only applied rate affects our calculation of the stream time */
1151   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
1152   fail_unless (result == 0);
1153
1154   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
1155   fail_unless (result == 200);
1156
1157   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
1158   fail_unless (result == 300);
1159
1160   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
1161   fail_unless (result == 400);
1162
1163   /* outside of the segment */
1164   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
1165   fail_unless (result == -1);
1166
1167   /***********************************************************
1168    * Segment rate 2.0, applied rate -1.0
1169    * this means we have a reverse stream that we should
1170    * speed up by a factor of 2.0
1171    ************************************************************/
1172   gst_segment_set_newsegment_full (&segment, FALSE, 2.0, -1.0,
1173       GST_FORMAT_TIME, 0, 200, 200);
1174
1175   fail_unless (segment.rate == 2.0);
1176   fail_unless (segment.applied_rate == -1.0);
1177   fail_unless (segment.format == GST_FORMAT_TIME);
1178   fail_unless (segment.flags == 0);
1179   fail_unless (segment.start == 0);
1180   fail_unless (segment.stop == 200);
1181   fail_unless (segment.time == 200);
1182   /* previous segment lasted 100 */
1183   fail_unless (segment.accum == 100);
1184   fail_unless (segment.last_stop == 0);
1185   fail_unless (segment.duration == -1);
1186
1187   /* invalid time gives invalid result */
1188   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
1189   fail_unless (result == -1);
1190
1191   /* only applied rate affects our calculation of the stream time */
1192   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
1193   fail_unless (result == 200);
1194
1195   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
1196   fail_unless (result == 100);
1197
1198   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
1199   fail_unless (result == 50);
1200
1201   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
1202   fail_unless (result == 0);
1203
1204   /* outside of the segment */
1205   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
1206   fail_unless (result == -1);
1207
1208   /***********************************************************
1209    * Segment rate -1.0, applied rate -1.0
1210    * this means we have a reverse stream that we should
1211    * reverse to get the normal stream again.
1212    ************************************************************/
1213   gst_segment_set_newsegment_full (&segment, FALSE, -1.0, -1.0,
1214       GST_FORMAT_TIME, 0, 200, 200);
1215
1216   fail_unless (segment.rate == -1.0);
1217   fail_unless (segment.applied_rate == -1.0);
1218   fail_unless (segment.format == GST_FORMAT_TIME);
1219   fail_unless (segment.flags == 0);
1220   fail_unless (segment.start == 0);
1221   fail_unless (segment.stop == 200);
1222   fail_unless (segment.time == 200);
1223   /* accumulated 100 of previous segment to make 200 */
1224   fail_unless (segment.accum == 200);
1225   fail_unless (segment.last_stop == 0);
1226   fail_unless (segment.duration == -1);
1227
1228   /* invalid time gives invalid result */
1229   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
1230   fail_unless (result == -1);
1231
1232   /* only applied rate affects our calculation of the stream time */
1233   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
1234   fail_unless (result == 200);
1235
1236   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
1237   fail_unless (result == 100);
1238
1239   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
1240   fail_unless (result == 50);
1241
1242   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
1243   fail_unless (result == 0);
1244
1245   /* outside of the segment */
1246   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
1247   fail_unless (result == -1);
1248
1249   /***********************************************************
1250    * Segment rate -1.0, applied rate -1.0
1251    * this means we have a reverse stream that we should
1252    * reverse to get the normal stream again.
1253    ************************************************************/
1254   gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 2.0,
1255       GST_FORMAT_TIME, 0, 200, 0);
1256
1257   fail_unless (segment.rate == -1.0);
1258   fail_unless (segment.applied_rate == 2.0);
1259   fail_unless (segment.format == GST_FORMAT_TIME);
1260   fail_unless (segment.flags == 0);
1261   fail_unless (segment.start == 0);
1262   fail_unless (segment.stop == 200);
1263   fail_unless (segment.time == 0);
1264   fail_unless (segment.accum == 400);
1265   fail_unless (segment.last_stop == 0);
1266   fail_unless (segment.duration == -1);
1267
1268   /* invalid time gives invalid result */
1269   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
1270   fail_unless (result == -1);
1271
1272   /* only applied rate affects our calculation of the stream time */
1273   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 0);
1274   fail_unless (result == 0);
1275
1276   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 100);
1277   fail_unless (result == 200);
1278
1279   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 150);
1280   fail_unless (result == 300);
1281
1282   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 200);
1283   fail_unless (result == 400);
1284
1285   /* outside of the segment */
1286   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, 300);
1287   fail_unless (result == -1);
1288 }
1289
1290 GST_END_TEST;
1291
1292 /* mess with the segment structure in the time format */
1293 GST_START_TEST (segment_newsegment_runningtime)
1294 {
1295   GstSegment segment;
1296   gint64 result;
1297
1298   gst_segment_init (&segment, GST_FORMAT_TIME);
1299
1300   /***************************
1301    * Normal segment
1302    ***************************/
1303   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
1304       GST_FORMAT_TIME, 0, 200, 0);
1305
1306   fail_unless (segment.rate == 1.0);
1307   fail_unless (segment.applied_rate == 1.0);
1308   fail_unless (segment.format == GST_FORMAT_TIME);
1309   fail_unless (segment.flags == 0);
1310   fail_unless (segment.start == 0);
1311   fail_unless (segment.stop == 200);
1312   fail_unless (segment.time == 0);
1313   fail_unless (segment.accum == 0);
1314   fail_unless (segment.last_stop == 0);
1315   fail_unless (segment.duration == -1);
1316
1317   /* invalid time gives invalid result */
1318   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1319   fail_unless (result == -1);
1320
1321   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 0);
1322   fail_unless (result == 0);
1323
1324   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
1325   fail_unless (result == 100);
1326
1327   /* at edge is exactly the segment duration */
1328   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
1329   fail_unless (result == 200);
1330
1331   /* outside of the segment */
1332   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 300);
1333   fail_unless (result == -1);
1334
1335   /***********************************************************
1336    * time shifted by 500, check if accumulation worked.
1337    * Rate convert to twice the speed which means scaling down
1338    * all positions by 2.0 in this segment.
1339    * Then time argument is not used at all here.
1340    ***********************************************************/
1341   gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 1.0,
1342       GST_FORMAT_TIME, 0, 200, 500);
1343
1344   /* normal speed gives elapsed of 200 */
1345   fail_unless (segment.accum == 200);
1346
1347   /* invalid time gives invalid result */
1348   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1349   fail_unless (result == -1);
1350
1351   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 0);
1352   fail_unless (result == 200);
1353
1354   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
1355   fail_unless (result == 250);
1356
1357   /* outside of the segment */
1358   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
1359   fail_unless (result == -1);
1360
1361   /********************************************
1362    * time offset by 500
1363    * applied rate is not used for running time
1364    ********************************************/
1365   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 2.0,
1366       GST_FORMAT_TIME, 500, 700, 0);
1367
1368   /* previous segment played at double speed gives elapsed time of
1369    * 100 added to previous accum of 200 gives 300. */
1370   fail_unless (segment.accum == 300);
1371
1372   /* invalid time gives invalid result */
1373   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1374   fail_unless (result == -1);
1375
1376   /* before segment is invalid */
1377   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
1378   fail_unless (result == -1);
1379
1380   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
1381   fail_unless (result == 300);
1382
1383   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
1384   fail_unless (result == 400);
1385
1386   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
1387   fail_unless (result == 500);
1388
1389   /* outside of the segment */
1390   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
1391   fail_unless (result == -1);
1392
1393   /**********************************************************
1394    * time offset by 500, shifted by 200
1395    * Negative rate makes the running time go backwards 
1396    * relative to the segment stop position. again time
1397    * is ignored.
1398    **********************************************************/
1399   gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
1400       GST_FORMAT_TIME, 500, 700, 200);
1401
1402   fail_unless (segment.accum == 500);
1403
1404   /* invalid time gives invalid result */
1405   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1406   fail_unless (result == -1);
1407
1408   /* before segment is invalid */
1409   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
1410   fail_unless (result == -1);
1411
1412   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
1413   fail_unless (result == 700);
1414
1415   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
1416   fail_unless (result == 600);
1417
1418   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
1419   fail_unless (result == 500);
1420
1421   /* outside of the segment */
1422   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
1423   fail_unless (result == -1);
1424
1425   /**********************************************************
1426    * time offset by 500, shifted by 200
1427    * Negative rate makes the running time go backwards at
1428    * twice speed relative to the segment stop position. again 
1429    * time is ignored.
1430    **********************************************************/
1431   gst_segment_set_newsegment_full (&segment, FALSE, -2.0, -2.0,
1432       GST_FORMAT_TIME, 500, 700, 200);
1433
1434   fail_unless (segment.accum == 700);
1435
1436   /* invalid time gives invalid result */
1437   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1438   fail_unless (result == -1);
1439
1440   /* before segment is invalid */
1441   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
1442   fail_unless (result == -1);
1443
1444   /* total scaled segment time is 100, accum is 700, so we get 800 */
1445   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
1446   fail_unless (result == 800);
1447
1448   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
1449   fail_unless (result == 750);
1450
1451   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
1452   fail_unless (result == 700);
1453
1454   /* outside of the segment */
1455   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
1456   fail_unless (result == -1);
1457
1458   /* see if negative rate closed segment correctly */
1459   gst_segment_set_newsegment_full (&segment, FALSE, -2.0, -1.0,
1460       GST_FORMAT_TIME, 500, 700, 200);
1461
1462   /* previous segment lasted 100, and was at 700 so we should get 800 */
1463   fail_unless (segment.accum == 800);
1464 }
1465
1466 GST_END_TEST;
1467
1468 /* mess with the segment structure in the time format */
1469 GST_START_TEST (segment_newsegment_accum)
1470 {
1471   GstSegment segment;
1472   gint64 result;
1473
1474   gst_segment_init (&segment, GST_FORMAT_TIME);
1475
1476   /***************************
1477    * Normal reverse segment
1478    ***************************/
1479   gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
1480       GST_FORMAT_TIME, 0, 200, 0);
1481
1482   fail_unless (segment.rate == -1.0);
1483   fail_unless (segment.applied_rate == 1.0);
1484   fail_unless (segment.format == GST_FORMAT_TIME);
1485   fail_unless (segment.flags == 0);
1486   fail_unless (segment.start == 0);
1487   fail_unless (segment.stop == 200);
1488   fail_unless (segment.time == 0);
1489   fail_unless (segment.accum == 0);
1490   fail_unless (segment.last_stop == 0);
1491   fail_unless (segment.duration == -1);
1492
1493   /* invalid time gives invalid result */
1494   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1495   fail_unless (result == -1);
1496
1497   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
1498   fail_unless (result == 0);
1499
1500   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
1501   fail_unless (result == 50);
1502
1503   /* update segment, this accumulates 50 from the previous segment. */
1504   gst_segment_set_newsegment_full (&segment, TRUE, -2.0, 1.0,
1505       GST_FORMAT_TIME, 0, 150, 0);
1506
1507   fail_unless (segment.rate == -2.0);
1508   fail_unless (segment.applied_rate == 1.0);
1509   fail_unless (segment.format == GST_FORMAT_TIME);
1510   fail_unless (segment.flags == 0);
1511   fail_unless (segment.start == 0);
1512   fail_unless (segment.stop == 150);
1513   fail_unless (segment.time == 0);
1514   fail_unless (segment.accum == 50);
1515   fail_unless (segment.last_stop == 0);
1516   fail_unless (segment.duration == -1);
1517
1518   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
1519   fail_unless (result == 50);
1520
1521   /* 50 accumulated + 50 / 2 */
1522   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
1523   fail_unless (result == 75);
1524
1525   /* update segment, this does not accumulate anything. */
1526   gst_segment_set_newsegment_full (&segment, TRUE, 1.0, 1.0,
1527       GST_FORMAT_TIME, 100, 200, 100);
1528
1529   fail_unless (segment.rate == 1.0);
1530   fail_unless (segment.applied_rate == 1.0);
1531   fail_unless (segment.format == GST_FORMAT_TIME);
1532   fail_unless (segment.flags == 0);
1533   fail_unless (segment.start == 100);
1534   fail_unless (segment.stop == 200);
1535   fail_unless (segment.time == 100);
1536   fail_unless (segment.accum == 50);
1537   fail_unless (segment.last_stop == 100);
1538   fail_unless (segment.duration == -1);
1539
1540   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
1541   fail_unless (result == 50);
1542
1543   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
1544   fail_unless (result == 100);
1545 }
1546
1547 GST_END_TEST;
1548
1549 /* mess with the segment structure in the time format */
1550 GST_START_TEST (segment_newsegment_accum2)
1551 {
1552   GstSegment segment;
1553   gint64 result;
1554
1555   gst_segment_init (&segment, GST_FORMAT_TIME);
1556
1557   /***************************
1558    * Normal reverse segment
1559    ***************************/
1560   gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
1561       GST_FORMAT_TIME, 0, 200, 0);
1562
1563   fail_unless (segment.rate == -1.0);
1564   fail_unless (segment.applied_rate == 1.0);
1565   fail_unless (segment.format == GST_FORMAT_TIME);
1566   fail_unless (segment.flags == 0);
1567   fail_unless (segment.start == 0);
1568   fail_unless (segment.stop == 200);
1569   fail_unless (segment.time == 0);
1570   fail_unless (segment.accum == 0);
1571   fail_unless (segment.last_stop == 0);
1572   fail_unless (segment.duration == -1);
1573
1574   /* invalid time gives invalid result */
1575   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1576   fail_unless (result == -1);
1577
1578   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
1579   fail_unless (result == 0);
1580
1581   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
1582   fail_unless (result == 50);
1583
1584   /* close segment, this accumulates nothing. */
1585   gst_segment_set_newsegment_full (&segment, TRUE, -1.0, 1.0,
1586       GST_FORMAT_TIME, 150, 200, 0);
1587
1588   fail_unless (segment.rate == -1.0);
1589   fail_unless (segment.applied_rate == 1.0);
1590   fail_unless (segment.format == GST_FORMAT_TIME);
1591   fail_unless (segment.flags == 0);
1592   fail_unless (segment.start == 150);
1593   fail_unless (segment.stop == 200);
1594   fail_unless (segment.time == 0);
1595   fail_unless (segment.accum == 0);
1596   fail_unless (segment.last_stop == 150);
1597   fail_unless (segment.duration == -1);
1598
1599   /* new segment, this accumulates 50. */
1600   gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
1601       GST_FORMAT_TIME, 150, 300, 150);
1602
1603   fail_unless (segment.rate == 1.0);
1604   fail_unless (segment.applied_rate == 1.0);
1605   fail_unless (segment.format == GST_FORMAT_TIME);
1606   fail_unless (segment.flags == 0);
1607   fail_unless (segment.start == 150);
1608   fail_unless (segment.stop == 300);
1609   fail_unless (segment.time == 150);
1610   fail_unless (segment.accum == 50);
1611   fail_unless (segment.last_stop == 150);
1612   fail_unless (segment.duration == -1);
1613
1614   /* invalid time gives invalid result */
1615   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
1616   fail_unless (result == -1);
1617
1618   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
1619   fail_unless (result == 50);
1620
1621   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
1622   fail_unless (result == 100);
1623 }
1624
1625 GST_END_TEST;
1626
1627 static Suite *
1628 gst_segment_suite (void)
1629 {
1630   Suite *s = suite_create ("GstSegment");
1631   TCase *tc_chain = tcase_create ("segments");
1632
1633   tcase_set_timeout (tc_chain, 20);
1634
1635   suite_add_tcase (s, tc_chain);
1636   tcase_add_test (tc_chain, segment_seek_nosize);
1637   tcase_add_test (tc_chain, segment_seek_size);
1638   tcase_add_test (tc_chain, segment_seek_reverse);
1639   tcase_add_test (tc_chain, segment_seek_rate);
1640   tcase_add_test (tc_chain, segment_newsegment_open);
1641   tcase_add_test (tc_chain, segment_newsegment_closed);
1642   tcase_add_test (tc_chain, segment_newsegment_streamtime);
1643   tcase_add_test (tc_chain, segment_newsegment_streamtime_rate);
1644   tcase_add_test (tc_chain, segment_newsegment_streamtime_applied_rate);
1645   tcase_add_test (tc_chain, segment_newsegment_streamtime_applied_rate_rate);
1646   tcase_add_test (tc_chain, segment_newsegment_runningtime);
1647   tcase_add_test (tc_chain, segment_newsegment_accum);
1648   tcase_add_test (tc_chain, segment_newsegment_accum2);
1649
1650   return s;
1651 }
1652
1653 GST_CHECK_MAIN (gst_segment);