2 * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
3 * 2009 Wim Taymans <wim.taymans@gmail.com>
5 * gstsegment.c: Unit test for segments
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.
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.
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.
23 #include <gst/check/gstcheck.h>
25 /* mess with the segment structure in the bytes format */
26 GST_START_TEST (segment_seek_nosize)
30 guint64 cstart, cstop;
33 gst_segment_init (&segment, GST_FORMAT_BYTES);
35 /* configure segment to start 100 */
36 gst_segment_do_seek (&segment, 1.0,
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);
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);
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);
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);
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);
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);
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);
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);
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);
92 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
93 fail_unless (res == FALSE);
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);
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);
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);
113 /* add 100 to start, set stop to 300 */
114 gst_segment_do_seek (&segment, 1.0,
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);
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
126 ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
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);
136 /* seek relative to end, should not do anything since size is
138 gst_segment_do_seek (&segment, 1.0,
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);
146 /* completely outside */
147 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
148 fail_unless (res == FALSE);
150 /* touching lower bound */
151 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 200, &cstart, &cstop);
152 fail_unless (res == FALSE);
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);
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);
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);
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);
182 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
183 fail_unless (res == FALSE);
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);
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);
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);
203 /* start outside on boundary */
204 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
205 fail_unless (res == FALSE);
207 /* start completely outside */
208 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 350, -1, &cstart, &cstop);
209 fail_unless (res == FALSE);
214 /* mess with the segment structure in the bytes format */
215 GST_START_TEST (segment_seek_size)
219 guint64 cstart, cstop;
222 gst_segment_init (&segment, GST_FORMAT_BYTES);
223 segment.duration = 200;
225 /* configure segment to start 100 */
226 gst_segment_do_seek (&segment, 1.0,
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);
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);
239 /* touching lower bound */
240 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
241 fail_unless (res == FALSE);
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);
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);
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);
264 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
265 fail_unless (res == FALSE);
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);
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);
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);
285 /* add 100 to start, set stop to 300, stop clips to 200 */
286 gst_segment_do_seek (&segment, 1.0,
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);
293 /* add 100 to start (to 300), set stop to 200, this clips start
295 gst_segment_do_seek (&segment, 1.0,
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);
303 /* seek relative to end */
304 gst_segment_do_seek (&segment, 1.0,
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);
312 /* completely outside */
313 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
314 fail_unless (res == FALSE);
316 /* touching lower bound */
317 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
318 fail_unless (res == FALSE);
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);
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);
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);
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);
348 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
349 fail_unless (res == FALSE);
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);
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);
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);
369 /* start outside on boundary */
370 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
371 fail_unless (res == FALSE);
373 /* start completely outside */
374 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
375 fail_unless (res == FALSE);
380 GST_START_TEST (segment_seek_reverse)
385 gst_segment_init (&segment, GST_FORMAT_BYTES);
386 segment.duration = 200;
388 /* configure segment to stop 100 */
389 gst_segment_do_seek (&segment, -1.0,
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);
400 gst_segment_do_seek (&segment, -1.0,
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);
410 gst_segment_do_seek (&segment, -1.0,
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);
423 /* mess with the segment structure in the bytes format */
424 GST_START_TEST (segment_seek_rate)
429 gst_segment_init (&segment, GST_FORMAT_BYTES);
431 /* configure segment to rate 2.0 */
432 gst_segment_do_seek (&segment, 2.0,
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);
442 /* set a real stop position, this must happen in bytes */
443 gst_segment_do_seek (&segment, 3.0,
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
453 fail_unless (update == FALSE);
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);
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);
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);
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);
484 GST_START_TEST (segment_copy)
487 GstSegment segment = { 0.0, };
489 /* this is a boxed type copy function, we support copying NULL */
490 fail_unless (gst_segment_copy (NULL) == NULL);
492 gst_segment_init (&segment, GST_FORMAT_TIME);
495 segment.applied_rate = 1.0;
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);
511 gst_segment_suite (void)
513 Suite *s = suite_create ("GstSegment");
514 TCase *tc_chain = tcase_create ("segments");
516 tcase_set_timeout (tc_chain, 20);
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);
528 GST_CHECK_MAIN (gst_segment);