tests: remove segment accumulation checks
[platform/upstream/gstreamer.git] / tests / check / gst / gstsegment.c
1 /* GStreamer
2  * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
3  *               2009 Wim Taymans <wim.taymans@gmail.com>
4  *
5  * gstsegment.c: Unit test for segments
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 /* mess with the segment structure in the bytes format */
26 GST_START_TEST (segment_seek_nosize)
27 {
28   GstSegment segment;
29   gboolean res;
30   guint64 cstart, cstop;
31   gboolean update;
32
33   gst_segment_init (&segment, GST_FORMAT_BYTES);
34
35   /* configure segment to start 100 */
36   gst_segment_do_seek (&segment, 1.0,
37       GST_FORMAT_BYTES,
38       GST_SEEK_FLAG_NONE,
39       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
40   fail_unless (segment.start == 100);
41   fail_unless (segment.stop == -1);
42   fail_unless (update == TRUE);
43
44   /* do some clipping on the open range */
45   /* completely outside */
46   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
47   fail_unless (res == FALSE);
48
49   /* touching lower bound, still outside of the segment */
50   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
51   fail_unless (res == FALSE);
52
53   /* partially inside */
54   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
55   fail_unless (res == TRUE);
56   fail_unless (cstart == 100);
57   fail_unless (cstop == 150);
58
59   /* inside, touching lower bound */
60   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
61       100, 150, &cstart, &cstop);
62   fail_unless (res == TRUE);
63   fail_unless (cstart == 100);
64   fail_unless (cstop == 150);
65
66   /* special case, 0 duration and outside segment */
67   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 90, 90, &cstart, &cstop);
68   fail_unless (res == FALSE);
69
70   /* special case, 0 duration and touching lower bound, i.e. inside segment */
71   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
72       100, 100, &cstart, &cstop);
73   fail_unless (res == TRUE);
74   fail_unless (cstart == 100);
75   fail_unless (cstop == 100);
76
77   /* special case, 0 duration and inside the segment */
78   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
79       120, 120, &cstart, &cstop);
80   fail_unless (res == TRUE);
81   fail_unless (cstart == 120);
82   fail_unless (cstop == 120);
83
84   /* completely inside */
85   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
86       150, 200, &cstart, &cstop);
87   fail_unless (res == TRUE);
88   fail_unless (cstart == 150);
89   fail_unless (cstop == 200);
90
91   /* invalid start */
92   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
93   fail_unless (res == FALSE);
94
95   /* start outside, we don't know the stop */
96   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
97   fail_unless (res == TRUE);
98   fail_unless (cstart == 100);
99   fail_unless (cstop == -1);
100
101   /* start on lower bound */
102   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
103   fail_unless (res == TRUE);
104   fail_unless (cstart == 100);
105   fail_unless (cstop == -1);
106
107   /* start inside */
108   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
109   fail_unless (res == TRUE);
110   fail_unless (cstart == 150);
111   fail_unless (cstop == -1);
112
113   /* add 100 to start, set stop to 300 */
114   gst_segment_do_seek (&segment, 1.0,
115       GST_FORMAT_BYTES,
116       GST_SEEK_FLAG_NONE,
117       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
118   fail_unless (segment.start == 200);
119   fail_unless (segment.stop == 300);
120   fail_unless (update == TRUE);
121
122   update = FALSE;
123   /* add 100 to start (to 300), set stop to 200, this is not allowed.
124    * nothing should be updated in the segment. A g_warning is
125    * emited. */
126   ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
127           GST_FORMAT_BYTES,
128           GST_SEEK_FLAG_NONE,
129           GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update));
130   fail_unless (segment.start == 200);
131   fail_unless (segment.stop == 300);
132   /* update didn't change */
133   fail_unless (update == FALSE);
134
135   update = TRUE;
136   /* seek relative to end, should not do anything since size is
137    * unknown. */
138   gst_segment_do_seek (&segment, 1.0,
139       GST_FORMAT_BYTES,
140       GST_SEEK_FLAG_NONE,
141       GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
142   fail_unless (segment.start == 200);
143   fail_unless (segment.stop == 300);
144   fail_unless (update == FALSE);
145
146   /* completely outside */
147   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
148   fail_unless (res == FALSE);
149
150   /* touching lower bound */
151   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 200, &cstart, &cstop);
152   fail_unless (res == FALSE);
153
154   /* partially inside */
155   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 250, &cstart, &cstop);
156   fail_unless (res == TRUE);
157   fail_unless (cstart == 200);
158   fail_unless (cstop == 250);
159
160   /* inside, touching lower bound */
161   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
162       200, 250, &cstart, &cstop);
163   fail_unless (res == TRUE);
164   fail_unless (cstart == 200);
165   fail_unless (cstop == 250);
166
167   /* completely inside */
168   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
169       250, 290, &cstart, &cstop);
170   fail_unless (res == TRUE);
171   fail_unless (cstart == 250);
172   fail_unless (cstop == 290);
173
174   /* partially inside */
175   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
176       250, 350, &cstart, &cstop);
177   fail_unless (res == TRUE);
178   fail_unless (cstart == 250);
179   fail_unless (cstop == 300);
180
181   /* invalid start */
182   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
183   fail_unless (res == FALSE);
184
185   /* start outside */
186   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
187   fail_unless (res == TRUE);
188   fail_unless (cstart == 200);
189   fail_unless (cstop == 300);
190
191   /* start on lower bound */
192   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
193   fail_unless (res == TRUE);
194   fail_unless (cstart == 200);
195   fail_unless (cstop == 300);
196
197   /* start inside */
198   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
199   fail_unless (res == TRUE);
200   fail_unless (cstart == 250);
201   fail_unless (cstop == 300);
202
203   /* start outside on boundary */
204   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
205   fail_unless (res == FALSE);
206
207   /* start completely outside */
208   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 350, -1, &cstart, &cstop);
209   fail_unless (res == FALSE);
210 }
211
212 GST_END_TEST;
213
214 /* mess with the segment structure in the bytes format */
215 GST_START_TEST (segment_seek_size)
216 {
217   GstSegment segment;
218   gboolean res;
219   guint64 cstart, cstop;
220   gboolean update;
221
222   gst_segment_init (&segment, GST_FORMAT_BYTES);
223   segment.duration = 200;
224
225   /* configure segment to start 100 */
226   gst_segment_do_seek (&segment, 1.0,
227       GST_FORMAT_BYTES,
228       GST_SEEK_FLAG_NONE,
229       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
230   fail_unless (segment.start == 100);
231   fail_unless (segment.stop == -1);
232   fail_unless (update == TRUE);
233
234   /* do some clipping on the open range */
235   /* completely outside */
236   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
237   fail_unless (res == FALSE);
238
239   /* touching lower bound */
240   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
241   fail_unless (res == FALSE);
242
243   /* partially inside */
244   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
245   fail_unless (res == TRUE);
246   fail_unless (cstart == 100);
247   fail_unless (cstop == 150);
248
249   /* inside, touching lower bound */
250   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
251       100, 150, &cstart, &cstop);
252   fail_unless (res == TRUE);
253   fail_unless (cstart == 100);
254   fail_unless (cstop == 150);
255
256   /* completely inside */
257   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
258       150, 200, &cstart, &cstop);
259   fail_unless (res == TRUE);
260   fail_unless (cstart == 150);
261   fail_unless (cstop == 200);
262
263   /* invalid start */
264   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
265   fail_unless (res == FALSE);
266
267   /* start outside */
268   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
269   fail_unless (res == TRUE);
270   fail_unless (cstart == 100);
271   fail_unless (cstop == -1);
272
273   /* start on lower bound */
274   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
275   fail_unless (res == TRUE);
276   fail_unless (cstart == 100);
277   fail_unless (cstop == -1);
278
279   /* start inside */
280   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
281   fail_unless (res == TRUE);
282   fail_unless (cstart == 150);
283   fail_unless (cstop == -1);
284
285   /* add 100 to start, set stop to 300, stop clips to 200 */
286   gst_segment_do_seek (&segment, 1.0,
287       GST_FORMAT_BYTES,
288       GST_SEEK_FLAG_NONE,
289       GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
290   fail_unless (segment.start == 200);
291   fail_unless (segment.stop == 200);
292
293   /* add 100 to start (to 300), set stop to 200, this clips start
294    * to duration */
295   gst_segment_do_seek (&segment, 1.0,
296       GST_FORMAT_BYTES,
297       GST_SEEK_FLAG_NONE,
298       GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update);
299   fail_unless (segment.start == 200);
300   fail_unless (segment.stop == 200);
301   fail_unless (update == FALSE);
302
303   /* seek relative to end */
304   gst_segment_do_seek (&segment, 1.0,
305       GST_FORMAT_BYTES,
306       GST_SEEK_FLAG_NONE,
307       GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
308   fail_unless (segment.start == 100);
309   fail_unless (segment.stop == 180);
310   fail_unless (update == TRUE);
311
312   /* completely outside */
313   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
314   fail_unless (res == FALSE);
315
316   /* touching lower bound */
317   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
318   fail_unless (res == FALSE);
319
320   /* partially inside */
321   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
322   fail_unless (res == TRUE);
323   fail_unless (cstart == 100);
324   fail_unless (cstop == 150);
325
326   /* inside, touching lower bound */
327   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
328       100, 150, &cstart, &cstop);
329   fail_unless (res == TRUE);
330   fail_unless (cstart == 100);
331   fail_unless (cstop == 150);
332
333   /* completely inside */
334   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
335       150, 170, &cstart, &cstop);
336   fail_unless (res == TRUE);
337   fail_unless (cstart == 150);
338   fail_unless (cstop == 170);
339
340   /* partially inside */
341   res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
342       150, 250, &cstart, &cstop);
343   fail_unless (res == TRUE);
344   fail_unless (cstart == 150);
345   fail_unless (cstop == 180);
346
347   /* invalid start */
348   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
349   fail_unless (res == FALSE);
350
351   /* start outside */
352   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
353   fail_unless (res == TRUE);
354   fail_unless (cstart == 100);
355   fail_unless (cstop == 180);
356
357   /* start on lower bound */
358   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
359   fail_unless (res == TRUE);
360   fail_unless (cstart == 100);
361   fail_unless (cstop == 180);
362
363   /* start inside */
364   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
365   fail_unless (res == TRUE);
366   fail_unless (cstart == 150);
367   fail_unless (cstop == 180);
368
369   /* start outside on boundary */
370   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
371   fail_unless (res == FALSE);
372
373   /* start completely outside */
374   res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
375   fail_unless (res == FALSE);
376 }
377
378 GST_END_TEST;
379
380 GST_START_TEST (segment_seek_reverse)
381 {
382   GstSegment segment;
383   gboolean update;
384
385   gst_segment_init (&segment, GST_FORMAT_BYTES);
386   segment.duration = 200;
387
388   /* configure segment to stop 100 */
389   gst_segment_do_seek (&segment, -1.0,
390       GST_FORMAT_BYTES,
391       GST_SEEK_FLAG_NONE,
392       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
393   fail_unless (segment.start == 0);
394   fail_unless (segment.stop == 100);
395   fail_unless (segment.time == 0);
396   fail_unless (segment.position == 100);
397   fail_unless (update == TRUE);
398
399   /* update */
400   gst_segment_do_seek (&segment, -1.0,
401       GST_FORMAT_BYTES,
402       GST_SEEK_FLAG_NONE,
403       GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_SET, 100 - 20, &update);
404   fail_unless (segment.start == 10);
405   fail_unless (segment.stop == 80);
406   fail_unless (segment.time == 10);
407   fail_unless (segment.position == 80);
408   fail_unless (update == TRUE);
409
410   gst_segment_do_seek (&segment, -1.0,
411       GST_FORMAT_BYTES,
412       GST_SEEK_FLAG_NONE,
413       GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
414   fail_unless (segment.start == 20);
415   fail_unless (segment.stop == 80);
416   fail_unless (segment.time == 20);
417   fail_unless (segment.position == 80);
418   fail_unless (update == FALSE);
419 }
420
421 GST_END_TEST;
422
423 /* mess with the segment structure in the bytes format */
424 GST_START_TEST (segment_seek_rate)
425 {
426   GstSegment segment;
427   gboolean update;
428
429   gst_segment_init (&segment, GST_FORMAT_BYTES);
430
431   /* configure segment to rate 2.0 */
432   gst_segment_do_seek (&segment, 2.0,
433       GST_FORMAT_BYTES,
434       GST_SEEK_FLAG_NONE,
435       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
436   fail_unless (segment.format == GST_FORMAT_BYTES);
437   fail_unless (segment.start == 0);
438   fail_unless (segment.stop == -1);
439   fail_unless (segment.rate == 2.0);
440   fail_unless (update == FALSE);
441
442   /* set a real stop position, this must happen in bytes */
443   gst_segment_do_seek (&segment, 3.0,
444       GST_FORMAT_BYTES,
445       GST_SEEK_FLAG_NONE,
446       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
447   fail_unless (segment.format == GST_FORMAT_BYTES);
448   fail_unless (segment.start == 0);
449   fail_unless (segment.stop == 100);
450   fail_unless (segment.rate == 3.0);
451   /* no seek should happen, we just updated the stop position in forward
452    * playback mode.*/
453   fail_unless (update == FALSE);
454
455   /* set some duration, stop -1 END seeks will now work with the
456    * duration, if the formats match */
457   segment.duration = 200;
458   fail_unless (segment.duration == 200);
459
460   /* seek to end with 0 should set the stop to the duration */
461   gst_segment_do_seek (&segment, 2.0,
462       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
463       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
464   fail_unless (segment.stop == 200);
465   fail_unless (segment.duration == 200);
466
467   /* subtract 100 from the end */
468   gst_segment_do_seek (&segment, 2.0,
469       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
470       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
471   fail_unless (segment.stop == 100);
472   fail_unless (segment.duration == 200);
473
474   /* add 100 to the duration, this should be clamped to the duration */
475   gst_segment_do_seek (&segment, 2.0,
476       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
477       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
478   fail_unless (segment.stop == 200);
479   fail_unless (segment.duration == 200);
480 }
481
482 GST_END_TEST;
483
484 GST_START_TEST (segment_copy)
485 {
486   GstSegment *copy;
487   GstSegment segment = { 0.0, };
488
489   /* this is a boxed type copy function, we support copying NULL */
490   fail_unless (gst_segment_copy (NULL) == NULL);
491
492   gst_segment_init (&segment, GST_FORMAT_TIME);
493
494   segment.rate = -1.0;
495   segment.applied_rate = 1.0;
496   segment.start = 0;
497   segment.stop = 200;
498   segment.time = 0;
499
500   copy = gst_segment_copy (&segment);
501   fail_unless (copy != NULL);
502   /* we inited the struct on the stack to zeroes, so direct comparison should
503    * be ok here despite the padding field and regardless of implementation */
504   fail_unless (memcmp (copy, &segment, sizeof (GstSegment)) == 0);
505   gst_segment_free (copy);
506 }
507
508 GST_END_TEST;
509
510 static Suite *
511 gst_segment_suite (void)
512 {
513   Suite *s = suite_create ("GstSegment");
514   TCase *tc_chain = tcase_create ("segments");
515
516   tcase_set_timeout (tc_chain, 20);
517
518   suite_add_tcase (s, tc_chain);
519   tcase_add_test (tc_chain, segment_seek_nosize);
520   tcase_add_test (tc_chain, segment_seek_size);
521   tcase_add_test (tc_chain, segment_seek_reverse);
522   tcase_add_test (tc_chain, segment_seek_rate);
523   tcase_add_test (tc_chain, segment_copy);
524
525   return s;
526 }
527
528 GST_CHECK_MAIN (gst_segment);