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