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