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., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
26 #include <gst/check/gstcheck.h>
28 #define check_times(segment, position, stream_time, running_time) G_STMT_START { \
29 guint64 st, rt, pos; \
31 st = gst_segment_to_stream_time ((segment), (segment)->format, (position)); \
32 rt = gst_segment_to_running_time ((segment), (segment)->format, (position)); \
33 GST_DEBUG ("position %" G_GUINT64_FORMAT ", st %" G_GUINT64_FORMAT ", rt %" \
34 G_GUINT64_FORMAT, (guint64) (position), (guint64) (stream_time), (guint64) (running_time)); \
36 fail_unless_equals_int64 (st, (stream_time)); \
37 fail_unless_equals_int64 (rt, (running_time)); \
38 if ((stream_time) != -1) { \
39 pos = gst_segment_position_from_stream_time ((segment), (segment)->format, st); \
40 fail_unless_equals_int64 (pos, (position)); \
43 if ((running_time) != -1) { \
44 pos = gst_segment_position_from_running_time ((segment), (segment)->format, rt); \
45 fail_unless_equals_int64 (pos, (position)); \
49 /* mess with the segment structure in the bytes format */
50 GST_START_TEST (segment_seek_nosize)
54 guint64 cstart, cstop;
57 gst_segment_init (&segment, GST_FORMAT_BYTES);
59 /* configure segment to start 100 */
60 gst_segment_do_seek (&segment, 1.0,
63 GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
64 fail_unless_equals_uint64 (segment.start, 100);
65 fail_unless_equals_uint64 (segment.position, 100);
66 fail_unless_equals_uint64 (segment.stop, -1);
67 fail_unless (update == TRUE);
68 /* appended after current position 0 */
69 check_times (&segment, 100, 100, 0);
71 /* do some clipping on the open range */
72 /* completely outside */
73 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
74 fail_unless (res == FALSE);
76 /* touching lower bound, still outside of the segment */
77 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
78 fail_unless (res == FALSE);
80 /* partially inside */
81 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
82 fail_unless (res == TRUE);
83 fail_unless_equals_uint64 (cstart, 100);
84 fail_unless_equals_uint64 (cstop, 150);
86 /* inside, touching lower bound */
87 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
88 100, 150, &cstart, &cstop);
89 fail_unless (res == TRUE);
90 fail_unless_equals_uint64 (cstart, 100);
91 fail_unless_equals_uint64 (cstop, 150);
93 /* special case, 0 duration and outside segment */
94 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 90, 90, &cstart, &cstop);
95 fail_unless (res == FALSE);
97 /* special case, 0 duration and touching lower bound, i.e. inside segment */
98 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
99 100, 100, &cstart, &cstop);
100 fail_unless (res == TRUE);
101 fail_unless_equals_uint64 (cstart, 100);
102 fail_unless_equals_uint64 (cstop, 100);
104 /* special case, 0 duration and inside the segment */
105 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
106 120, 120, &cstart, &cstop);
107 fail_unless (res == TRUE);
108 fail_unless_equals_uint64 (cstart, 120);
109 fail_unless_equals_uint64 (cstop, 120);
111 /* completely inside */
112 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
113 150, 200, &cstart, &cstop);
114 fail_unless (res == TRUE);
115 fail_unless_equals_uint64 (cstart, 150);
116 fail_unless_equals_uint64 (cstop, 200);
119 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
120 fail_unless (res == FALSE);
122 /* start outside, we don't know the stop */
123 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
124 fail_unless (res == TRUE);
125 fail_unless_equals_uint64 (cstart, 100);
126 fail_unless_equals_int64 (cstop, -1);
128 /* start on lower bound */
129 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
130 fail_unless (res == TRUE);
131 fail_unless_equals_uint64 (cstart, 100);
132 fail_unless_equals_int64 (cstop, -1);
135 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
136 fail_unless (res == TRUE);
137 fail_unless_equals_uint64 (cstart, 150);
138 fail_unless_equals_int64 (cstop, -1);
140 /* move to 150, this is a running_time of 50 */
141 segment.position = 150;
142 check_times (&segment, 150, 150, 50);
144 /* add 100 to start, set stop to 300 */
145 gst_segment_do_seek (&segment, 1.0,
148 GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
149 fail_unless_equals_uint64 (segment.start, 200);
150 fail_unless_equals_uint64 (segment.position, 200);
151 fail_unless_equals_uint64 (segment.stop, 300);
152 fail_unless_equals_uint64 (segment.base, 50);
153 fail_unless (update == TRUE);
154 check_times (&segment, 200, 200, 50);
155 check_times (&segment, 250, 250, 100);
158 /* add 100 to start (to 300), set stop to 200, this is not allowed.
159 * nothing should be updated in the segment. A g_warning is
161 ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
164 GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update));
165 fail_unless_equals_uint64 (segment.start, 200);
166 fail_unless_equals_uint64 (segment.position, 200);
167 fail_unless_equals_uint64 (segment.stop, 300);
168 fail_unless_equals_uint64 (segment.base, 50);
169 /* update didn't change */
170 fail_unless (update == FALSE);
171 check_times (&segment, 200, 200, 50);
172 check_times (&segment, 250, 250, 100);
175 /* seek relative to end, should not do anything since size is
177 gst_segment_do_seek (&segment, 1.0,
180 GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
181 fail_unless_equals_uint64 (segment.start, 200);
182 fail_unless_equals_uint64 (segment.position, 200);
183 fail_unless_equals_uint64 (segment.stop, 300);
184 fail_unless_equals_uint64 (segment.base, 50);
185 fail_unless (update == FALSE);
186 check_times (&segment, 250, 250, 100);
188 /* completely outside */
189 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
190 fail_unless (res == FALSE);
192 /* touching lower bound */
193 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 200, &cstart, &cstop);
194 fail_unless (res == FALSE);
196 /* partially inside */
197 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 250, &cstart, &cstop);
198 fail_unless (res == TRUE);
199 fail_unless_equals_uint64 (cstart, 200);
200 fail_unless_equals_uint64 (cstop, 250);
202 /* inside, touching lower bound */
203 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
204 200, 250, &cstart, &cstop);
205 fail_unless (res == TRUE);
206 fail_unless_equals_uint64 (cstart, 200);
207 fail_unless_equals_uint64 (cstop, 250);
209 /* completely inside */
210 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
211 250, 290, &cstart, &cstop);
212 fail_unless (res == TRUE);
213 fail_unless_equals_uint64 (cstart, 250);
214 fail_unless_equals_uint64 (cstop, 290);
216 /* partially inside */
217 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
218 250, 350, &cstart, &cstop);
219 fail_unless (res == TRUE);
220 fail_unless_equals_uint64 (cstart, 250);
221 fail_unless_equals_uint64 (cstop, 300);
224 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
225 fail_unless (res == FALSE);
228 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
229 fail_unless (res == TRUE);
230 fail_unless_equals_uint64 (cstart, 200);
231 fail_unless_equals_uint64 (cstop, 300);
233 /* start on lower bound */
234 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
235 fail_unless (res == TRUE);
236 fail_unless_equals_uint64 (cstart, 200);
237 fail_unless_equals_uint64 (cstop, 300);
240 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
241 fail_unless (res == TRUE);
242 fail_unless_equals_uint64 (cstart, 250);
243 fail_unless_equals_uint64 (cstop, 300);
245 /* start outside on boundary */
246 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
247 fail_unless (res == FALSE);
249 /* start completely outside */
250 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 350, -1, &cstart, &cstop);
251 fail_unless (res == FALSE);
256 /* mess with the segment structure in the bytes format */
257 GST_START_TEST (segment_seek_size)
261 guint64 cstart, cstop;
264 gst_segment_init (&segment, GST_FORMAT_BYTES);
265 segment.duration = 200;
267 /* configure segment to start 100 */
268 gst_segment_do_seek (&segment, 1.0,
271 GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
272 fail_unless_equals_uint64 (segment.start, 100);
273 fail_unless_equals_uint64 (segment.position, 100);
274 fail_unless_equals_int64 (segment.stop, -1);
275 fail_unless (update == TRUE);
276 check_times (&segment, 100, 100, 0);
278 /* do some clipping on the open range */
279 /* completely outside */
280 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
281 fail_unless (res == FALSE);
283 /* touching lower bound */
284 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
285 fail_unless (res == FALSE);
287 /* partially inside */
288 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
289 fail_unless (res == TRUE);
290 fail_unless_equals_uint64 (cstart, 100);
291 fail_unless_equals_uint64 (cstop, 150);
293 /* inside, touching lower bound */
294 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
295 100, 150, &cstart, &cstop);
296 fail_unless (res == TRUE);
297 fail_unless_equals_uint64 (cstart, 100);
298 fail_unless_equals_uint64 (cstop, 150);
300 /* completely inside */
301 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
302 150, 200, &cstart, &cstop);
303 fail_unless (res == TRUE);
304 fail_unless_equals_uint64 (cstart, 150);
305 fail_unless_equals_uint64 (cstop, 200);
308 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
309 fail_unless (res == FALSE);
312 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
313 fail_unless (res == TRUE);
314 fail_unless_equals_uint64 (cstart, 100);
315 fail_unless_equals_int64 (cstop, -1);
317 /* start on lower bound */
318 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
319 fail_unless (res == TRUE);
320 fail_unless_equals_uint64 (cstart, 100);
321 fail_unless_equals_uint64 (cstop, -1);
324 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
325 fail_unless (res == TRUE);
326 fail_unless_equals_uint64 (cstart, 150);
327 fail_unless_equals_uint64 (cstop, -1);
329 /* add 100 to start, set stop to 300, stop clips to 200 */
330 gst_segment_do_seek (&segment, 1.0,
333 GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
334 fail_unless_equals_uint64 (segment.start, 200);
335 fail_unless_equals_uint64 (segment.position, 200);
336 fail_unless_equals_uint64 (segment.stop, 200);
337 check_times (&segment, 200, 200, 0);
339 /* add 100 to start (to 300), set stop to 200, this clips start
341 gst_segment_do_seek (&segment, 1.0,
344 GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update);
345 fail_unless_equals_uint64 (segment.start, 200);
346 fail_unless_equals_uint64 (segment.position, 200);
347 fail_unless_equals_uint64 (segment.stop, 200);
348 fail_unless (update == FALSE);
349 check_times (&segment, 200, 200, 0);
351 /* special case, segment's start and stop are identical */
352 /* completely outside */
353 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
354 fail_unless (res == FALSE);
356 /* completely outside also */
357 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
358 250, 300, &cstart, &cstop);
359 fail_unless (res == FALSE);
361 /* stop at boundary point. it's outside because stop is exclusive */
362 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
363 100, 200, &cstart, &cstop);
364 fail_unless (res == FALSE);
366 /* touching boundary point. it's inside because start at segment start */
367 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
368 200, 300, &cstart, &cstop);
369 fail_unless (res == TRUE);
370 fail_unless_equals_uint64 (cstart, 200);
371 fail_unless_equals_uint64 (cstop, 200);
373 /* completely inside */
374 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
375 200, 200, &cstart, &cstop);
376 fail_unless (res == TRUE);
377 fail_unless_equals_uint64 (cstart, 200);
378 fail_unless_equals_uint64 (cstop, 200);
380 /* exclusively cover boundary point */
381 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
382 150, 250, &cstart, &cstop);
383 fail_unless (res == TRUE);
384 fail_unless_equals_uint64 (cstart, 200);
385 fail_unless_equals_uint64 (cstop, 200);
388 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 200, &cstart, &cstop);
389 fail_unless (res == FALSE);
392 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
393 fail_unless (res == TRUE);
394 fail_unless_equals_uint64 (cstart, 200);
395 fail_unless_equals_uint64 (cstop, 200);
397 /* start on boundary point */
398 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
399 fail_unless (res == TRUE);
400 fail_unless_equals_uint64 (cstart, 200);
401 fail_unless_equals_uint64 (cstop, 200);
403 /* start completely outside */
404 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
405 fail_unless (res == FALSE);
407 /* seek relative to end */
408 gst_segment_do_seek (&segment, 1.0,
411 GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
412 fail_unless_equals_uint64 (segment.start, 100);
413 fail_unless_equals_uint64 (segment.position, 100);
414 fail_unless_equals_uint64 (segment.stop, 180);
415 fail_unless (update == TRUE);
416 check_times (&segment, 150, 150, 50);
418 /* completely outside */
419 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
420 fail_unless (res == FALSE);
422 /* touching lower bound */
423 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
424 fail_unless (res == FALSE);
426 /* partially inside */
427 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
428 fail_unless (res == TRUE);
429 fail_unless_equals_uint64 (cstart, 100);
430 fail_unless_equals_uint64 (cstop, 150);
432 /* inside, touching lower bound */
433 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
434 100, 150, &cstart, &cstop);
435 fail_unless (res == TRUE);
436 fail_unless_equals_uint64 (cstart, 100);
437 fail_unless_equals_uint64 (cstop, 150);
439 /* completely inside */
440 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
441 150, 170, &cstart, &cstop);
442 fail_unless (res == TRUE);
443 fail_unless_equals_uint64 (cstart, 150);
444 fail_unless_equals_uint64 (cstop, 170);
446 /* partially inside */
447 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
448 150, 250, &cstart, &cstop);
449 fail_unless (res == TRUE);
450 fail_unless_equals_uint64 (cstart, 150);
451 fail_unless_equals_uint64 (cstop, 180);
454 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
455 fail_unless (res == FALSE);
458 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
459 fail_unless (res == TRUE);
460 fail_unless_equals_uint64 (cstart, 100);
461 fail_unless_equals_uint64 (cstop, 180);
463 /* start on lower bound */
464 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
465 fail_unless (res == TRUE);
466 fail_unless_equals_uint64 (cstart, 100);
467 fail_unless_equals_uint64 (cstop, 180);
470 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
471 fail_unless (res == TRUE);
472 fail_unless_equals_uint64 (cstart, 150);
473 fail_unless_equals_uint64 (cstop, 180);
475 /* start outside on boundary */
476 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
477 fail_unless (res == FALSE);
479 /* start completely outside */
480 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
481 fail_unless (res == FALSE);
486 GST_START_TEST (segment_seek_reverse)
491 gst_segment_init (&segment, GST_FORMAT_BYTES);
492 segment.duration = 200;
494 /* configure segment to stop 100 */
495 gst_segment_do_seek (&segment, -1.0,
498 GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
499 fail_unless_equals_uint64 (segment.start, 0);
500 fail_unless_equals_uint64 (segment.stop, 100);
501 fail_unless_equals_uint64 (segment.time, 0);
502 fail_unless_equals_uint64 (segment.position, 100);
503 fail_unless (update == TRUE);
504 check_times (&segment, 100, 100, 0);
505 check_times (&segment, 50, 50, 50);
506 check_times (&segment, 0, 0, 100);
509 gst_segment_do_seek (&segment, -1.0,
512 GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_SET, 100 - 20, &update);
513 fail_unless_equals_uint64 (segment.start, 10);
514 fail_unless_equals_uint64 (segment.stop, 80);
515 fail_unless_equals_uint64 (segment.time, 10);
516 fail_unless_equals_uint64 (segment.position, 80);
517 fail_unless (update == TRUE);
518 check_times (&segment, 80, 80, 0);
519 check_times (&segment, 40, 40, 40);
520 check_times (&segment, 10, 10, 70);
522 gst_segment_do_seek (&segment, -1.0,
525 GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
526 fail_unless_equals_uint64 (segment.start, 20);
527 fail_unless_equals_uint64 (segment.stop, 80);
528 fail_unless_equals_uint64 (segment.time, 20);
529 fail_unless_equals_uint64 (segment.position, 80);
530 fail_unless (update == FALSE);
531 check_times (&segment, 80, 80, 0);
532 check_times (&segment, 20, 20, 60);
537 /* mess with the segment structure in the bytes format */
538 GST_START_TEST (segment_seek_rate)
543 gst_segment_init (&segment, GST_FORMAT_BYTES);
545 /* configure segment to rate 2.0 */
546 gst_segment_do_seek (&segment, 2.0,
549 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
550 fail_unless (segment.format == GST_FORMAT_BYTES);
551 fail_unless_equals_uint64 (segment.start, 0);
552 fail_unless_equals_uint64 (segment.position, 0);
553 fail_unless_equals_int64 (segment.stop, -1);
554 fail_unless_equals_float (segment.rate, 2.0);
555 fail_unless (update == FALSE);
556 check_times (&segment, 50, 50, 25);
558 /* set a real stop position, this must happen in bytes */
559 gst_segment_do_seek (&segment, 3.0,
562 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
563 fail_unless (segment.format == GST_FORMAT_BYTES);
564 fail_unless_equals_uint64 (segment.start, 0);
565 fail_unless_equals_uint64 (segment.stop, 100);
566 fail_unless_equals_float (segment.rate, 3.0);
567 /* no seek should happen, we just updated the stop position in forward
569 fail_unless (update == FALSE);
570 check_times (&segment, 60, 60, 20);
572 /* set some duration, stop -1 END seeks will now work with the
573 * duration, if the formats match */
574 segment.duration = 200;
576 /* seek to end with 0 should set the stop to the duration */
577 gst_segment_do_seek (&segment, 2.0,
578 GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
579 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
580 fail_unless_equals_uint64 (segment.stop, 200);
581 fail_unless_equals_uint64 (segment.duration, 200);
583 /* subtract 100 from the end */
584 gst_segment_do_seek (&segment, 2.0,
585 GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
586 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
587 fail_unless_equals_uint64 (segment.stop, 100);
588 fail_unless_equals_uint64 (segment.duration, 200);
590 /* add 100 to the duration, this should be clamped to the duration */
591 gst_segment_do_seek (&segment, 2.0,
592 GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
593 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
594 fail_unless_equals_uint64 (segment.stop, 200);
595 fail_unless_equals_uint64 (segment.duration, 200);
600 GST_START_TEST (segment_copy)
603 GstSegment segment = { 0.0, };
605 /* this is a boxed type copy function, we support copying NULL */
606 fail_unless (gst_segment_copy (NULL) == NULL);
608 gst_segment_init (&segment, GST_FORMAT_TIME);
611 segment.applied_rate = 1.0;
616 copy = gst_segment_copy (&segment);
617 fail_unless (copy != NULL);
618 /* we inited the struct on the stack to zeroes, so direct comparison should
619 * be ok here despite the padding field and regardless of implementation */
620 fail_unless (memcmp (copy, &segment, sizeof (GstSegment)) == 0);
621 gst_segment_free (copy);
626 /* mess with the segment structure in the bytes format */
627 GST_START_TEST (segment_seek_noupdate)
632 gst_segment_init (&segment, GST_FORMAT_TIME);
635 segment.position = 50;
639 /* doesn't change anything */
640 gst_segment_do_seek (&segment, 1.0,
643 GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
644 fail_unless (update == FALSE);
645 fail_unless (segment.format == GST_FORMAT_TIME);
646 fail_unless_equals_uint64 (segment.start, 0);
647 fail_unless_equals_uint64 (segment.stop, 200);
648 fail_unless_equals_uint64 (segment.time, 0);
649 fail_unless_equals_uint64 (segment.position, 50);
650 fail_unless_equals_uint64 (segment.base, 50);
651 fail_unless_equals_uint64 (segment.offset, 50);
653 gst_segment_do_seek (&segment, 2.0,
656 GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
657 fail_unless (update == FALSE);
658 fail_unless (segment.format == GST_FORMAT_TIME);
659 fail_unless_equals_uint64 (segment.start, 0);
660 fail_unless_equals_uint64 (segment.stop, 200);
661 fail_unless_equals_uint64 (segment.time, 0);
662 fail_unless_equals_uint64 (segment.position, 50);
663 fail_unless_equals_uint64 (segment.base, 50);
664 fail_unless_equals_uint64 (segment.offset, 50);
666 gst_segment_do_seek (&segment, 1.0,
669 GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
670 fail_unless (update == FALSE);
671 fail_unless (segment.format == GST_FORMAT_TIME);
672 fail_unless_equals_uint64 (segment.start, 0);
673 fail_unless_equals_uint64 (segment.stop, 200);
674 fail_unless_equals_uint64 (segment.time, 0);
675 fail_unless_equals_uint64 (segment.position, 50);
676 fail_unless_equals_uint64 (segment.base, 0);
677 fail_unless_equals_uint64 (segment.offset, 50);
682 GST_START_TEST (segment_offset)
686 gst_segment_init (&segment, GST_FORMAT_TIME);
689 segment.position = 50;
693 check_times (&segment, 20, 20, 20);
694 check_times (&segment, 220, -1, -1);
696 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
698 fail_unless_equals_uint64 (segment.start, 0);
699 fail_unless_equals_uint64 (segment.stop, 200);
700 fail_unless_equals_uint64 (segment.time, 0);
701 fail_unless_equals_uint64 (segment.position, 50);
702 fail_unless_equals_uint64 (segment.base, 0);
703 fail_unless_equals_uint64 (segment.offset, 0);
704 check_times (&segment, 20, 20, 20);
706 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
708 fail_unless_equals_uint64 (segment.start, 0);
709 fail_unless_equals_uint64 (segment.stop, 200);
710 fail_unless_equals_uint64 (segment.time, 0);
711 fail_unless_equals_uint64 (segment.position, 50);
712 fail_unless_equals_uint64 (segment.base, 100);
713 fail_unless_equals_uint64 (segment.offset, 0);
714 check_times (&segment, 20, 20, 120);
716 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
718 fail_unless_equals_uint64 (segment.start, 0);
719 fail_unless_equals_uint64 (segment.stop, 200);
720 fail_unless_equals_uint64 (segment.time, 0);
721 fail_unless_equals_uint64 (segment.position, 50);
722 fail_unless_equals_uint64 (segment.base, 50);
723 fail_unless_equals_uint64 (segment.offset, 0);
724 check_times (&segment, 20, 20, 70);
726 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
728 fail_unless_equals_uint64 (segment.start, 0);
729 fail_unless_equals_uint64 (segment.stop, 200);
730 fail_unless_equals_uint64 (segment.time, 0);
731 fail_unless_equals_uint64 (segment.position, 50);
732 fail_unless_equals_uint64 (segment.base, 0);
733 fail_unless_equals_uint64 (segment.offset, 50);
734 check_times (&segment, 20, 20, -1);
735 check_times (&segment, 200, 200, 150);
737 /* can go negative */
738 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
740 fail_unless_equals_uint64 (segment.start, 0);
741 fail_unless_equals_uint64 (segment.stop, 200);
742 fail_unless_equals_uint64 (segment.time, 0);
743 fail_unless_equals_uint64 (segment.position, 50);
744 fail_unless_equals_uint64 (segment.base, 0);
745 fail_unless_equals_uint64 (segment.offset, 50);
746 check_times (&segment, 100, 100, 50);
747 check_times (&segment, 200, 200, 150);
749 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
751 fail_unless_equals_uint64 (segment.start, 0);
752 fail_unless_equals_uint64 (segment.stop, 200);
753 fail_unless_equals_uint64 (segment.time, 0);
754 fail_unless_equals_uint64 (segment.position, 50);
755 fail_unless_equals_uint64 (segment.base, 0);
756 fail_unless_equals_uint64 (segment.offset, 200);
757 check_times (&segment, 200, 200, 0);
759 gst_segment_init (&segment, GST_FORMAT_TIME);
762 segment.position = 50;
766 check_times (&segment, 40, 20, 20);
767 check_times (&segment, 240, -1, -1);
769 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
771 fail_unless_equals_uint64 (segment.start, 20);
772 fail_unless_equals_uint64 (segment.stop, 220);
773 fail_unless_equals_uint64 (segment.time, 0);
774 fail_unless_equals_uint64 (segment.position, 50);
775 fail_unless_equals_uint64 (segment.base, 0);
776 fail_unless_equals_uint64 (segment.offset, 0);
777 check_times (&segment, 40, 20, 20);
779 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
781 fail_unless_equals_uint64 (segment.start, 20);
782 fail_unless_equals_uint64 (segment.stop, 220);
783 fail_unless_equals_uint64 (segment.time, 0);
784 fail_unless_equals_uint64 (segment.position, 50);
785 fail_unless_equals_uint64 (segment.base, 100);
786 fail_unless_equals_uint64 (segment.offset, 0);
787 check_times (&segment, 40, 20, 120);
789 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
791 fail_unless_equals_uint64 (segment.start, 20);
792 fail_unless_equals_uint64 (segment.stop, 220);
793 fail_unless_equals_uint64 (segment.time, 0);
794 fail_unless_equals_uint64 (segment.position, 50);
795 fail_unless_equals_uint64 (segment.base, 50);
796 fail_unless_equals_uint64 (segment.offset, 0);
797 check_times (&segment, 40, 20, 70);
799 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
801 fail_unless_equals_uint64 (segment.start, 20);
802 fail_unless_equals_uint64 (segment.stop, 220);
803 fail_unless_equals_uint64 (segment.time, 0);
804 fail_unless_equals_uint64 (segment.position, 50);
805 fail_unless_equals_uint64 (segment.base, 0);
806 fail_unless_equals_uint64 (segment.offset, 50);
807 check_times (&segment, 40, 20, -1);
808 check_times (&segment, 220, 200, 150);
813 GST_START_TEST (segment_full)
818 gst_segment_init (&segment, GST_FORMAT_TIME);
821 segment.position = 150;
825 check_times (&segment, 100, 50, 50);
826 check_times (&segment, 220, -1, -1);
828 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
830 fail_unless (rt == 0);
831 fail_unless (gst_segment_position_from_running_time_full (&segment,
832 GST_FORMAT_TIME, rt, &pos) == 1);
833 fail_unless (pos == 50);
834 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
836 fail_unless (rt == 150);
837 fail_unless (gst_segment_position_from_running_time_full (&segment,
838 GST_FORMAT_TIME, rt, &pos) == 1);
839 fail_unless (pos == 200);
840 fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 40, 40, NULL,
842 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 40,
844 fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 49, 49, NULL,
846 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 49,
848 fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 201, 201, NULL,
850 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 201,
852 fail_unless (gst_segment_position_from_running_time_full (&segment,
853 GST_FORMAT_TIME, rt, &pos) == 1);
854 fail_unless (pos == 201);
856 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
858 fail_unless (segment.offset == 50);
860 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
862 GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
863 fail_unless (rt == 50);
867 segment.position = 150;
870 gst_segment_set_running_time (&segment, GST_FORMAT_TIME, 100);
871 fail_unless_equals_int (segment.base, 100);
872 fail_unless (gst_segment_position_from_running_time_full (&segment,
873 GST_FORMAT_TIME, 70, &pos) == -1);
874 fail_unless (gst_segment_position_from_running_time_full (&segment,
875 GST_FORMAT_TIME, 140, &pos) == 1);
876 fail_unless_equals_int (pos, 190);
881 GST_START_TEST (segment_stream_time_full)
886 gst_segment_init (&segment, GST_FORMAT_TIME);
891 segment.position = 0;
893 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
895 fail_unless_equals_int (st, 20);
896 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
898 fail_unless_equals_int (st, 0);
899 fail_unless (gst_segment_position_from_stream_time_full (&segment,
900 GST_FORMAT_TIME, 0, &pos) == 1);
901 fail_unless_equals_int (pos, 20);
902 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
904 fail_unless_equals_int (st, 10);
905 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
907 fail_unless_equals_int (st, 20);
908 fail_unless (gst_segment_position_from_stream_time_full (&segment,
909 GST_FORMAT_TIME, st, &pos) == 1);
910 fail_unless_equals_int (pos, 40);
912 fail_unless (gst_segment_position_from_stream_time_full (&segment,
913 GST_FORMAT_TIME, 40, &pos) == -1);
914 fail_unless_equals_int (pos, 10);
915 fail_unless (gst_segment_position_from_stream_time_full (&segment,
916 GST_FORMAT_TIME, 60, &pos) == 1);
917 fail_unless_equals_int (pos, 10);
920 segment.position = 150;
923 segment.applied_rate = -1;
926 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
928 fail_unless_equals_int (st, 200);
929 fail_unless (gst_segment_position_from_stream_time_full (&segment,
930 GST_FORMAT_TIME, 200, &pos) == 1);
931 fail_unless_equals_int (pos, 0);
932 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
934 fail_unless_equals_int (st, 50);
935 fail_unless (gst_segment_position_from_stream_time_full (&segment,
936 GST_FORMAT_TIME, 200, &pos) == 1);
937 fail_unless_equals_int (pos, 0);
938 fail_unless (gst_segment_position_from_stream_time_full (&segment,
939 GST_FORMAT_TIME, 250, &pos) == -1);
940 fail_unless_equals_int (pos, 50);
943 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
945 fail_unless_equals_int (st, 20);
946 fail_unless (gst_segment_position_from_stream_time_full (&segment,
947 GST_FORMAT_TIME, 50, &pos) == 1);
948 fail_unless_equals_int (pos, 220);
949 fail_unless (gst_segment_position_from_stream_time_full (&segment,
950 GST_FORMAT_TIME, 90, &pos) == 1);
951 fail_unless_equals_int (pos, 180);
954 fail_unless (gst_segment_position_from_stream_time_full (&segment,
955 GST_FORMAT_TIME, 5, &pos) == 1);
956 fail_unless_equals_int (pos, 125);
961 GST_START_TEST (segment_negative_rate)
965 gst_segment_init (&segment, GST_FORMAT_TIME);
968 segment.position = 150;
971 segment.applied_rate = -1;
974 /* somewhere in the middle */
975 check_times (&segment, 100, 100, 100);
977 check_times (&segment, 220, -1, -1);
979 check_times (&segment, 10, -1, -1);
980 /* at segment start */
981 check_times (&segment, 50, 150, 150);
982 /* another place in the middle */
983 check_times (&segment, 150, 50, 50);
984 /* at segment stop */
985 check_times (&segment, 200, 0, 0);
989 /* somewhere in the middle */
990 check_times (&segment, 100, 200, 200);
991 /* at segment start */
992 check_times (&segment, 50, 250, 250);
993 /* another place in the middle */
994 check_times (&segment, 150, 150, 150);
995 /* at segment stop */
996 check_times (&segment, 200, 100, 100);
1001 GST_START_TEST (segment_negative_applied_rate)
1005 gst_segment_init (&segment, GST_FORMAT_TIME);
1008 segment.position = 150;
1011 segment.applied_rate = -1;
1014 /* somewhere in the middle */
1015 check_times (&segment, 100, 100, 50);
1017 check_times (&segment, 220, -1, -1);
1019 check_times (&segment, 10, -1, -1);
1020 /* at segment start */
1021 check_times (&segment, 50, 150, 0);
1022 /* another place in the middle */
1023 check_times (&segment, 150, 50, 100);
1024 /* at segment stop */
1025 check_times (&segment, 200, 0, 150);
1029 /* somewhere in the middle */
1030 check_times (&segment, 100, 200, 150);
1031 /* at segment start */
1032 check_times (&segment, 50, 250, 100);
1033 /* another place in the middle */
1034 check_times (&segment, 150, 150, 200);
1035 /* at segment stop */
1036 check_times (&segment, 200, 100, 250);
1042 gst_segment_suite (void)
1044 Suite *s = suite_create ("GstSegment");
1045 TCase *tc_chain = tcase_create ("segments");
1047 tcase_set_timeout (tc_chain, 20);
1049 suite_add_tcase (s, tc_chain);
1050 tcase_add_test (tc_chain, segment_seek_nosize);
1051 tcase_add_test (tc_chain, segment_seek_size);
1052 tcase_add_test (tc_chain, segment_seek_reverse);
1053 tcase_add_test (tc_chain, segment_seek_rate);
1054 tcase_add_test (tc_chain, segment_copy);
1055 tcase_add_test (tc_chain, segment_seek_noupdate);
1056 tcase_add_test (tc_chain, segment_offset);
1057 tcase_add_test (tc_chain, segment_full);
1058 tcase_add_test (tc_chain, segment_negative_rate);
1059 tcase_add_test (tc_chain, segment_negative_applied_rate);
1060 tcase_add_test (tc_chain, segment_stream_time_full);
1065 GST_CHECK_MAIN (gst_segment);