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.
23 #include <gst/check/gstcheck.h>
25 #define check_times(segment, position, stream_time, running_time) G_STMT_START { \
26 guint64 st, rt, pos; \
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)); \
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)); \
40 if ((running_time) != -1) { \
41 pos = gst_segment_position_from_running_time ((segment), (segment)->format, rt); \
42 fail_unless_equals_int64 (pos, (position)); \
46 /* mess with the segment structure in the bytes format */
47 GST_START_TEST (segment_seek_nosize)
51 guint64 cstart, cstop;
54 gst_segment_init (&segment, GST_FORMAT_BYTES);
56 /* configure segment to start 100 */
57 gst_segment_do_seek (&segment, 1.0,
60 GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
61 fail_unless_equals_uint64 (segment.start, 100);
62 fail_unless_equals_uint64 (segment.position, 100);
63 fail_unless_equals_uint64 (segment.stop, -1);
64 fail_unless (update == TRUE);
65 /* appended after current position 0 */
66 check_times (&segment, 100, 100, 0);
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);
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);
77 /* partially inside */
78 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
79 fail_unless (res == TRUE);
80 fail_unless_equals_uint64 (cstart, 100);
81 fail_unless_equals_uint64 (cstop, 150);
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_equals_uint64 (cstart, 100);
88 fail_unless_equals_uint64 (cstop, 150);
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);
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_equals_uint64 (cstart, 100);
99 fail_unless_equals_uint64 (cstop, 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_equals_uint64 (cstart, 120);
106 fail_unless_equals_uint64 (cstop, 120);
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_equals_uint64 (cstart, 150);
113 fail_unless_equals_uint64 (cstop, 200);
116 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
117 fail_unless (res == FALSE);
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_equals_uint64 (cstart, 100);
123 fail_unless_equals_int64 (cstop, -1);
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_equals_uint64 (cstart, 100);
129 fail_unless_equals_int64 (cstop, -1);
132 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
133 fail_unless (res == TRUE);
134 fail_unless_equals_uint64 (cstart, 150);
135 fail_unless_equals_int64 (cstop, -1);
137 /* move to 150, this is a running_time of 50 */
138 segment.position = 150;
139 check_times (&segment, 150, 150, 50);
141 /* add 100 to start, set stop to 300 */
142 gst_segment_do_seek (&segment, 1.0,
145 GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
146 fail_unless_equals_uint64 (segment.start, 200);
147 fail_unless_equals_uint64 (segment.position, 200);
148 fail_unless_equals_uint64 (segment.stop, 300);
149 fail_unless_equals_uint64 (segment.base, 50);
150 fail_unless (update == TRUE);
151 check_times (&segment, 200, 200, 50);
152 check_times (&segment, 250, 250, 100);
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
158 ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
161 GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update));
162 fail_unless_equals_uint64 (segment.start, 200);
163 fail_unless_equals_uint64 (segment.position, 200);
164 fail_unless_equals_uint64 (segment.stop, 300);
165 fail_unless_equals_uint64 (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);
172 /* seek relative to end, should not do anything since size is
174 gst_segment_do_seek (&segment, 1.0,
177 GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
178 fail_unless_equals_uint64 (segment.start, 200);
179 fail_unless_equals_uint64 (segment.position, 200);
180 fail_unless_equals_uint64 (segment.stop, 300);
181 fail_unless_equals_uint64 (segment.base, 50);
182 fail_unless (update == FALSE);
183 check_times (&segment, 250, 250, 100);
185 /* completely outside */
186 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
187 fail_unless (res == FALSE);
189 /* touching lower bound */
190 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 200, &cstart, &cstop);
191 fail_unless (res == FALSE);
193 /* partially inside */
194 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 250, &cstart, &cstop);
195 fail_unless (res == TRUE);
196 fail_unless_equals_uint64 (cstart, 200);
197 fail_unless_equals_uint64 (cstop, 250);
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_equals_uint64 (cstart, 200);
204 fail_unless_equals_uint64 (cstop, 250);
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_equals_uint64 (cstart, 250);
211 fail_unless_equals_uint64 (cstop, 290);
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_equals_uint64 (cstart, 250);
218 fail_unless_equals_uint64 (cstop, 300);
221 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
222 fail_unless (res == FALSE);
225 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
226 fail_unless (res == TRUE);
227 fail_unless_equals_uint64 (cstart, 200);
228 fail_unless_equals_uint64 (cstop, 300);
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_equals_uint64 (cstart, 200);
234 fail_unless_equals_uint64 (cstop, 300);
237 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
238 fail_unless (res == TRUE);
239 fail_unless_equals_uint64 (cstart, 250);
240 fail_unless_equals_uint64 (cstop, 300);
242 /* start outside on boundary */
243 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 300, -1, &cstart, &cstop);
244 fail_unless (res == FALSE);
246 /* start completely outside */
247 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 350, -1, &cstart, &cstop);
248 fail_unless (res == FALSE);
253 /* mess with the segment structure in the bytes format */
254 GST_START_TEST (segment_seek_size)
258 guint64 cstart, cstop;
261 gst_segment_init (&segment, GST_FORMAT_BYTES);
262 segment.duration = 200;
264 /* configure segment to start 100 */
265 gst_segment_do_seek (&segment, 1.0,
268 GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
269 fail_unless_equals_uint64 (segment.start, 100);
270 fail_unless_equals_uint64 (segment.position, 100);
271 fail_unless_equals_int64 (segment.stop, -1);
272 fail_unless (update == TRUE);
273 check_times (&segment, 100, 100, 0);
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);
280 /* touching lower bound */
281 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
282 fail_unless (res == FALSE);
284 /* partially inside */
285 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
286 fail_unless (res == TRUE);
287 fail_unless_equals_uint64 (cstart, 100);
288 fail_unless_equals_uint64 (cstop, 150);
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_equals_uint64 (cstart, 100);
295 fail_unless_equals_uint64 (cstop, 150);
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_equals_uint64 (cstart, 150);
302 fail_unless_equals_uint64 (cstop, 200);
305 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
306 fail_unless (res == FALSE);
309 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
310 fail_unless (res == TRUE);
311 fail_unless_equals_uint64 (cstart, 100);
312 fail_unless_equals_int64 (cstop, -1);
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_equals_uint64 (cstart, 100);
318 fail_unless_equals_uint64 (cstop, -1);
321 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
322 fail_unless (res == TRUE);
323 fail_unless_equals_uint64 (cstart, 150);
324 fail_unless_equals_uint64 (cstop, -1);
326 /* add 100 to start, set stop to 300, stop clips to 200 */
327 gst_segment_do_seek (&segment, 1.0,
330 GST_SEEK_TYPE_SET, 100 + 100, GST_SEEK_TYPE_SET, 300, &update);
331 fail_unless_equals_uint64 (segment.start, 200);
332 fail_unless_equals_uint64 (segment.position, 200);
333 fail_unless_equals_uint64 (segment.stop, 200);
334 check_times (&segment, 200, 200, 0);
336 /* add 100 to start (to 300), set stop to 200, this clips start
338 gst_segment_do_seek (&segment, 1.0,
341 GST_SEEK_TYPE_SET, 200 + 100, GST_SEEK_TYPE_SET, 200, &update);
342 fail_unless_equals_uint64 (segment.start, 200);
343 fail_unless_equals_uint64 (segment.position, 200);
344 fail_unless_equals_uint64 (segment.stop, 200);
345 fail_unless (update == FALSE);
346 check_times (&segment, 200, 200, 0);
348 /* special case, segment's start and stop are identical */
349 /* completely outside */
350 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
351 fail_unless (res == FALSE);
353 /* completely outside also */
354 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
355 250, 300, &cstart, &cstop);
356 fail_unless (res == FALSE);
358 /* stop at boundary point. it's outside because stop is exclusive */
359 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
360 100, 200, &cstart, &cstop);
361 fail_unless (res == FALSE);
363 /* touching boundary point. it's inside because start at segment start */
364 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
365 200, 300, &cstart, &cstop);
366 fail_unless (res == TRUE);
367 fail_unless_equals_uint64 (cstart, 200);
368 fail_unless_equals_uint64 (cstop, 200);
370 /* completely inside */
371 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
372 200, 200, &cstart, &cstop);
373 fail_unless (res == TRUE);
374 fail_unless_equals_uint64 (cstart, 200);
375 fail_unless_equals_uint64 (cstop, 200);
377 /* exclusively cover boundary point */
378 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
379 150, 250, &cstart, &cstop);
380 fail_unless (res == TRUE);
381 fail_unless_equals_uint64 (cstart, 200);
382 fail_unless_equals_uint64 (cstop, 200);
385 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 200, &cstart, &cstop);
386 fail_unless (res == FALSE);
389 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
390 fail_unless (res == TRUE);
391 fail_unless_equals_uint64 (cstart, 200);
392 fail_unless_equals_uint64 (cstop, 200);
394 /* start on boundary point */
395 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 200, -1, &cstart, &cstop);
396 fail_unless (res == TRUE);
397 fail_unless_equals_uint64 (cstart, 200);
398 fail_unless_equals_uint64 (cstop, 200);
400 /* start completely outside */
401 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
402 fail_unless (res == FALSE);
404 /* seek relative to end */
405 gst_segment_do_seek (&segment, 1.0,
408 GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
409 fail_unless_equals_uint64 (segment.start, 100);
410 fail_unless_equals_uint64 (segment.position, 100);
411 fail_unless_equals_uint64 (segment.stop, 180);
412 fail_unless (update == TRUE);
413 check_times (&segment, 150, 150, 50);
415 /* completely outside */
416 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 0, 50, &cstart, &cstop);
417 fail_unless (res == FALSE);
419 /* touching lower bound */
420 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 100, &cstart, &cstop);
421 fail_unless (res == FALSE);
423 /* partially inside */
424 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, 150, &cstart, &cstop);
425 fail_unless (res == TRUE);
426 fail_unless_equals_uint64 (cstart, 100);
427 fail_unless_equals_uint64 (cstop, 150);
429 /* inside, touching lower bound */
430 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
431 100, 150, &cstart, &cstop);
432 fail_unless (res == TRUE);
433 fail_unless_equals_uint64 (cstart, 100);
434 fail_unless_equals_uint64 (cstop, 150);
436 /* completely inside */
437 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
438 150, 170, &cstart, &cstop);
439 fail_unless (res == TRUE);
440 fail_unless_equals_uint64 (cstart, 150);
441 fail_unless_equals_uint64 (cstop, 170);
443 /* partially inside */
444 res = gst_segment_clip (&segment, GST_FORMAT_BYTES,
445 150, 250, &cstart, &cstop);
446 fail_unless (res == TRUE);
447 fail_unless_equals_uint64 (cstart, 150);
448 fail_unless_equals_uint64 (cstop, 180);
451 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, -1, 100, &cstart, &cstop);
452 fail_unless (res == FALSE);
455 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 50, -1, &cstart, &cstop);
456 fail_unless (res == TRUE);
457 fail_unless_equals_uint64 (cstart, 100);
458 fail_unless_equals_uint64 (cstop, 180);
460 /* start on lower bound */
461 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 100, -1, &cstart, &cstop);
462 fail_unless (res == TRUE);
463 fail_unless_equals_uint64 (cstart, 100);
464 fail_unless_equals_uint64 (cstop, 180);
467 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 150, -1, &cstart, &cstop);
468 fail_unless (res == TRUE);
469 fail_unless_equals_uint64 (cstart, 150);
470 fail_unless_equals_uint64 (cstop, 180);
472 /* start outside on boundary */
473 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 180, -1, &cstart, &cstop);
474 fail_unless (res == FALSE);
476 /* start completely outside */
477 res = gst_segment_clip (&segment, GST_FORMAT_BYTES, 250, -1, &cstart, &cstop);
478 fail_unless (res == FALSE);
483 GST_START_TEST (segment_seek_reverse)
488 gst_segment_init (&segment, GST_FORMAT_BYTES);
489 segment.duration = 200;
491 /* configure segment to stop 100 */
492 gst_segment_do_seek (&segment, -1.0,
495 GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
496 fail_unless_equals_uint64 (segment.start, 0);
497 fail_unless_equals_uint64 (segment.stop, 100);
498 fail_unless_equals_uint64 (segment.time, 0);
499 fail_unless_equals_uint64 (segment.position, 100);
500 fail_unless (update == TRUE);
501 check_times (&segment, 100, 100, 0);
502 check_times (&segment, 50, 50, 50);
503 check_times (&segment, 0, 0, 100);
506 gst_segment_do_seek (&segment, -1.0,
509 GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_SET, 100 - 20, &update);
510 fail_unless_equals_uint64 (segment.start, 10);
511 fail_unless_equals_uint64 (segment.stop, 80);
512 fail_unless_equals_uint64 (segment.time, 10);
513 fail_unless_equals_uint64 (segment.position, 80);
514 fail_unless (update == TRUE);
515 check_times (&segment, 80, 80, 0);
516 check_times (&segment, 40, 40, 40);
517 check_times (&segment, 10, 10, 70);
519 gst_segment_do_seek (&segment, -1.0,
522 GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
523 fail_unless_equals_uint64 (segment.start, 20);
524 fail_unless_equals_uint64 (segment.stop, 80);
525 fail_unless_equals_uint64 (segment.time, 20);
526 fail_unless_equals_uint64 (segment.position, 80);
527 fail_unless (update == FALSE);
528 check_times (&segment, 80, 80, 0);
529 check_times (&segment, 20, 20, 60);
534 /* mess with the segment structure in the bytes format */
535 GST_START_TEST (segment_seek_rate)
540 gst_segment_init (&segment, GST_FORMAT_BYTES);
542 /* configure segment to rate 2.0 */
543 gst_segment_do_seek (&segment, 2.0,
546 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
547 fail_unless (segment.format == GST_FORMAT_BYTES);
548 fail_unless_equals_uint64 (segment.start, 0);
549 fail_unless_equals_uint64 (segment.position, 0);
550 fail_unless_equals_int64 (segment.stop, -1);
551 fail_unless_equals_float (segment.rate, 2.0);
552 fail_unless (update == FALSE);
553 check_times (&segment, 50, 50, 25);
555 /* set a real stop position, this must happen in bytes */
556 gst_segment_do_seek (&segment, 3.0,
559 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
560 fail_unless (segment.format == GST_FORMAT_BYTES);
561 fail_unless_equals_uint64 (segment.start, 0);
562 fail_unless_equals_uint64 (segment.stop, 100);
563 fail_unless_equals_float (segment.rate, 3.0);
564 /* no seek should happen, we just updated the stop position in forward
566 fail_unless (update == FALSE);
567 check_times (&segment, 60, 60, 20);
569 /* set some duration, stop -1 END seeks will now work with the
570 * duration, if the formats match */
571 segment.duration = 200;
573 /* seek to end with 0 should set the stop to the duration */
574 gst_segment_do_seek (&segment, 2.0,
575 GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
576 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
577 fail_unless_equals_uint64 (segment.stop, 200);
578 fail_unless_equals_uint64 (segment.duration, 200);
580 /* subtract 100 from the end */
581 gst_segment_do_seek (&segment, 2.0,
582 GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
583 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
584 fail_unless_equals_uint64 (segment.stop, 100);
585 fail_unless_equals_uint64 (segment.duration, 200);
587 /* add 100 to the duration, this should be clamped to the duration */
588 gst_segment_do_seek (&segment, 2.0,
589 GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
590 GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
591 fail_unless_equals_uint64 (segment.stop, 200);
592 fail_unless_equals_uint64 (segment.duration, 200);
597 GST_START_TEST (segment_copy)
600 GstSegment segment = { 0.0, };
602 /* this is a boxed type copy function, we support copying NULL */
603 fail_unless (gst_segment_copy (NULL) == NULL);
605 gst_segment_init (&segment, GST_FORMAT_TIME);
608 segment.applied_rate = 1.0;
613 copy = gst_segment_copy (&segment);
614 fail_unless (copy != NULL);
615 /* we inited the struct on the stack to zeroes, so direct comparison should
616 * be ok here despite the padding field and regardless of implementation */
617 fail_unless (memcmp (copy, &segment, sizeof (GstSegment)) == 0);
618 gst_segment_free (copy);
623 /* mess with the segment structure in the bytes format */
624 GST_START_TEST (segment_seek_noupdate)
629 gst_segment_init (&segment, GST_FORMAT_TIME);
632 segment.position = 50;
636 /* doesn't change anything */
637 gst_segment_do_seek (&segment, 1.0,
640 GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
641 fail_unless (update == FALSE);
642 fail_unless (segment.format == GST_FORMAT_TIME);
643 fail_unless_equals_uint64 (segment.start, 0);
644 fail_unless_equals_uint64 (segment.stop, 200);
645 fail_unless_equals_uint64 (segment.time, 0);
646 fail_unless_equals_uint64 (segment.position, 50);
647 fail_unless_equals_uint64 (segment.base, 50);
648 fail_unless_equals_uint64 (segment.offset, 50);
650 gst_segment_do_seek (&segment, 2.0,
653 GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
654 fail_unless (update == FALSE);
655 fail_unless (segment.format == GST_FORMAT_TIME);
656 fail_unless_equals_uint64 (segment.start, 0);
657 fail_unless_equals_uint64 (segment.stop, 200);
658 fail_unless_equals_uint64 (segment.time, 0);
659 fail_unless_equals_uint64 (segment.position, 50);
660 fail_unless_equals_uint64 (segment.base, 50);
661 fail_unless_equals_uint64 (segment.offset, 50);
663 gst_segment_do_seek (&segment, 1.0,
666 GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
667 fail_unless (update == FALSE);
668 fail_unless (segment.format == GST_FORMAT_TIME);
669 fail_unless_equals_uint64 (segment.start, 0);
670 fail_unless_equals_uint64 (segment.stop, 200);
671 fail_unless_equals_uint64 (segment.time, 0);
672 fail_unless_equals_uint64 (segment.position, 50);
673 fail_unless_equals_uint64 (segment.base, 0);
674 fail_unless_equals_uint64 (segment.offset, 50);
679 GST_START_TEST (segment_offset)
683 gst_segment_init (&segment, GST_FORMAT_TIME);
686 segment.position = 50;
690 check_times (&segment, 20, 20, 20);
691 check_times (&segment, 220, -1, -1);
693 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
695 fail_unless_equals_uint64 (segment.start, 0);
696 fail_unless_equals_uint64 (segment.stop, 200);
697 fail_unless_equals_uint64 (segment.time, 0);
698 fail_unless_equals_uint64 (segment.position, 50);
699 fail_unless_equals_uint64 (segment.base, 0);
700 fail_unless_equals_uint64 (segment.offset, 0);
701 check_times (&segment, 20, 20, 20);
703 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
705 fail_unless_equals_uint64 (segment.start, 0);
706 fail_unless_equals_uint64 (segment.stop, 200);
707 fail_unless_equals_uint64 (segment.time, 0);
708 fail_unless_equals_uint64 (segment.position, 50);
709 fail_unless_equals_uint64 (segment.base, 100);
710 fail_unless_equals_uint64 (segment.offset, 0);
711 check_times (&segment, 20, 20, 120);
713 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
715 fail_unless_equals_uint64 (segment.start, 0);
716 fail_unless_equals_uint64 (segment.stop, 200);
717 fail_unless_equals_uint64 (segment.time, 0);
718 fail_unless_equals_uint64 (segment.position, 50);
719 fail_unless_equals_uint64 (segment.base, 50);
720 fail_unless_equals_uint64 (segment.offset, 0);
721 check_times (&segment, 20, 20, 70);
723 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
725 fail_unless_equals_uint64 (segment.start, 0);
726 fail_unless_equals_uint64 (segment.stop, 200);
727 fail_unless_equals_uint64 (segment.time, 0);
728 fail_unless_equals_uint64 (segment.position, 50);
729 fail_unless_equals_uint64 (segment.base, 0);
730 fail_unless_equals_uint64 (segment.offset, 50);
731 check_times (&segment, 20, 20, -1);
732 check_times (&segment, 200, 200, 150);
734 /* can go negative */
735 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
737 fail_unless_equals_uint64 (segment.start, 0);
738 fail_unless_equals_uint64 (segment.stop, 200);
739 fail_unless_equals_uint64 (segment.time, 0);
740 fail_unless_equals_uint64 (segment.position, 50);
741 fail_unless_equals_uint64 (segment.base, 0);
742 fail_unless_equals_uint64 (segment.offset, 50);
743 check_times (&segment, 100, 100, 50);
744 check_times (&segment, 200, 200, 150);
746 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
748 fail_unless_equals_uint64 (segment.start, 0);
749 fail_unless_equals_uint64 (segment.stop, 200);
750 fail_unless_equals_uint64 (segment.time, 0);
751 fail_unless_equals_uint64 (segment.position, 50);
752 fail_unless_equals_uint64 (segment.base, 0);
753 fail_unless_equals_uint64 (segment.offset, 200);
754 check_times (&segment, 200, 200, 0);
756 gst_segment_init (&segment, GST_FORMAT_TIME);
759 segment.position = 50;
763 check_times (&segment, 40, 20, 20);
764 check_times (&segment, 240, -1, -1);
766 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
768 fail_unless_equals_uint64 (segment.start, 20);
769 fail_unless_equals_uint64 (segment.stop, 220);
770 fail_unless_equals_uint64 (segment.time, 0);
771 fail_unless_equals_uint64 (segment.position, 50);
772 fail_unless_equals_uint64 (segment.base, 0);
773 fail_unless_equals_uint64 (segment.offset, 0);
774 check_times (&segment, 40, 20, 20);
776 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
778 fail_unless_equals_uint64 (segment.start, 20);
779 fail_unless_equals_uint64 (segment.stop, 220);
780 fail_unless_equals_uint64 (segment.time, 0);
781 fail_unless_equals_uint64 (segment.position, 50);
782 fail_unless_equals_uint64 (segment.base, 100);
783 fail_unless_equals_uint64 (segment.offset, 0);
784 check_times (&segment, 40, 20, 120);
786 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
788 fail_unless_equals_uint64 (segment.start, 20);
789 fail_unless_equals_uint64 (segment.stop, 220);
790 fail_unless_equals_uint64 (segment.time, 0);
791 fail_unless_equals_uint64 (segment.position, 50);
792 fail_unless_equals_uint64 (segment.base, 50);
793 fail_unless_equals_uint64 (segment.offset, 0);
794 check_times (&segment, 40, 20, 70);
796 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
798 fail_unless_equals_uint64 (segment.start, 20);
799 fail_unless_equals_uint64 (segment.stop, 220);
800 fail_unless_equals_uint64 (segment.time, 0);
801 fail_unless_equals_uint64 (segment.position, 50);
802 fail_unless_equals_uint64 (segment.base, 0);
803 fail_unless_equals_uint64 (segment.offset, 50);
804 check_times (&segment, 40, 20, -1);
805 check_times (&segment, 220, 200, 150);
810 GST_START_TEST (segment_full)
815 gst_segment_init (&segment, GST_FORMAT_TIME);
818 segment.position = 150;
822 check_times (&segment, 100, 50, 50);
823 check_times (&segment, 220, -1, -1);
825 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
827 fail_unless (rt == 0);
828 fail_unless (gst_segment_position_from_running_time_full (&segment,
829 GST_FORMAT_TIME, rt, &pos) == 1);
830 fail_unless (pos == 50);
831 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
833 fail_unless (rt == 150);
834 fail_unless (gst_segment_position_from_running_time_full (&segment,
835 GST_FORMAT_TIME, rt, &pos) == 1);
836 fail_unless (pos == 200);
837 fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 40, 40, NULL,
839 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 40,
841 fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 49, 49, NULL,
843 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 49,
845 fail_unless (!gst_segment_clip (&segment, GST_FORMAT_TIME, 201, 201, NULL,
847 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME, 201,
849 fail_unless (gst_segment_position_from_running_time_full (&segment,
850 GST_FORMAT_TIME, rt, &pos) == 1);
851 fail_unless (pos == 201);
853 fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
855 fail_unless (segment.offset == 50);
857 fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
859 GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
860 fail_unless (rt == 50);
864 segment.position = 150;
867 gst_segment_set_running_time (&segment, GST_FORMAT_TIME, 100);
868 fail_unless_equals_int (segment.base, 100);
869 fail_unless (gst_segment_position_from_running_time_full (&segment,
870 GST_FORMAT_TIME, 70, &pos) == -1);
871 fail_unless (gst_segment_position_from_running_time_full (&segment,
872 GST_FORMAT_TIME, 140, &pos) == 1);
873 fail_unless_equals_int (pos, 190);
878 GST_START_TEST (segment_stream_time_full)
883 gst_segment_init (&segment, GST_FORMAT_TIME);
888 segment.position = 0;
890 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
892 fail_unless_equals_int (st, 20);
893 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
895 fail_unless_equals_int (st, 0);
896 fail_unless (gst_segment_position_from_stream_time_full (&segment,
897 GST_FORMAT_TIME, 0, &pos) == 1);
898 fail_unless_equals_int (pos, 20);
899 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
901 fail_unless_equals_int (st, 10);
902 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
904 fail_unless_equals_int (st, 20);
905 fail_unless (gst_segment_position_from_stream_time_full (&segment,
906 GST_FORMAT_TIME, st, &pos) == 1);
907 fail_unless_equals_int (pos, 40);
909 fail_unless (gst_segment_position_from_stream_time_full (&segment,
910 GST_FORMAT_TIME, 40, &pos) == -1);
911 fail_unless_equals_int (pos, 10);
912 fail_unless (gst_segment_position_from_stream_time_full (&segment,
913 GST_FORMAT_TIME, 60, &pos) == 1);
914 fail_unless_equals_int (pos, 10);
917 segment.position = 150;
920 segment.applied_rate = -1;
923 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
925 fail_unless_equals_int (st, 200);
926 fail_unless (gst_segment_position_from_stream_time_full (&segment,
927 GST_FORMAT_TIME, 200, &pos) == 1);
928 fail_unless_equals_int (pos, 0);
929 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
931 fail_unless_equals_int (st, 50);
932 fail_unless (gst_segment_position_from_stream_time_full (&segment,
933 GST_FORMAT_TIME, 200, &pos) == 1);
934 fail_unless_equals_int (pos, 0);
935 fail_unless (gst_segment_position_from_stream_time_full (&segment,
936 GST_FORMAT_TIME, 250, &pos) == -1);
937 fail_unless_equals_int (pos, 50);
940 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
942 fail_unless_equals_int (st, 20);
943 fail_unless (gst_segment_position_from_stream_time_full (&segment,
944 GST_FORMAT_TIME, 50, &pos) == 1);
945 fail_unless_equals_int (pos, 220);
946 fail_unless (gst_segment_position_from_stream_time_full (&segment,
947 GST_FORMAT_TIME, 90, &pos) == 1);
948 fail_unless_equals_int (pos, 180);
951 fail_unless (gst_segment_position_from_stream_time_full (&segment,
952 GST_FORMAT_TIME, 5, &pos) == 1);
953 fail_unless_equals_int (pos, 125);
958 GST_START_TEST (segment_negative_rate)
962 gst_segment_init (&segment, GST_FORMAT_TIME);
965 segment.position = 150;
968 segment.applied_rate = -1;
971 /* somewhere in the middle */
972 check_times (&segment, 100, 100, 100);
974 check_times (&segment, 220, -1, -1);
976 check_times (&segment, 10, -1, -1);
977 /* at segment start */
978 check_times (&segment, 50, 150, 150);
979 /* another place in the middle */
980 check_times (&segment, 150, 50, 50);
981 /* at segment stop */
982 check_times (&segment, 200, 0, 0);
986 /* somewhere in the middle */
987 check_times (&segment, 100, 200, 200);
988 /* at segment start */
989 check_times (&segment, 50, 250, 250);
990 /* another place in the middle */
991 check_times (&segment, 150, 150, 150);
992 /* at segment stop */
993 check_times (&segment, 200, 100, 100);
998 GST_START_TEST (segment_negative_applied_rate)
1002 gst_segment_init (&segment, GST_FORMAT_TIME);
1005 segment.position = 150;
1008 segment.applied_rate = -1;
1011 /* somewhere in the middle */
1012 check_times (&segment, 100, 100, 50);
1014 check_times (&segment, 220, -1, -1);
1016 check_times (&segment, 10, -1, -1);
1017 /* at segment start */
1018 check_times (&segment, 50, 150, 0);
1019 /* another place in the middle */
1020 check_times (&segment, 150, 50, 100);
1021 /* at segment stop */
1022 check_times (&segment, 200, 0, 150);
1026 /* somewhere in the middle */
1027 check_times (&segment, 100, 200, 150);
1028 /* at segment start */
1029 check_times (&segment, 50, 250, 100);
1030 /* another place in the middle */
1031 check_times (&segment, 150, 150, 200);
1032 /* at segment stop */
1033 check_times (&segment, 200, 100, 250);
1039 gst_segment_suite (void)
1041 Suite *s = suite_create ("GstSegment");
1042 TCase *tc_chain = tcase_create ("segments");
1044 tcase_set_timeout (tc_chain, 20);
1046 suite_add_tcase (s, tc_chain);
1047 tcase_add_test (tc_chain, segment_seek_nosize);
1048 tcase_add_test (tc_chain, segment_seek_size);
1049 tcase_add_test (tc_chain, segment_seek_reverse);
1050 tcase_add_test (tc_chain, segment_seek_rate);
1051 tcase_add_test (tc_chain, segment_copy);
1052 tcase_add_test (tc_chain, segment_seek_noupdate);
1053 tcase_add_test (tc_chain, segment_offset);
1054 tcase_add_test (tc_chain, segment_full);
1055 tcase_add_test (tc_chain, segment_negative_rate);
1056 tcase_add_test (tc_chain, segment_negative_applied_rate);
1057 tcase_add_test (tc_chain, segment_stream_time_full);
1062 GST_CHECK_MAIN (gst_segment);