segment: Add _full variants of all stream/running_time from/to segment position functions
[platform/upstream/gstreamer.git] / tests / check / gst / gstsegment.c
1 /* GStreamer
2  * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
3  *               2009 Wim Taymans <wim.taymans@gmail.com>
4  *
5  * gstsegment.c: Unit test for segments
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 #define check_times(segment, position, stream_time, running_time) G_STMT_START { \
26   guint64 st, rt, pos; \
27   \
28   st = gst_segment_to_stream_time ((segment), (segment)->format, (position)); \
29   rt = gst_segment_to_running_time ((segment), (segment)->format, (position)); \
30   GST_DEBUG ("position %" G_GUINT64_FORMAT ", st %" G_GUINT64_FORMAT ", rt %" \
31       G_GUINT64_FORMAT, (guint64) (position), (guint64) (stream_time), (guint64) (running_time)); \
32   \
33   fail_unless_equals_int64 (st, (stream_time)); \
34   fail_unless_equals_int64 (rt, (running_time)); \
35   if ((stream_time) != -1) { \
36     pos = gst_segment_position_from_stream_time ((segment), (segment)->format, st); \
37     fail_unless_equals_int64 (pos, (position)); \
38   } \
39   \
40   if ((running_time) != -1) { \
41     pos = gst_segment_position_from_running_time ((segment), (segment)->format, rt); \
42     fail_unless_equals_int64 (pos, (position)); \
43   } \
44 } G_STMT_END;
45
46 /* mess with the segment structure in the bytes format */
47 GST_START_TEST (segment_seek_nosize)
48 {
49   GstSegment segment;
50   gboolean res;
51   guint64 cstart, cstop;
52   gboolean update;
53
54   gst_segment_init (&segment, GST_FORMAT_BYTES);
55
56   /* configure segment to start 100 */
57   gst_segment_do_seek (&segment, 1.0,
58       GST_FORMAT_BYTES,
59       GST_SEEK_FLAG_NONE,
60       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
61   fail_unless (segment.start == 100);
62   fail_unless (segment.position == 100);
63   fail_unless (segment.stop == -1);
64   fail_unless (update == TRUE);
65   /* appended after current position 0 */
66   check_times (&segment, 100, 100, 0);
67
68   /* do some clipping on the open range */
69   /* completely outside */
70   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
71   fail_unless (res == FALSE);
72
73   /* touching lower bound, still outside of the segment */
74   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
75   fail_unless (res == FALSE);
76
77   /* partially inside */
78   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
79   fail_unless (res == TRUE);
80   fail_unless (cstart == 100);
81   fail_unless (cstop == 150);
82
83   /* inside, touching lower bound */
84   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
85       100, 150, &cstart, &cstop);
86   fail_unless (res == TRUE);
87   fail_unless (cstart == 100);
88   fail_unless (cstop == 150);
89
90   /* special case, 0 duration and outside segment */
91   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 90, 90, &cstart, &cstop);
92   fail_unless (res == FALSE);
93
94   /* special case, 0 duration and touching lower bound, i.e. inside segment */
95   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
96       100, 100, &cstart, &cstop);
97   fail_unless (res == TRUE);
98   fail_unless (cstart == 100);
99   fail_unless (cstop == 100);
100
101   /* special case, 0 duration and inside the segment */
102   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
103       120, 120, &cstart, &cstop);
104   fail_unless (res == TRUE);
105   fail_unless (cstart == 120);
106   fail_unless (cstop == 120);
107
108   /* completely inside */
109   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
110       150, 200, &cstart, &cstop);
111   fail_unless (res == TRUE);
112   fail_unless (cstart == 150);
113   fail_unless (cstop == 200);
114
115   /* invalid start */
116   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
117   fail_unless (res == FALSE);
118
119   /* start outside, we don't know the stop */
120   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
121   fail_unless (res == TRUE);
122   fail_unless (cstart == 100);
123   fail_unless (cstop == -1);
124
125   /* start on lower bound */
126   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
127   fail_unless (res == TRUE);
128   fail_unless (cstart == 100);
129   fail_unless (cstop == -1);
130
131   /* start inside */
132   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
133   fail_unless (res == TRUE);
134   fail_unless (cstart == 150);
135   fail_unless (cstop == -1);
136
137   /* move to 150, this is a running_time of 50 */
138   segment.position = 150;
139   check_times (&segment, 150, 150, 50);
140
141   /* add 100 to start, set stop to 300 */
142   gst_segment_do_seek (&segment, 1.0,
143       GST_FORMAT_BYTES,
144       GST_SEEK_FLAG_NONE,
145       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
146   fail_unless (segment.start == 200);
147   fail_unless (segment.position == 200);
148   fail_unless (segment.stop == 300);
149   fail_unless (segment.base == 50);
150   fail_unless (update == TRUE);
151   check_times (&segment, 200, 200, 50);
152   check_times (&segment, 250, 250, 100);
153
154   update = FALSE;
155   /* add 100 to start (to 300), set stop to 200, this is not allowed.
156    * nothing should be updated in the segment. A g_warning is
157    * emitted. */
158   ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
159           GST_FORMAT_BYTES,
160           GST_SEEK_FLAG_NONE,
161           GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update));
162   fail_unless (segment.start == 200);
163   fail_unless (segment.position == 200);
164   fail_unless (segment.stop == 300);
165   fail_unless (segment.base == 50);
166   /* update didn't change */
167   fail_unless (update == FALSE);
168   check_times (&segment, 200, 200, 50);
169   check_times (&segment, 250, 250, 100);
170
171   update = TRUE;
172   /* seek relative to end, should not do anything since size is
173    * unknown. */
174   gst_segment_do_seek (&segment, 1.0,
175       GST_FORMAT_BYTES,
176       GST_SEEK_FLAG_NONE,
177       GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
178   fail_unless (segment.start == 200);
179   fail_unless (segment.position == 200);
180   fail_unless (segment.stop == 300);
181   fail_unless (segment.base == 50);
182   fail_unless (update == FALSE);
183   check_times (&segment, 250, 250, 100);
184
185   /* completely outside */
186   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
187   fail_unless (res == FALSE);
188
189   /* touching lower bound */
190   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 200, &cstart, &cstop);
191   fail_unless (res == FALSE);
192
193   /* partially inside */
194   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 250, &cstart, &cstop);
195   fail_unless (res == TRUE);
196   fail_unless (cstart == 200);
197   fail_unless (cstop == 250);
198
199   /* inside, touching lower bound */
200   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
201       200, 250, &cstart, &cstop);
202   fail_unless (res == TRUE);
203   fail_unless (cstart == 200);
204   fail_unless (cstop == 250);
205
206   /* completely inside */
207   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
208       250, 290, &cstart, &cstop);
209   fail_unless (res == TRUE);
210   fail_unless (cstart == 250);
211   fail_unless (cstop == 290);
212
213   /* partially inside */
214   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
215       250, 350, &cstart, &cstop);
216   fail_unless (res == TRUE);
217   fail_unless (cstart == 250);
218   fail_unless (cstop == 300);
219
220   /* invalid start */
221   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
222   fail_unless (res == FALSE);
223
224   /* start outside */
225   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
226   fail_unless (res == TRUE);
227   fail_unless (cstart == 200);
228   fail_unless (cstop == 300);
229
230   /* start on lower bound */
231   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
232   fail_unless (res == TRUE);
233   fail_unless (cstart == 200);
234   fail_unless (cstop == 300);
235
236   /* start inside */
237   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
238   fail_unless (res == TRUE);
239   fail_unless (cstart == 250);
240   fail_unless (cstop == 300);
241
242   /* start outside on boundary */
243   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
244   fail_unless (res == FALSE);
245
246   /* start completely outside */
247   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 350, -1, &cstart, &cstop);
248   fail_unless (res == FALSE);
249 }
250
251 GST_END_TEST;
252
253 /* mess with the segment structure in the bytes format */
254 GST_START_TEST (segment_seek_size)
255 {
256   GstSegment segment;
257   gboolean res;
258   guint64 cstart, cstop;
259   gboolean update;
260
261   gst_segment_init (&segment, GST_FORMAT_BYTES);
262   segment.duration = 200;
263
264   /* configure segment to start 100 */
265   gst_segment_do_seek (&segment, 1.0,
266       GST_FORMAT_BYTES,
267       GST_SEEK_FLAG_NONE,
268       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
269   fail_unless (segment.start == 100);
270   fail_unless (segment.position == 100);
271   fail_unless (segment.stop == -1);
272   fail_unless (update == TRUE);
273   check_times (&segment, 100, 100, 0);
274
275   /* do some clipping on the open range */
276   /* completely outside */
277   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
278   fail_unless (res == FALSE);
279
280   /* touching lower bound */
281   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
282   fail_unless (res == FALSE);
283
284   /* partially inside */
285   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
286   fail_unless (res == TRUE);
287   fail_unless (cstart == 100);
288   fail_unless (cstop == 150);
289
290   /* inside, touching lower bound */
291   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
292       100, 150, &cstart, &cstop);
293   fail_unless (res == TRUE);
294   fail_unless (cstart == 100);
295   fail_unless (cstop == 150);
296
297   /* completely inside */
298   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
299       150, 200, &cstart, &cstop);
300   fail_unless (res == TRUE);
301   fail_unless (cstart == 150);
302   fail_unless (cstop == 200);
303
304   /* invalid start */
305   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
306   fail_unless (res == FALSE);
307
308   /* start outside */
309   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
310   fail_unless (res == TRUE);
311   fail_unless (cstart == 100);
312   fail_unless (cstop == -1);
313
314   /* start on lower bound */
315   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
316   fail_unless (res == TRUE);
317   fail_unless (cstart == 100);
318   fail_unless (cstop == -1);
319
320   /* start inside */
321   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
322   fail_unless (res == TRUE);
323   fail_unless (cstart == 150);
324   fail_unless (cstop == -1);
325
326   /* add 100 to start, set stop to 300, stop clips to 200 */
327   gst_segment_do_seek (&segment, 1.0,
328       GST_FORMAT_BYTES,
329       GST_SEEK_FLAG_NONE,
330       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
331   fail_unless (segment.start == 200);
332   fail_unless (segment.position == 200);
333   fail_unless (segment.stop == 200);
334   check_times (&segment, 200, 200, 0);
335
336   /* add 100 to start (to 300), set stop to 200, this clips start
337    * to duration */
338   gst_segment_do_seek (&segment, 1.0,
339       GST_FORMAT_BYTES,
340       GST_SEEK_FLAG_NONE,
341       GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update);
342   fail_unless (segment.start == 200);
343   fail_unless (segment.position == 200);
344   fail_unless (segment.stop == 200);
345   fail_unless (update == FALSE);
346   check_times (&segment, 200, 200, 0);
347
348   /* seek relative to end */
349   gst_segment_do_seek (&segment, 1.0,
350       GST_FORMAT_BYTES,
351       GST_SEEK_FLAG_NONE,
352       GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
353   fail_unless (segment.start == 100);
354   fail_unless (segment.position == 100);
355   fail_unless (segment.stop == 180);
356   fail_unless (update == TRUE);
357   check_times (&segment, 150, 150, 50);
358
359   /* completely outside */
360   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
361   fail_unless (res == FALSE);
362
363   /* touching lower bound */
364   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
365   fail_unless (res == FALSE);
366
367   /* partially inside */
368   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
369   fail_unless (res == TRUE);
370   fail_unless (cstart == 100);
371   fail_unless (cstop == 150);
372
373   /* inside, touching lower bound */
374   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
375       100, 150, &cstart, &cstop);
376   fail_unless (res == TRUE);
377   fail_unless (cstart == 100);
378   fail_unless (cstop == 150);
379
380   /* completely inside */
381   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
382       150, 170, &cstart, &cstop);
383   fail_unless (res == TRUE);
384   fail_unless (cstart == 150);
385   fail_unless (cstop == 170);
386
387   /* partially inside */
388   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
389       150, 250, &cstart, &cstop);
390   fail_unless (res == TRUE);
391   fail_unless (cstart == 150);
392   fail_unless (cstop == 180);
393
394   /* invalid start */
395   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
396   fail_unless (res == FALSE);
397
398   /* start outside */
399   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
400   fail_unless (res == TRUE);
401   fail_unless (cstart == 100);
402   fail_unless (cstop == 180);
403
404   /* start on lower bound */
405   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
406   fail_unless (res == TRUE);
407   fail_unless (cstart == 100);
408   fail_unless (cstop == 180);
409
410   /* start inside */
411   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
412   fail_unless (res == TRUE);
413   fail_unless (cstart == 150);
414   fail_unless (cstop == 180);
415
416   /* start outside on boundary */
417   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
418   fail_unless (res == FALSE);
419
420   /* start completely outside */
421   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
422   fail_unless (res == FALSE);
423 }
424
425 GST_END_TEST;
426
427 GST_START_TEST (segment_seek_reverse)
428 {
429   GstSegment segment;
430   gboolean update;
431
432   gst_segment_init (&segment, GST_FORMAT_BYTES);
433   segment.duration = 200;
434
435   /* configure segment to stop 100 */
436   gst_segment_do_seek (&segment, -1.0,
437       GST_FORMAT_BYTES,
438       GST_SEEK_FLAG_NONE,
439       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
440   fail_unless (segment.start == 0);
441   fail_unless (segment.stop == 100);
442   fail_unless (segment.time == 0);
443   fail_unless (segment.position == 100);
444   fail_unless (update == TRUE);
445   check_times (&segment, 100, 100, 0);
446   check_times (&segment, 50, 50, 50);
447   check_times (&segment, 0, 0, 100);
448
449   /* update */
450   gst_segment_do_seek (&segment, -1.0,
451       GST_FORMAT_BYTES,
452       GST_SEEK_FLAG_NONE,
453       GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_SET, 100 - 20, &update);
454   fail_unless (segment.start == 10);
455   fail_unless (segment.stop == 80);
456   fail_unless (segment.time == 10);
457   fail_unless (segment.position == 80);
458   fail_unless (update == TRUE);
459   check_times (&segment, 80, 80, 0);
460   check_times (&segment, 40, 40, 40);
461   check_times (&segment, 10, 10, 70);
462
463   gst_segment_do_seek (&segment, -1.0,
464       GST_FORMAT_BYTES,
465       GST_SEEK_FLAG_NONE,
466       GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
467   fail_unless (segment.start == 20);
468   fail_unless (segment.stop == 80);
469   fail_unless (segment.time == 20);
470   fail_unless (segment.position == 80);
471   fail_unless (update == FALSE);
472   check_times (&segment, 80, 80, 0);
473   check_times (&segment, 20, 20, 60);
474 }
475
476 GST_END_TEST;
477
478 /* mess with the segment structure in the bytes format */
479 GST_START_TEST (segment_seek_rate)
480 {
481   GstSegment segment;
482   gboolean update;
483
484   gst_segment_init (&segment, GST_FORMAT_BYTES);
485
486   /* configure segment to rate 2.0 */
487   gst_segment_do_seek (&segment, 2.0,
488       GST_FORMAT_BYTES,
489       GST_SEEK_FLAG_NONE,
490       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
491   fail_unless (segment.format == GST_FORMAT_BYTES);
492   fail_unless (segment.start == 0);
493   fail_unless (segment.position == 0);
494   fail_unless (segment.stop == -1);
495   fail_unless (segment.rate == 2.0);
496   fail_unless (update == FALSE);
497   check_times (&segment, 50, 50, 25);
498
499   /* set a real stop position, this must happen in bytes */
500   gst_segment_do_seek (&segment, 3.0,
501       GST_FORMAT_BYTES,
502       GST_SEEK_FLAG_NONE,
503       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
504   fail_unless (segment.format == GST_FORMAT_BYTES);
505   fail_unless (segment.start == 0);
506   fail_unless (segment.stop == 100);
507   fail_unless (segment.rate == 3.0);
508   /* no seek should happen, we just updated the stop position in forward
509    * playback mode.*/
510   fail_unless (update == FALSE);
511   check_times (&segment, 60, 60, 20);
512
513   /* set some duration, stop -1 END seeks will now work with the
514    * duration, if the formats match */
515   segment.duration = 200;
516   fail_unless (segment.duration == 200);
517
518   /* seek to end with 0 should set the stop to the duration */
519   gst_segment_do_seek (&segment, 2.0,
520       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
521       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
522   fail_unless (segment.stop == 200);
523   fail_unless (segment.duration == 200);
524
525   /* subtract 100 from the end */
526   gst_segment_do_seek (&segment, 2.0,
527       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
528       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
529   fail_unless (segment.stop == 100);
530   fail_unless (segment.duration == 200);
531
532   /* add 100 to the duration, this should be clamped to the duration */
533   gst_segment_do_seek (&segment, 2.0,
534       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
535       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
536   fail_unless (segment.stop == 200);
537   fail_unless (segment.duration == 200);
538 }
539
540 GST_END_TEST;
541
542 GST_START_TEST (segment_copy)
543 {
544   GstSegment *copy;
545   GstSegment segment = { 0.0, };
546
547   /* this is a boxed type copy function, we support copying NULL */
548   fail_unless (gst_segment_copy (NULL) == NULL);
549
550   gst_segment_init (&segment, GST_FORMAT_TIME);
551
552   segment.rate = -1.0;
553   segment.applied_rate = 1.0;
554   segment.start = 0;
555   segment.stop = 200;
556   segment.time = 0;
557
558   copy = gst_segment_copy (&segment);
559   fail_unless (copy != NULL);
560   /* we inited the struct on the stack to zeroes, so direct comparison should
561    * be ok here despite the padding field and regardless of implementation */
562   fail_unless (memcmp (copy, &segment, sizeof (GstSegment)) == 0);
563   gst_segment_free (copy);
564 }
565
566 GST_END_TEST;
567
568 /* mess with the segment structure in the bytes format */
569 GST_START_TEST (segment_seek_noupdate)
570 {
571   GstSegment segment;
572   gboolean update;
573
574   gst_segment_init (&segment, GST_FORMAT_TIME);
575
576   segment.start = 0;
577   segment.position = 50;
578   segment.stop = 200;
579   segment.time = 0;
580
581   /* doesn't change anything */
582   gst_segment_do_seek (&segment, 1.0,
583       GST_FORMAT_TIME,
584       GST_SEEK_FLAG_NONE,
585       GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
586   fail_unless (update == FALSE);
587   fail_unless (segment.format == GST_FORMAT_TIME);
588   fail_unless (segment.start == 0);
589   fail_unless (segment.stop == 200);
590   fail_unless (segment.time == 0);
591   fail_unless (segment.position == 50);
592   fail_unless (segment.base == 50);
593   fail_unless (segment.offset == 50);
594
595   gst_segment_do_seek (&segment, 2.0,
596       GST_FORMAT_TIME,
597       GST_SEEK_FLAG_NONE,
598       GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
599   fail_unless (update == FALSE);
600   fail_unless (segment.format == GST_FORMAT_TIME);
601   fail_unless (segment.start == 0);
602   fail_unless (segment.stop == 200);
603   fail_unless (segment.time == 0);
604   fail_unless (segment.position == 50);
605   fail_unless (segment.base == 50);
606   fail_unless_equals_int (segment.offset, 50);
607
608   gst_segment_do_seek (&segment, 1.0,
609       GST_FORMAT_TIME,
610       GST_SEEK_FLAG_FLUSH,
611       GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
612   fail_unless (update == FALSE);
613   fail_unless (segment.format == GST_FORMAT_TIME);
614   fail_unless (segment.start == 0);
615   fail_unless (segment.stop == 200);
616   fail_unless (segment.time == 0);
617   fail_unless (segment.position == 50);
618   fail_unless (segment.base == 0);
619   fail_unless (segment.offset == 50);
620 }
621
622 GST_END_TEST;
623
624 GST_START_TEST (segment_offset)
625 {
626   GstSegment segment;
627
628   gst_segment_init (&segment, GST_FORMAT_TIME);
629
630   segment.start = 0;
631   segment.position = 50;
632   segment.stop = 200;
633   segment.time = 0;
634
635   check_times (&segment, 20, 20, 20);
636   check_times (&segment, 220, -1, -1);
637
638   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
639           0) == TRUE);
640   fail_unless (segment.start == 0);
641   fail_unless (segment.stop == 200);
642   fail_unless (segment.time == 0);
643   fail_unless (segment.position == 50);
644   fail_unless (segment.base == 0);
645   fail_unless (segment.offset == 0);
646   check_times (&segment, 20, 20, 20);
647
648   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
649           100) == TRUE);
650   fail_unless (segment.start == 0);
651   fail_unless (segment.stop == 200);
652   fail_unless (segment.time == 0);
653   fail_unless (segment.position == 50);
654   fail_unless (segment.base == 100);
655   fail_unless (segment.offset == 0);
656   check_times (&segment, 20, 20, 120);
657
658   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
659           -50) == TRUE);
660   fail_unless (segment.start == 0);
661   fail_unless (segment.stop == 200);
662   fail_unless (segment.time == 0);
663   fail_unless (segment.position == 50);
664   fail_unless (segment.base == 50);
665   fail_unless (segment.offset == 0);
666   check_times (&segment, 20, 20, 70);
667
668   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
669           -100) == TRUE);
670   fail_unless (segment.start == 0);
671   fail_unless (segment.stop == 200);
672   fail_unless (segment.time == 0);
673   fail_unless (segment.position == 50);
674   fail_unless (segment.base == 0);
675   fail_unless (segment.offset == 50);
676   check_times (&segment, 20, 20, -1);
677   check_times (&segment, 200, 200, 150);
678
679   /* can go negative */
680   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
681           -151) == FALSE);
682   fail_unless (segment.start == 0);
683   fail_unless (segment.stop == 200);
684   fail_unless (segment.time == 0);
685   fail_unless (segment.position == 50);
686   fail_unless (segment.base == 0);
687   fail_unless (segment.offset == 50);
688   check_times (&segment, 100, 100, 50);
689   check_times (&segment, 200, 200, 150);
690
691   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
692           -150) == TRUE);
693   fail_unless (segment.start == 0);
694   fail_unless (segment.stop == 200);
695   fail_unless (segment.time == 0);
696   fail_unless (segment.position == 50);
697   fail_unless (segment.base == 0);
698   fail_unless (segment.offset == 200);
699   check_times (&segment, 200, 200, 0);
700
701   gst_segment_init (&segment, GST_FORMAT_TIME);
702
703   segment.start = 20;
704   segment.position = 50;
705   segment.stop = 220;
706   segment.time = 0;
707
708   check_times (&segment, 40, 20, 20);
709   check_times (&segment, 240, -1, -1);
710
711   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
712           0) == TRUE);
713   fail_unless (segment.start == 20);
714   fail_unless (segment.stop == 220);
715   fail_unless (segment.time == 0);
716   fail_unless (segment.position == 50);
717   fail_unless (segment.base == 0);
718   fail_unless (segment.offset == 0);
719   check_times (&segment, 40, 20, 20);
720
721   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
722           100) == TRUE);
723   fail_unless (segment.start == 20);
724   fail_unless (segment.stop == 220);
725   fail_unless (segment.time == 0);
726   fail_unless (segment.position == 50);
727   fail_unless (segment.base == 100);
728   fail_unless (segment.offset == 0);
729   check_times (&segment, 40, 20, 120);
730
731   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
732           -50) == TRUE);
733   fail_unless (segment.start == 20);
734   fail_unless (segment.stop == 220);
735   fail_unless (segment.time == 0);
736   fail_unless (segment.position == 50);
737   fail_unless (segment.base == 50);
738   fail_unless (segment.offset == 0);
739   check_times (&segment, 40, 20, 70);
740
741   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
742           -100) == TRUE);
743   fail_unless (segment.start == 20);
744   fail_unless (segment.stop == 220);
745   fail_unless (segment.time == 0);
746   fail_unless (segment.position == 50);
747   fail_unless (segment.base == 0);
748   fail_unless (segment.offset == 50);
749   check_times (&segment, 40, 20, -1);
750   check_times (&segment, 220, 200, 150);
751 }
752
753 GST_END_TEST;
754
755 GST_START_TEST (segment_full)
756 {
757   GstSegment segment;
758   guint64 rt, pos;
759
760   gst_segment_init (&segment, GST_FORMAT_TIME);
761
762   segment.start = 50;
763   segment.position = 150;
764   segment.stop = 200;
765   segment.time = 0;
766
767   check_times (&segment, 100, 50, 50);
768   check_times (&segment, 220, -1, -1);
769
770   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
771           50, &rt) == 1);
772   fail_unless (rt == 0);
773   fail_unless (gst_segment_position_from_running_time_full (&segment,
774           GST_FORMAT_TIME, rt, &pos) == 1);
775   fail_unless (pos == 50);
776   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
777           200, &rt) == 1);
778   fail_unless (rt == 150);
779   fail_unless (gst_segment_position_from_running_time_full (&segment,
780           GST_FORMAT_TIME, rt, &pos) == 1);
781   fail_unless (pos == 200);
782   fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 40, 40, NULL,
783           NULL));
784   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 40,
785           &rt) == -1);
786   fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 49, 49, NULL,
787           NULL));
788   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 49,
789           &rt) == -1);
790   fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 201, 201, NULL,
791           NULL));
792   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 201,
793           &rt) == 1);
794   fail_unless (gst_segment_position_from_running_time_full (&segment,
795           GST_FORMAT_TIME, rt, &pos) == 1);
796   fail_unless (pos == 201);
797
798   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
799           -50) == TRUE);
800   fail_unless (segment.offset == 50);
801
802   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
803           50, &rt) == -1);
804   GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
805   fail_unless (rt == 50);
806
807   segment.start = 50;
808   segment.stop = 300;
809   segment.position = 150;
810   segment.time = 0;
811   segment.offset = 0;
812   gst_segment_set_running_time (&segment, GST_FORMAT_TIME, 100);
813   fail_unless_equals_int (segment.base, 100);
814   fail_unless (gst_segment_position_from_running_time_full (&segment,
815           GST_FORMAT_TIME, 70, &pos) == -1);
816   fail_unless (gst_segment_position_from_running_time_full (&segment,
817           GST_FORMAT_TIME, 140, &pos) == 1);
818   fail_unless_equals_int (pos, 190);
819 }
820
821 GST_END_TEST;
822
823 GST_START_TEST (segment_stream_time_full)
824 {
825   GstSegment segment;
826   guint64 st, pos;
827
828   gst_segment_init (&segment, GST_FORMAT_TIME);
829
830   segment.start = 50;
831   segment.stop = 200;
832   segment.time = 30;
833   segment.position = 0;
834
835   fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
836           0, &st) == -1);
837   fail_unless_equals_int (st, 20);
838   fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
839           20, &st) == 1);
840   fail_unless_equals_int (st, 0);
841   fail_unless (gst_segment_position_from_stream_time_full (&segment,
842           GST_FORMAT_TIME, 0, &pos) == 1);
843   fail_unless_equals_int (pos, 20);
844   fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
845           10, &st) == -1);
846   fail_unless_equals_int (st, 10);
847   fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
848           40, &st) == 1);
849   fail_unless_equals_int (st, 20);
850   fail_unless (gst_segment_position_from_stream_time_full (&segment,
851           GST_FORMAT_TIME, st, &pos) == 1);
852   fail_unless_equals_int (pos, 40);
853   segment.time = 100;
854   fail_unless (gst_segment_position_from_stream_time_full (&segment,
855           GST_FORMAT_TIME, 40, &pos) == -1);
856   fail_unless_equals_int (pos, 10);
857   fail_unless (gst_segment_position_from_stream_time_full (&segment,
858           GST_FORMAT_TIME, 60, &pos) == 1);
859   fail_unless_equals_int (pos, 10);
860
861   segment.start = 50;
862   segment.position = 150;
863   segment.stop = 200;
864   segment.time = 0;
865   segment.applied_rate = -1;
866   segment.rate = -1;
867
868   fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
869           0, &st) == 1);
870   fail_unless_equals_int (st, 200);
871   fail_unless (gst_segment_position_from_stream_time_full (&segment,
872           GST_FORMAT_TIME, 200, &pos) == 1);
873   fail_unless_equals_int (pos, 0);
874   fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
875           250, &st) == -1);
876   fail_unless_equals_int (st, 50);
877   fail_unless (gst_segment_position_from_stream_time_full (&segment,
878           GST_FORMAT_TIME, 200, &pos) == 1);
879   fail_unless_equals_int (pos, 0);
880   fail_unless (gst_segment_position_from_stream_time_full (&segment,
881           GST_FORMAT_TIME, 250, &pos) == -1);
882   fail_unless_equals_int (pos, 50);
883
884   segment.time = 70;
885   fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
886           250, &st) == 1);
887   fail_unless_equals_int (st, 20);
888   fail_unless (gst_segment_position_from_stream_time_full (&segment,
889           GST_FORMAT_TIME, 50, &pos) == 1);
890   fail_unless_equals_int (pos, 220);
891   fail_unless (gst_segment_position_from_stream_time_full (&segment,
892           GST_FORMAT_TIME, 90, &pos) == 1);
893   fail_unless_equals_int (pos, 180);
894
895   segment.stop = 60;
896   fail_unless (gst_segment_position_from_stream_time_full (&segment,
897           GST_FORMAT_TIME, 5, &pos) == 1);
898   fail_unless_equals_int (pos, 125);
899 }
900
901 GST_END_TEST;
902
903 GST_START_TEST (segment_negative_rate)
904 {
905   GstSegment segment;
906
907   gst_segment_init (&segment, GST_FORMAT_TIME);
908
909   segment.start = 50;
910   segment.position = 150;
911   segment.stop = 200;
912   segment.time = 0;
913   segment.applied_rate = -1;
914   segment.rate = -1;
915
916   /* somewhere in the middle */
917   check_times (&segment, 100, 100, 100);
918   /* after stop */
919   check_times (&segment, 220, -1, -1);
920   /* before start */
921   check_times (&segment, 10, -1, -1);
922   /* at segment start */
923   check_times (&segment, 50, 150, 150);
924   /* another place in the middle */
925   check_times (&segment, 150, 50, 50);
926   /* at segment stop */
927   check_times (&segment, 200, 0, 0);
928
929   segment.time = 100;
930   segment.base = 100;
931   /* somewhere in the middle */
932   check_times (&segment, 100, 200, 200);
933   /* at segment start */
934   check_times (&segment, 50, 250, 250);
935   /* another place in the middle */
936   check_times (&segment, 150, 150, 150);
937   /* at segment stop */
938   check_times (&segment, 200, 100, 100);
939 }
940
941 GST_END_TEST;
942
943 GST_START_TEST (segment_negative_applied_rate)
944 {
945   GstSegment segment;
946
947   gst_segment_init (&segment, GST_FORMAT_TIME);
948
949   segment.start = 50;
950   segment.position = 150;
951   segment.stop = 200;
952   segment.time = 0;
953   segment.applied_rate = -1;
954   segment.rate = 1;
955
956   /* somewhere in the middle */
957   check_times (&segment, 100, 100, 50);
958   /* after stop */
959   check_times (&segment, 220, -1, -1);
960   /* before start */
961   check_times (&segment, 10, -1, -1);
962   /* at segment start */
963   check_times (&segment, 50, 150, 0);
964   /* another place in the middle */
965   check_times (&segment, 150, 50, 100);
966   /* at segment stop */
967   check_times (&segment, 200, 0, 150);
968
969   segment.time = 100;
970   segment.base = 100;
971   /* somewhere in the middle */
972   check_times (&segment, 100, 200, 150);
973   /* at segment start */
974   check_times (&segment, 50, 250, 100);
975   /* another place in the middle */
976   check_times (&segment, 150, 150, 200);
977   /* at segment stop */
978   check_times (&segment, 200, 100, 250);
979 }
980
981 GST_END_TEST;
982
983 static Suite *
984 gst_segment_suite (void)
985 {
986   Suite *s = suite_create ("GstSegment");
987   TCase *tc_chain = tcase_create ("segments");
988
989   tcase_set_timeout (tc_chain, 20);
990
991   suite_add_tcase (s, tc_chain);
992   tcase_add_test (tc_chain, segment_seek_nosize);
993   tcase_add_test (tc_chain, segment_seek_size);
994   tcase_add_test (tc_chain, segment_seek_reverse);
995   tcase_add_test (tc_chain, segment_seek_rate);
996   tcase_add_test (tc_chain, segment_copy);
997   tcase_add_test (tc_chain, segment_seek_noupdate);
998   tcase_add_test (tc_chain, segment_offset);
999   tcase_add_test (tc_chain, segment_full);
1000   tcase_add_test (tc_chain, segment_negative_rate);
1001   tcase_add_test (tc_chain, segment_negative_applied_rate);
1002   tcase_add_test (tc_chain, segment_stream_time_full);
1003
1004   return s;
1005 }
1006
1007 GST_CHECK_MAIN (gst_segment);