2 * Unit test for a deterministic clock for Gstreamer unit tests
4 * Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
5 * Copyright (C) 2012 Sebastian Rasmussen <sebastian.rasmussen@axis.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #include <gst/check/gstcheck.h>
24 #include <gst/check/gsttestclock.h>
28 GstTestClock *test_clock;
30 GstClockTime reference;
31 } GtuClockWaitContext;
36 GstClockTimeDiff jitter;
37 } SyncClockWaitContext;
39 #define assert_pending_id(pending_id, id, type, time) \
41 GstClockEntry *entry = GST_CLOCK_ENTRY (pending_id); \
42 g_assert (entry == (id)); \
43 g_assert (GST_CLOCK_ENTRY_TYPE (entry) == (type)); \
44 g_assert_cmpuint (GST_CLOCK_ENTRY_TIME (entry), ==, (time)); \
47 #define assert_processed_id(processed_id, id, type, time) \
49 GstClockEntry *entry = GST_CLOCK_ENTRY (processed_id); \
50 g_assert (entry == (id)); \
51 g_assert (GST_CLOCK_ENTRY_TYPE (entry) == (type)); \
52 g_assert_cmpuint (GST_CLOCK_ENTRY_STATUS (entry), ==, (time)); \
55 static gpointer test_wait_pending_single_shot_id_sync_worker (gpointer data);
56 static gpointer test_wait_pending_single_shot_id_async_worker (gpointer data);
57 static gpointer test_wait_pending_periodic_id_waiter_thread (gpointer data);
58 static gboolean test_async_wait_cb (GstClock * clock, GstClockTime time,
59 GstClockID id, gpointer user_data);
61 static GtuClockWaitContext *gst_test_util_wait_for_clock_id_begin (GstTestClock
62 * clock, GstClockID id, GstClockTimeDiff * jitter);
63 static GstClockReturn gst_test_util_wait_for_clock_id_end (GtuClockWaitContext *
66 gst_test_util_clock_wait_context_has_completed (GtuClockWaitContext * wait_ctx);
69 test_wait_pending_single_shot_id_sync_worker (gpointer data)
71 SyncClockWaitContext *ctx = data;
73 gst_clock_id_wait (ctx->clock_id, &ctx->jitter);
79 test_wait_pending_single_shot_id_async_worker (gpointer data)
81 GstClockID clock_id = data;
83 g_usleep (G_USEC_PER_SEC / 10);
84 gst_clock_id_wait_async (clock_id, test_async_wait_cb, NULL, NULL);
90 test_wait_pending_periodic_id_waiter_thread (gpointer data)
92 GstClockID clock_id = data;
93 gst_clock_id_wait (clock_id, NULL);
98 test_async_wait_cb (GstClock * clock,
99 GstClockTime time, GstClockID id, gpointer user_data)
102 gboolean *wait_complete = user_data;
104 if (wait_complete != NULL)
105 *wait_complete = TRUE;
110 static GtuClockWaitContext *
111 gst_test_util_wait_for_clock_id_begin (GstTestClock * test_clock, GstClockID id,
112 GstClockTimeDiff * jitter)
114 GtuClockWaitContext *wait_ctx;
116 wait_ctx = g_slice_new (GtuClockWaitContext);
117 wait_ctx->test_clock = gst_object_ref (test_clock);
118 wait_ctx->reference = gst_clock_get_time (GST_CLOCK (wait_ctx->test_clock));
119 wait_ctx->id = gst_clock_id_ref (id);
122 GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
123 GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
124 GstClockTime reference = wait_ctx->reference;
126 *jitter = GST_CLOCK_DIFF (requested, reference);
129 if (!gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id)) {
130 GstClockClass *klass = GST_CLOCK_GET_CLASS (wait_ctx->test_clock);
131 GstClock *clock = GST_CLOCK (wait_ctx->test_clock);
132 g_assert (klass->wait_async (clock, wait_ctx->id) == GST_CLOCK_OK);
135 g_assert (gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
136 g_assert_cmpint (gst_test_clock_peek_id_count (wait_ctx->test_clock), >, 0);
141 static GstClockReturn
142 gst_test_util_wait_for_clock_id_end (GtuClockWaitContext * wait_ctx)
144 GstClockReturn status = GST_CLOCK_ERROR;
145 GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
147 if (G_UNLIKELY (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED)) {
148 status = GST_CLOCK_UNSCHEDULED;
150 GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
151 GstClockTimeDiff diff;
153 g_assert (gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
155 diff = GST_CLOCK_DIFF (requested, wait_ctx->reference);
158 status = GST_CLOCK_EARLY;
160 status = GST_CLOCK_OK;
163 g_atomic_int_set (&GST_CLOCK_ENTRY_STATUS (entry), status);
166 if (GST_CLOCK_ENTRY_TYPE (entry) == GST_CLOCK_ENTRY_SINGLE) {
167 GstClockClass *klass = GST_CLOCK_GET_CLASS (wait_ctx->test_clock);
168 GstClock *clock = GST_CLOCK (wait_ctx->test_clock);
170 klass->unschedule (clock, wait_ctx->id);
171 g_assert (!gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
173 GST_CLOCK_ENTRY_TIME (entry) += GST_CLOCK_ENTRY_INTERVAL (entry);
174 g_assert (gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
177 gst_clock_id_unref (wait_ctx->id);
178 gst_object_unref (wait_ctx->test_clock);
179 g_slice_free (GtuClockWaitContext, wait_ctx);
185 gst_test_util_clock_wait_context_has_completed (GtuClockWaitContext * wait_ctx)
187 GstClock *clock = GST_CLOCK (wait_ctx->test_clock);
188 GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
189 GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
190 GstClockTime now = gst_clock_get_time (clock);
192 return requested < now;
195 GST_START_TEST (test_object_flags)
197 GstClock *clock = gst_test_clock_new ();
198 g_assert (GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC));
199 g_assert (GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_DO_SINGLE_ASYNC));
200 g_assert (GST_OBJECT_FLAG_IS_SET (clock,
201 GST_CLOCK_FLAG_CAN_DO_PERIODIC_SYNC));
202 g_assert (GST_OBJECT_FLAG_IS_SET (clock,
203 GST_CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC));
204 gst_object_unref (clock);
209 GST_START_TEST (test_resolution_query)
211 GstClock *clock = gst_test_clock_new ();
212 g_assert_cmpuint (gst_clock_get_resolution (clock), ==, 1);
213 gst_object_unref (clock);
218 GST_START_TEST (test_start_time)
223 clock = gst_test_clock_new ();
224 g_assert_cmpuint (gst_clock_get_time (clock), ==, 0);
225 g_object_get (clock, "start-time", &start_time, NULL);
226 g_assert_cmpuint (start_time, ==, 0);
227 gst_object_unref (clock);
229 clock = gst_test_clock_new_with_start_time (GST_SECOND);
230 g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND);
231 g_object_get (clock, "start-time", &start_time, NULL);
232 g_assert_cmpuint (start_time, ==, GST_SECOND);
233 gst_object_unref (clock);
238 GST_START_TEST (test_set_time)
240 GstClock *clock = gst_test_clock_new_with_start_time (GST_SECOND);
241 gst_test_clock_set_time (GST_TEST_CLOCK (clock), GST_SECOND);
242 g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND);
243 gst_test_clock_set_time (GST_TEST_CLOCK (clock), GST_SECOND + 1);
244 g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND + 1);
245 gst_object_unref (clock);
250 GST_START_TEST (test_advance_time)
252 GstClock *clock = gst_test_clock_new_with_start_time (GST_SECOND);
253 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 0);
254 g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND);
255 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 42 * GST_MSECOND);
256 g_assert_cmpuint (gst_clock_get_time (clock), ==,
257 GST_SECOND + (42 * GST_MSECOND));
258 gst_object_unref (clock);
263 GST_START_TEST (test_wait_synchronous_no_timeout)
266 GstTestClock *test_clock;
268 GThread *worker_thread;
269 GstClockID pending_id;
270 GstClockID processed_id;
271 SyncClockWaitContext context;
273 clock = gst_test_clock_new_with_start_time (GST_SECOND);
274 test_clock = GST_TEST_CLOCK (clock);
276 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
277 context.clock_id = gst_clock_id_ref (clock_id);
280 g_thread_new ("worker_thread",
281 test_wait_pending_single_shot_id_sync_worker, &context);
282 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
283 assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
285 gst_clock_id_unref (pending_id);
286 processed_id = gst_test_clock_process_next_clock_id (test_clock);
287 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
289 gst_clock_id_unref (processed_id);
290 g_thread_join (worker_thread);
291 g_assert_cmpuint (context.jitter, ==, 1);
292 gst_clock_id_unref (context.clock_id);
293 gst_clock_id_unref (clock_id);
295 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
296 context.clock_id = gst_clock_id_ref (clock_id);
299 g_thread_new ("worker_thread",
300 test_wait_pending_single_shot_id_sync_worker, &context);
301 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
302 assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_SECOND);
303 gst_clock_id_unref (pending_id);
304 processed_id = gst_test_clock_process_next_clock_id (test_clock);
305 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
307 gst_clock_id_unref (processed_id);
308 g_thread_join (worker_thread);
309 g_assert_cmpuint (context.jitter, ==, 0);
310 gst_clock_id_unref (context.clock_id);
311 gst_clock_id_unref (clock_id);
313 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND + 1);
314 context.clock_id = gst_clock_id_ref (clock_id);
317 g_thread_new ("worker_thread",
318 test_wait_pending_single_shot_id_sync_worker, &context);
319 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
320 assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
322 gst_clock_id_unref (pending_id);
323 processed_id = gst_test_clock_process_next_clock_id (test_clock);
324 g_assert (processed_id == NULL);
325 gst_test_clock_advance_time (test_clock, 1);
326 processed_id = gst_test_clock_process_next_clock_id (test_clock);
327 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
329 gst_clock_id_unref (processed_id);
330 g_thread_join (worker_thread);
331 g_assert_cmpuint (context.jitter, ==, -1);
332 gst_clock_id_unref (context.clock_id);
333 gst_clock_id_unref (clock_id);
335 gst_object_unref (clock);
340 GST_START_TEST (test_wait_pending_single_shot_id)
343 GstTestClock *test_clock;
345 GstClockID processed_id;
346 GThread *worker_thread;
347 GstClockID pending_id;
349 clock = gst_test_clock_new_with_start_time (GST_SECOND);
350 test_clock = GST_TEST_CLOCK (clock);
352 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
353 gst_clock_id_wait_async (clock_id, test_async_wait_cb, NULL, NULL);
354 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
355 assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_SECOND);
356 gst_clock_id_unref (pending_id);
357 processed_id = gst_test_clock_process_next_clock_id (test_clock);
358 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
360 gst_clock_id_unref (processed_id);
361 gst_clock_id_unref (clock_id);
363 clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
365 g_thread_new ("worker_thread",
366 test_wait_pending_single_shot_id_async_worker, clock_id);
367 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
368 assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
370 gst_clock_id_unref (pending_id);
371 g_thread_join (worker_thread);
372 gst_clock_id_unref (clock_id);
374 clock_id = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
376 g_thread_new ("worker_thread",
377 test_wait_pending_single_shot_id_async_worker, clock_id);
378 gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
379 g_thread_join (worker_thread);
380 gst_clock_id_unref (clock_id);
382 gst_object_unref (clock);
387 GST_START_TEST (test_wait_pending_periodic_id)
390 GstTestClock *test_clock;
392 GstClockID processed_id;
394 clock = gst_test_clock_new_with_start_time (GST_SECOND);
395 test_clock = GST_TEST_CLOCK (clock);
396 clock_id = gst_clock_new_periodic_id (clock, GST_SECOND, GST_MSECOND);
399 GThread *waiter_thread;
402 g_thread_new ("waiter_thread",
403 test_wait_pending_periodic_id_waiter_thread, clock_id);
405 gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
406 gst_test_clock_set_time (test_clock, GST_SECOND);
407 processed_id = gst_test_clock_process_next_clock_id (test_clock);
408 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
410 gst_clock_id_unref (processed_id);
412 g_thread_join (waiter_thread);
417 GThread *waiter_thread;
419 for (i = 0; i < 3; i++) {
420 g_assert (!gst_test_clock_peek_next_pending_id (test_clock, NULL));
421 g_usleep (G_USEC_PER_SEC / 10 / 10);
425 g_thread_new ("waiter_thread",
426 test_wait_pending_periodic_id_waiter_thread, clock_id);
428 gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
429 gst_clock_id_unschedule (clock_id);
431 g_thread_join (waiter_thread);
434 gst_clock_id_unref (clock_id);
435 gst_object_unref (clock);
440 GST_START_TEST (test_single_shot_sync_past)
443 GstTestClock *test_clock;
445 GstClockTimeDiff jitter;
446 GtuClockWaitContext *wait_ctx;
448 clock = gst_test_clock_new_with_start_time (GST_SECOND);
449 test_clock = GST_TEST_CLOCK (clock);
451 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
453 gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
454 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_EARLY);
455 g_assert_cmpint (jitter, ==, 1);
456 gst_clock_id_unref (clock_id);
458 gst_object_unref (clock);
463 GST_START_TEST (test_single_shot_sync_present)
466 GstTestClock *test_clock;
468 GstClockTimeDiff jitter;
469 GtuClockWaitContext *wait_ctx;
471 clock = gst_test_clock_new_with_start_time (GST_SECOND);
472 test_clock = GST_TEST_CLOCK (clock);
474 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
476 gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
477 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_OK);
478 g_assert_cmpint (jitter, ==, 0);
479 gst_clock_id_unref (clock_id);
481 gst_object_unref (clock);
486 GST_START_TEST (test_single_shot_sync_future)
489 GstTestClock *test_clock;
491 GstClockTimeDiff jitter;
492 GtuClockWaitContext *wait_ctx;
494 clock = gst_test_clock_new_with_start_time (GST_SECOND);
495 test_clock = GST_TEST_CLOCK (clock);
497 clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
499 gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
500 gst_test_clock_advance_time (test_clock, GST_SECOND);
501 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_OK);
502 g_assert_cmpint (jitter, ==, -GST_SECOND);
503 gst_clock_id_unref (clock_id);
505 gst_object_unref (clock);
510 GST_START_TEST (test_single_shot_sync_unschedule)
513 GstTestClock *test_clock;
515 GtuClockWaitContext *wait_ctx;
516 gboolean wait_complete = FALSE;
518 clock = gst_test_clock_new_with_start_time (GST_SECOND);
519 test_clock = GST_TEST_CLOCK (clock);
521 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
522 gst_clock_id_unschedule (clock_id);
523 /* any wait should timeout immediately */
524 g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
525 &wait_complete, NULL) == GST_CLOCK_UNSCHEDULED);
526 g_assert (gst_clock_id_wait (clock_id, NULL) == GST_CLOCK_UNSCHEDULED);
527 gst_clock_id_unref (clock_id);
529 clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
530 wait_ctx = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
531 gst_clock_id_unschedule (clock_id);
532 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx)
533 == GST_CLOCK_UNSCHEDULED);
534 gst_clock_id_unref (clock_id);
536 gst_object_unref (clock);
541 GST_START_TEST (test_single_shot_sync_ordering)
544 GstTestClock *test_clock;
545 GstClockID clock_id_a, clock_id_b;
546 GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
548 clock = gst_test_clock_new_with_start_time (GST_SECOND);
549 test_clock = GST_TEST_CLOCK (clock);
551 clock_id_a = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
553 gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_a, NULL);
555 gst_test_clock_advance_time (test_clock, GST_SECOND);
557 clock_id_b = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
559 gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b, NULL);
561 gst_test_clock_advance_time (test_clock, GST_SECOND);
563 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_b) == GST_CLOCK_OK);
564 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_a) == GST_CLOCK_OK);
566 gst_clock_id_unref (clock_id_b);
567 gst_clock_id_unref (clock_id_a);
569 gst_object_unref (clock);
574 GST_START_TEST (test_single_shot_sync_ordering_parallel)
577 GstTestClock *test_clock;
578 GstClockID clock_id_a, clock_id_b;
579 GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
581 clock = gst_test_clock_new_with_start_time (GST_SECOND);
582 test_clock = GST_TEST_CLOCK (clock);
584 clock_id_a = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
585 clock_id_b = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
586 wait_ctx_a = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_a,
588 wait_ctx_b = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b,
591 g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
593 gst_test_clock_advance_time (test_clock, GST_SECOND);
594 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_b) == GST_CLOCK_OK);
596 g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
598 gst_test_clock_advance_time (test_clock, GST_SECOND);
599 g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_a) == GST_CLOCK_OK);
601 gst_clock_id_unref (clock_id_b);
602 gst_clock_id_unref (clock_id_a);
604 gst_object_unref (clock);
609 GST_START_TEST (test_single_shot_sync_simultaneous_no_timeout)
612 GstTestClock *test_clock;
613 GstClockID clock_id_a;
614 GstClockID clock_id_b;
615 SyncClockWaitContext context_a;
616 SyncClockWaitContext context_b;
617 GThread *worker_thread_a;
618 GThread *worker_thread_b;
619 GstClockID processed_id;
620 GstClockID pending_id;
622 clock = gst_test_clock_new_with_start_time (GST_SECOND);
623 test_clock = GST_TEST_CLOCK (clock);
625 clock_id_a = gst_clock_new_single_shot_id (clock, 5 * GST_SECOND);
626 clock_id_b = gst_clock_new_single_shot_id (clock, 6 * GST_SECOND);
628 context_a.clock_id = gst_clock_id_ref (clock_id_a);
629 context_a.jitter = 0;
630 context_b.clock_id = gst_clock_id_ref (clock_id_b);
631 context_b.jitter = 0;
633 gst_test_clock_wait_for_multiple_pending_ids (test_clock, 0, NULL);
636 g_thread_new ("worker_thread_b",
637 test_wait_pending_single_shot_id_sync_worker, &context_b);
639 gst_test_clock_wait_for_multiple_pending_ids (test_clock, 1, NULL);
640 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
641 assert_pending_id (pending_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE,
643 gst_clock_id_unref (pending_id);
646 g_thread_new ("worker_thread_a",
647 test_wait_pending_single_shot_id_sync_worker, &context_a);
649 gst_test_clock_wait_for_multiple_pending_ids (test_clock, 2, NULL);
650 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
651 assert_pending_id (pending_id, clock_id_a, GST_CLOCK_ENTRY_SINGLE,
653 gst_clock_id_unref (pending_id);
655 g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
657 gst_test_clock_advance_time (test_clock, 5 * GST_SECOND);
658 processed_id = gst_test_clock_process_next_clock_id (test_clock);
659 assert_processed_id (processed_id, clock_id_a, GST_CLOCK_ENTRY_SINGLE,
661 gst_clock_id_unref (processed_id);
663 gst_test_clock_wait_for_multiple_pending_ids (test_clock, 1, NULL);
664 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
665 assert_pending_id (pending_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE,
667 gst_clock_id_unref (pending_id);
669 g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
671 gst_test_clock_advance_time (test_clock, 6 * GST_SECOND);
672 processed_id = gst_test_clock_process_next_clock_id (test_clock);
673 assert_processed_id (processed_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE,
675 gst_clock_id_unref (processed_id);
677 gst_test_clock_wait_for_multiple_pending_ids (test_clock, 0, NULL);
679 g_thread_join (worker_thread_a);
680 g_thread_join (worker_thread_b);
682 g_assert_cmpuint (context_a.jitter, ==, -4 * GST_SECOND);
683 g_assert_cmpuint (context_b.jitter, ==, -5 * GST_SECOND);
685 gst_clock_id_unref (context_a.clock_id);
686 gst_clock_id_unref (context_b.clock_id);
688 gst_clock_id_unref (clock_id_a);
689 gst_clock_id_unref (clock_id_b);
691 gst_object_unref (clock);
696 GST_START_TEST (test_processing_multiple_ids)
699 GstTestClock *test_clock;
700 GstClockID clock_id_a;
701 GstClockID clock_id_b;
702 SyncClockWaitContext context_a;
703 SyncClockWaitContext context_b;
704 GThread *worker_thread_a;
705 GThread *worker_thread_b;
706 GList *pending_list = NULL;
708 clock = gst_test_clock_new_with_start_time (GST_SECOND);
709 test_clock = GST_TEST_CLOCK (clock);
711 /* register a wait for 5 seconds */
712 clock_id_a = gst_clock_new_single_shot_id (clock, 5 * GST_SECOND);
713 context_a.clock_id = gst_clock_id_ref (clock_id_a);
714 context_a.jitter = 0;
716 g_thread_new ("worker_thread_a",
717 test_wait_pending_single_shot_id_sync_worker, &context_a);
719 /* register another wait for 6 seconds */
720 clock_id_b = gst_clock_new_single_shot_id (clock, 6 * GST_SECOND);
721 context_b.clock_id = gst_clock_id_ref (clock_id_b);
722 context_b.jitter = 0;
724 g_thread_new ("worker_thread_b",
725 test_wait_pending_single_shot_id_sync_worker, &context_b);
727 /* wait for two waits */
728 gst_test_clock_wait_for_multiple_pending_ids (test_clock, 2, &pending_list);
730 /* assert they are correct */
731 assert_pending_id (pending_list->data, clock_id_a, GST_CLOCK_ENTRY_SINGLE,
733 assert_pending_id (pending_list->next->data, clock_id_b,
734 GST_CLOCK_ENTRY_SINGLE, 6 * GST_SECOND);
736 /* verify we are waiting for 6 seconds as the latest time */
737 fail_unless_equals_int64 (6 * GST_SECOND,
738 gst_test_clock_id_list_get_latest_time (pending_list));
740 /* process both ID's at the same time */
741 gst_test_clock_process_id_list (test_clock, pending_list);
742 g_list_free_full (pending_list, (GDestroyNotify) gst_clock_id_unref);
744 g_thread_join (worker_thread_a);
745 g_thread_join (worker_thread_b);
747 fail_unless_equals_int64 (-4 * GST_SECOND, context_a.jitter);
748 fail_unless_equals_int64 (-5 * GST_SECOND, context_b.jitter);
750 gst_clock_id_unref (context_a.clock_id);
751 gst_clock_id_unref (context_b.clock_id);
753 gst_clock_id_unref (clock_id_a);
754 gst_clock_id_unref (clock_id_b);
756 gst_object_unref (clock);
761 GST_START_TEST (test_single_shot_async_past)
765 GstClockID processed_id;
766 gboolean wait_complete = FALSE;
768 clock = gst_test_clock_new_with_start_time (GST_SECOND);
769 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
770 g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
771 &wait_complete, NULL) == GST_CLOCK_OK);
772 g_assert (!wait_complete);
773 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
774 g_assert (wait_complete);
775 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
777 gst_clock_id_unref (processed_id);
778 gst_clock_id_unref (clock_id);
779 gst_object_unref (clock);
784 GST_START_TEST (test_single_shot_async_present)
788 GstClockID processed_id;
789 gboolean wait_complete = FALSE;
791 clock = gst_test_clock_new_with_start_time (GST_SECOND);
792 clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
793 g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
794 &wait_complete, NULL) == GST_CLOCK_OK);
795 g_assert (!wait_complete);
796 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
797 g_assert (wait_complete);
798 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
800 gst_clock_id_unref (processed_id);
801 gst_clock_id_unref (clock_id);
802 gst_object_unref (clock);
807 GST_START_TEST (test_single_shot_async_future)
811 GstClockID processed_id;
812 gboolean wait_complete = FALSE;
814 clock = gst_test_clock_new_with_start_time (GST_SECOND);
815 clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
816 g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
817 &wait_complete, NULL) == GST_CLOCK_OK);
818 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
819 g_assert (processed_id == NULL);
820 g_assert (!wait_complete);
821 g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
824 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), GST_SECOND - 1);
825 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
826 g_assert (processed_id == NULL);
827 g_assert (!wait_complete);
828 g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
831 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
832 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
833 g_assert (wait_complete);
834 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
836 gst_clock_id_unref (processed_id);
837 g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
840 gst_clock_id_unref (clock_id);
841 gst_object_unref (clock);
846 GST_START_TEST (test_single_shot_async_unschedule)
850 gboolean wait_complete = FALSE;
852 clock = gst_test_clock_new_with_start_time (GST_SECOND);
854 clock_id = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
855 g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
856 &wait_complete, NULL) == GST_CLOCK_OK);
858 gst_clock_id_unschedule (clock_id);
860 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 2 * GST_SECOND);
861 g_assert (gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock))
863 g_assert (!wait_complete);
865 gst_clock_id_unref (clock_id);
866 gst_object_unref (clock);
871 GST_START_TEST (test_periodic_sync)
874 GstTestClock *test_clock;
877 const GstClockTime interval = 4 * GST_MSECOND;
879 clock = gst_test_clock_new ();
880 test_clock = GST_TEST_CLOCK (clock);
882 clock_id = gst_clock_new_periodic_id (clock, GST_SECOND, interval);
884 for (i = 0; i < 3; i++) {
885 GtuClockWaitContext *wait_ctx;
886 GstClockID pending_id;
890 gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
892 gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
893 assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
894 GST_SECOND + (i * interval));
895 gst_clock_id_unref (pending_id);
897 for (j = 0; j < 10; j++) {
898 g_usleep (G_USEC_PER_SEC / 10 / 10);
899 g_assert (!gst_test_util_clock_wait_context_has_completed (wait_ctx));
903 gst_test_clock_advance_time (test_clock, GST_SECOND);
905 gst_test_clock_advance_time (test_clock, interval);
907 gst_test_util_wait_for_clock_id_end (wait_ctx);
910 gst_clock_id_unref (clock_id);
911 gst_object_unref (clock);
916 GST_START_TEST (test_periodic_async)
920 GstClockID processed_id;
921 gboolean wait_complete = FALSE;
922 const GstClockTime interval = 4 * GST_MSECOND;
924 clock = gst_test_clock_new ();
925 clock_id = gst_clock_new_periodic_id (clock, gst_clock_get_time (clock),
927 g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
928 &wait_complete, NULL) == GST_CLOCK_OK);
930 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
931 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
933 gst_clock_id_unref (processed_id);
935 g_assert (wait_complete);
936 wait_complete = FALSE;
938 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), interval - 1);
939 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
940 g_assert (processed_id == NULL);
941 g_assert (!wait_complete);
943 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
944 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
945 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
947 gst_clock_id_unref (processed_id);
948 g_assert (wait_complete);
949 wait_complete = FALSE;
951 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), interval - 1);
952 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
953 g_assert (processed_id == NULL);
954 g_assert (!wait_complete);
956 gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
957 processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
958 assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
960 gst_clock_id_unref (processed_id);
961 g_assert (wait_complete);
962 wait_complete = FALSE;
964 gst_clock_id_unref (clock_id);
965 gst_object_unref (clock);
970 GST_START_TEST (test_periodic_uniqueness)
973 GstTestClock *test_clock;
976 const GstClockTime interval = 4 * GST_MSECOND;
978 clock = gst_test_clock_new ();
979 test_clock = GST_TEST_CLOCK (clock);
981 clock_id = gst_clock_new_periodic_id (clock, 0, interval);
983 for (i = 0; i < 3; i++) {
984 GtuClockWaitContext *wait_ctx;
988 gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
990 for (j = 0; j < 10; j++) {
991 g_usleep (G_USEC_PER_SEC / 10 / 10);
992 g_assert_cmpuint (gst_test_clock_peek_id_count (test_clock), ==, 1);
995 gst_test_clock_advance_time (test_clock, interval);
996 gst_test_util_wait_for_clock_id_end (wait_ctx);
999 gst_clock_id_unref (clock_id);
1000 gst_object_unref (clock);
1005 GST_START_TEST (test_crank)
1008 GstTestClock *test_clock;
1009 GstClockID clock_id;
1010 SyncClockWaitContext context;
1011 GThread *worker_thread;
1013 clock = gst_test_clock_new_with_start_time (GST_SECOND);
1014 test_clock = GST_TEST_CLOCK (clock);
1016 /* register a wait for 5 seconds */
1017 clock_id = gst_clock_new_single_shot_id (clock, 5 * GST_SECOND);
1018 context.clock_id = gst_clock_id_ref (clock_id);
1021 g_thread_new ("worker_thread_a",
1022 test_wait_pending_single_shot_id_sync_worker, &context);
1025 gst_test_clock_crank (test_clock);
1027 /* the clock should have advanced and the wait released */
1028 g_thread_join (worker_thread);
1030 /* 4 seconds was spent waiting for the clock */
1031 fail_unless_equals_int64 (-4 * GST_SECOND, context.jitter);
1033 /* and the clock is now at 5 seconds */
1034 fail_unless_equals_int64 (5 * GST_SECOND, gst_clock_get_time (clock));
1036 gst_clock_id_unref (context.clock_id);
1037 gst_clock_id_unref (clock_id);
1038 gst_object_unref (clock);
1044 gst_test_clock_suite (void)
1046 Suite *s = suite_create ("GstTestClock");
1047 TCase *tc_chain = tcase_create ("testclock");
1049 suite_add_tcase (s, tc_chain);
1051 tcase_add_test (tc_chain, test_object_flags);
1052 tcase_add_test (tc_chain, test_resolution_query);
1053 tcase_add_test (tc_chain, test_start_time);
1054 tcase_add_test (tc_chain, test_set_time);
1055 tcase_add_test (tc_chain, test_advance_time);
1056 tcase_add_test (tc_chain, test_wait_synchronous_no_timeout);
1057 tcase_add_test (tc_chain, test_wait_pending_single_shot_id);
1058 tcase_add_test (tc_chain, test_wait_pending_periodic_id);
1059 tcase_add_test (tc_chain, test_single_shot_sync_simultaneous_no_timeout);
1060 tcase_add_test (tc_chain, test_processing_multiple_ids);
1061 tcase_add_test (tc_chain, test_single_shot_sync_past);
1062 tcase_add_test (tc_chain, test_single_shot_sync_present);
1063 tcase_add_test (tc_chain, test_single_shot_sync_future);
1064 tcase_add_test (tc_chain, test_single_shot_sync_unschedule);
1065 tcase_add_test (tc_chain, test_single_shot_sync_ordering);
1066 tcase_add_test (tc_chain, test_single_shot_sync_ordering_parallel);
1067 tcase_add_test (tc_chain, test_single_shot_async_past);
1068 tcase_add_test (tc_chain, test_single_shot_async_present);
1069 tcase_add_test (tc_chain, test_single_shot_async_future);
1070 tcase_add_test (tc_chain, test_single_shot_async_unschedule);
1071 tcase_add_test (tc_chain, test_periodic_sync);
1072 tcase_add_test (tc_chain, test_periodic_async);
1073 tcase_add_test (tc_chain, test_periodic_uniqueness);
1074 tcase_add_test (tc_chain, test_crank);
1079 GST_CHECK_MAIN (gst_test_clock);