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);
873 fail_unless (gst_segment_position_from_running_time_full (&segment,
874 GST_FORMAT_TIME, 70, &pos) == 1);
875 fail_unless_equals_int (pos, 120);
877 fail_unless (gst_segment_position_from_running_time_full (&segment,
878 GST_FORMAT_TIME, 140, &pos) == 1);
879 fail_unless_equals_int (pos, 190);
881 /* Test a non-1.0 rate that lands right before the segment, but still +ve */
886 segment.position = 40;
888 segment.time = 10000;
889 fail_unless (gst_segment_position_from_running_time_full (&segment,
890 GST_FORMAT_TIME, 140, &pos) == 1);
891 fail_unless (pos == 89);
892 /* And now one that should give a position < 0 */
893 fail_unless (gst_segment_position_from_running_time_full (&segment,
894 GST_FORMAT_TIME, 0, &pos) == -1);
895 fail_unless (pos == 65);
897 /* Test a non-1.0 negative rate that lands right after the (reversed) segment, but still +ve position */
902 segment.position = 150;
904 segment.time = 10000;
905 fail_unless (gst_segment_position_from_running_time_full (&segment,
906 GST_FORMAT_TIME, 200 + 133 + 20, &pos) == 1);
907 fail_unless (pos == 60);
908 /* And now one that should give a position < 0, reported as a negated value */
909 fail_unless (gst_segment_position_from_running_time_full (&segment,
910 GST_FORMAT_TIME, 200 + 133 + 70, &pos) == -1);
911 fail_unless (pos == 40);
913 /* Test gst_segment_position_from_running_time_full() with offsets */
916 segment.offset = 100;
918 segment.position = 150;
920 segment.time = 10000;
921 /* Position before the segment but >= 0 */
922 fail_unless (gst_segment_position_from_running_time_full (&segment,
923 GST_FORMAT_TIME, 75, &pos) == 1);
924 fail_unless (pos == 0);
925 fail_unless (gst_segment_position_from_running_time (&segment,
926 GST_FORMAT_TIME, 75) == -1);
928 /* Position before the segment and < 0 */
929 fail_unless (gst_segment_position_from_running_time_full (&segment,
930 GST_FORMAT_TIME, 65, &pos) == -1);
931 fail_unless (pos == 20); /* Actually -20 */
932 fail_unless (gst_segment_position_from_running_time (&segment,
933 GST_FORMAT_TIME, 65) == -1);
935 /* After the segment */
936 fail_unless (gst_segment_position_from_running_time_full (&segment,
937 GST_FORMAT_TIME, 175 + 150 + 10, &pos) == 1);
938 fail_unless (pos == 520);
939 fail_unless (gst_segment_position_from_running_time (&segment,
940 GST_FORMAT_TIME, 175 + 150 + 10) == -1);
942 /* And with negative rate, so the segment is reversed */
945 /* Before the segment */
946 fail_unless (gst_segment_position_from_running_time_full (&segment,
947 GST_FORMAT_TIME, 75, &pos) == 1);
948 fail_unless (pos == 600);
949 fail_unless (gst_segment_position_from_running_time (&segment,
950 GST_FORMAT_TIME, 75) == -1);
952 /* Position after the segment and < 0 */
953 fail_unless (gst_segment_position_from_running_time_full (&segment,
954 GST_FORMAT_TIME, 400, &pos) == -1);
955 fail_unless (pos == 50); /* Actually -50 */
956 fail_unless (gst_segment_position_from_running_time (&segment,
957 GST_FORMAT_TIME, 400) == -1);
959 /* Position after the segment and >= 0 */
960 fail_unless (gst_segment_position_from_running_time_full (&segment,
961 GST_FORMAT_TIME, 325 + 10, &pos) == 1);
962 fail_unless (pos == 80);
963 fail_unless (gst_segment_position_from_running_time (&segment,
964 GST_FORMAT_TIME, 325 + 10) == -1);
966 /* Big offset can clip away an entire reversed segment and produce a negative position anyway */
967 segment.offset = 1000;
968 fail_unless (gst_segment_position_from_running_time_full (&segment,
969 GST_FORMAT_TIME, 75, &pos) == -1);
970 fail_unless (pos == 300); /* Actually -300 */
975 GST_START_TEST (segment_stream_time_full)
980 gst_segment_init (&segment, GST_FORMAT_TIME);
985 segment.position = 0;
987 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
989 fail_unless_equals_int (st, 20);
990 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
992 fail_unless_equals_int (st, 0);
993 fail_unless (gst_segment_position_from_stream_time_full (&segment,
994 GST_FORMAT_TIME, 0, &pos) == 1);
995 fail_unless_equals_int (pos, 20);
996 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
998 fail_unless_equals_int (st, 10);
999 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
1001 fail_unless_equals_int (st, 20);
1002 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1003 GST_FORMAT_TIME, st, &pos) == 1);
1004 fail_unless_equals_int (pos, 40);
1006 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1007 GST_FORMAT_TIME, 40, &pos) == -1);
1008 fail_unless_equals_int (pos, 10);
1009 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1010 GST_FORMAT_TIME, 60, &pos) == 1);
1011 fail_unless_equals_int (pos, 10);
1014 segment.position = 150;
1017 segment.applied_rate = -1;
1020 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
1022 fail_unless_equals_int (st, 200);
1023 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1024 GST_FORMAT_TIME, 200, &pos) == 1);
1025 fail_unless_equals_int (pos, 0);
1026 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
1028 fail_unless_equals_int (st, 50);
1029 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1030 GST_FORMAT_TIME, 200, &pos) == 1);
1031 fail_unless_equals_int (pos, 0);
1032 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1033 GST_FORMAT_TIME, 250, &pos) == -1);
1034 fail_unless_equals_int (pos, 50);
1037 fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
1039 fail_unless_equals_int (st, 20);
1040 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1041 GST_FORMAT_TIME, 50, &pos) == 1);
1042 fail_unless_equals_int (pos, 220);
1043 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1044 GST_FORMAT_TIME, 90, &pos) == 1);
1045 fail_unless_equals_int (pos, 180);
1048 fail_unless (gst_segment_position_from_stream_time_full (&segment,
1049 GST_FORMAT_TIME, 5, &pos) == 1);
1050 fail_unless_equals_int (pos, 125);
1055 GST_START_TEST (segment_negative_rate)
1059 gst_segment_init (&segment, GST_FORMAT_TIME);
1062 segment.position = 150;
1065 segment.applied_rate = -1;
1068 /* somewhere in the middle */
1069 check_times (&segment, 100, 100, 100);
1071 check_times (&segment, 220, -1, -1);
1073 check_times (&segment, 10, -1, -1);
1074 /* at segment start */
1075 check_times (&segment, 50, 150, 150);
1076 /* another place in the middle */
1077 check_times (&segment, 150, 50, 50);
1078 /* at segment stop */
1079 check_times (&segment, 200, 0, 0);
1083 /* somewhere in the middle */
1084 check_times (&segment, 100, 200, 200);
1085 /* at segment start */
1086 check_times (&segment, 50, 250, 250);
1087 /* another place in the middle */
1088 check_times (&segment, 150, 150, 150);
1089 /* at segment stop */
1090 check_times (&segment, 200, 100, 100);
1095 GST_START_TEST (segment_negative_applied_rate)
1099 gst_segment_init (&segment, GST_FORMAT_TIME);
1102 segment.position = 150;
1105 segment.applied_rate = -1;
1108 /* somewhere in the middle */
1109 check_times (&segment, 100, 100, 50);
1111 check_times (&segment, 220, -1, -1);
1113 check_times (&segment, 10, -1, -1);
1114 /* at segment start */
1115 check_times (&segment, 50, 150, 0);
1116 /* another place in the middle */
1117 check_times (&segment, 150, 50, 100);
1118 /* at segment stop */
1119 check_times (&segment, 200, 0, 150);
1123 /* somewhere in the middle */
1124 check_times (&segment, 100, 200, 150);
1125 /* at segment start */
1126 check_times (&segment, 50, 250, 100);
1127 /* another place in the middle */
1128 check_times (&segment, 150, 150, 200);
1129 /* at segment stop */
1130 check_times (&segment, 200, 100, 250);
1136 gst_segment_suite (void)
1138 Suite *s = suite_create ("GstSegment");
1139 TCase *tc_chain = tcase_create ("segments");
1141 tcase_set_timeout (tc_chain, 20);
1143 suite_add_tcase (s, tc_chain);
1144 tcase_add_test (tc_chain, segment_seek_nosize);
1145 tcase_add_test (tc_chain, segment_seek_size);
1146 tcase_add_test (tc_chain, segment_seek_reverse);
1147 tcase_add_test (tc_chain, segment_seek_rate);
1148 tcase_add_test (tc_chain, segment_copy);
1149 tcase_add_test (tc_chain, segment_seek_noupdate);
1150 tcase_add_test (tc_chain, segment_offset);
1151 tcase_add_test (tc_chain, segment_full);
1152 tcase_add_test (tc_chain, segment_negative_rate);
1153 tcase_add_test (tc_chain, segment_negative_applied_rate);
1154 tcase_add_test (tc_chain, segment_stream_time_full);
1159 GST_CHECK_MAIN (gst_segment);