check: allow GstTestClock to handle clock notifications
[platform/upstream/gstreamer.git] / tests / check / libs / gsttestclock.c
1 /*
2  * Unit test for a deterministic clock for Gstreamer unit tests
3  *
4  * Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
5  * Copyright (C) 2012 Sebastian Rasmussen <sebastian.rasmussen@axis.com>
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include <gst/check/gstcheck.h>
24 #include <gst/check/gsttestclock.h>
25
26 typedef struct
27 {
28   GstTestClock *test_clock;
29   GstClockID id;
30   GstClockTime reference;
31 } GtuClockWaitContext;
32
33 typedef struct
34 {
35   GstClockID clock_id;
36   GstClockTimeDiff jitter;
37 } SyncClockWaitContext;
38
39 #define assert_pending_id(pending_id, id, type, time) \
40 G_STMT_START { \
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)); \
45 } G_STMT_END
46
47 #define assert_processed_id(processed_id, id, type, time) \
48 G_STMT_START { \
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)); \
53 } G_STMT_END
54
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);
60
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 *
64     wait_ctx);
65 static gboolean
66 gst_test_util_clock_wait_context_has_completed (GtuClockWaitContext * wait_ctx);
67
68 static gpointer
69 test_wait_pending_single_shot_id_sync_worker (gpointer data)
70 {
71   SyncClockWaitContext *ctx = data;
72
73   gst_clock_id_wait (ctx->clock_id, &ctx->jitter);
74
75   return NULL;
76 }
77
78 static gpointer
79 test_wait_pending_single_shot_id_async_worker (gpointer data)
80 {
81   GstClockID clock_id = data;
82
83   g_usleep (G_USEC_PER_SEC / 10);
84   gst_clock_id_wait_async (clock_id, test_async_wait_cb, NULL, NULL);
85
86   return NULL;
87 }
88
89 static gpointer
90 test_wait_pending_periodic_id_waiter_thread (gpointer data)
91 {
92   GstClockID clock_id = data;
93   gst_clock_id_wait (clock_id, NULL);
94   return NULL;
95 }
96
97 static gboolean
98 test_async_wait_cb (GstClock * clock,
99     GstClockTime time, GstClockID id, gpointer user_data)
100 {
101
102   gboolean *wait_complete = user_data;
103
104   if (wait_complete != NULL)
105     *wait_complete = TRUE;
106
107   return TRUE;
108 }
109
110 static GtuClockWaitContext *
111 gst_test_util_wait_for_clock_id_begin (GstTestClock * test_clock, GstClockID id,
112     GstClockTimeDiff * jitter)
113 {
114   GtuClockWaitContext *wait_ctx;
115
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);
120
121   if (jitter) {
122     GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
123     GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
124     GstClockTime reference = wait_ctx->reference;
125
126     *jitter = GST_CLOCK_DIFF (requested, reference);
127   }
128
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);
133   }
134
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);
137
138   return wait_ctx;
139 }
140
141 static GstClockReturn
142 gst_test_util_wait_for_clock_id_end (GtuClockWaitContext * wait_ctx)
143 {
144   GstClockReturn status = GST_CLOCK_ERROR;
145   GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
146
147   if (G_UNLIKELY (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED)) {
148     status = GST_CLOCK_UNSCHEDULED;
149   } else {
150     GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
151     GstClockTimeDiff diff;
152
153     g_assert (gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
154
155     diff = GST_CLOCK_DIFF (requested, wait_ctx->reference);
156
157     if (diff > 0) {
158       status = GST_CLOCK_EARLY;
159     } else {
160       status = GST_CLOCK_OK;
161     }
162
163     g_atomic_int_set (&GST_CLOCK_ENTRY_STATUS (entry), status);
164   }
165
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);
169
170     klass->unschedule (clock, wait_ctx->id);
171     g_assert (!gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
172   } else {
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));
175   }
176
177   gst_clock_id_unref (wait_ctx->id);
178   gst_object_unref (wait_ctx->test_clock);
179   g_slice_free (GtuClockWaitContext, wait_ctx);
180
181   return status;
182 }
183
184 static gboolean
185 gst_test_util_clock_wait_context_has_completed (GtuClockWaitContext * wait_ctx)
186 {
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);
191
192   return requested < now;
193 }
194
195 GST_START_TEST (test_object_flags)
196 {
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);
205 }
206
207 GST_END_TEST;
208
209 GST_START_TEST (test_resolution_query)
210 {
211   GstClock *clock = gst_test_clock_new ();
212   g_assert_cmpuint (gst_clock_get_resolution (clock), ==, 1);
213   gst_object_unref (clock);
214 }
215
216 GST_END_TEST;
217
218 GST_START_TEST (test_start_time)
219 {
220   GstClock *clock;
221   guint64 start_time;
222
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);
228
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);
234 }
235
236 GST_END_TEST;
237
238 GST_START_TEST (test_set_time)
239 {
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);
246 }
247
248 GST_END_TEST;
249
250 GST_START_TEST (test_advance_time)
251 {
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);
259 }
260
261 GST_END_TEST;
262
263 GST_START_TEST (test_wait_synchronous_no_timeout)
264 {
265   GstClock *clock;
266   GstTestClock *test_clock;
267   GstClockID clock_id;
268   GThread *worker_thread;
269   GstClockID pending_id;
270   GstClockID processed_id;
271   SyncClockWaitContext context;
272
273   clock = gst_test_clock_new_with_start_time (GST_SECOND);
274   test_clock = GST_TEST_CLOCK (clock);
275
276   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
277   context.clock_id = gst_clock_id_ref (clock_id);
278   context.jitter = 0;
279   worker_thread = g_thread_create (test_wait_pending_single_shot_id_sync_worker,
280       &context, TRUE, NULL);
281   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
282   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_SECOND - 1);
283   gst_clock_id_unref (pending_id);
284   processed_id = gst_test_clock_process_next_clock_id (test_clock);
285   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_EARLY);
286   gst_clock_id_unref (processed_id);
287   g_thread_join (worker_thread);
288   g_assert_cmpuint (context.jitter, ==, 1);
289   gst_clock_id_unref (context.clock_id);
290   gst_clock_id_unref (clock_id);
291
292   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
293   context.clock_id = gst_clock_id_ref (clock_id);
294   context.jitter = 0;
295   worker_thread = g_thread_create (test_wait_pending_single_shot_id_sync_worker,
296       &context, TRUE, NULL);
297   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
298   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_SECOND);
299   gst_clock_id_unref (pending_id);
300   processed_id = gst_test_clock_process_next_clock_id (test_clock);
301   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_OK);
302   gst_clock_id_unref (processed_id);
303   g_thread_join (worker_thread);
304   g_assert_cmpuint (context.jitter, ==, 0);
305   gst_clock_id_unref (context.clock_id);
306   gst_clock_id_unref (clock_id);
307
308   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND + 1);
309   context.clock_id = gst_clock_id_ref (clock_id);
310   context.jitter = 0;
311   worker_thread = g_thread_create (test_wait_pending_single_shot_id_sync_worker,
312       &context, TRUE, NULL);
313   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
314   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_SECOND + 1);
315   gst_clock_id_unref (pending_id);
316   processed_id = gst_test_clock_process_next_clock_id (test_clock);
317   g_assert (processed_id == NULL);
318   gst_test_clock_advance_time (test_clock, 1);
319   processed_id = gst_test_clock_process_next_clock_id (test_clock);
320   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_OK);
321   gst_clock_id_unref (processed_id);
322   g_thread_join (worker_thread);
323   g_assert_cmpuint (context.jitter, ==, -1);
324   gst_clock_id_unref (context.clock_id);
325   gst_clock_id_unref (clock_id);
326
327   gst_object_unref (clock);
328 }
329
330 GST_END_TEST;
331
332 GST_START_TEST (test_wait_pending_single_shot_id)
333 {
334   GstClock *clock;
335   GstTestClock *test_clock;
336   GstClockID clock_id;
337   GstClockID processed_id;
338   GThread *worker_thread;
339   GstClockID pending_id;
340
341   clock = gst_test_clock_new_with_start_time (GST_SECOND);
342   test_clock = GST_TEST_CLOCK (clock);
343
344   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
345   gst_clock_id_wait_async (clock_id, test_async_wait_cb, NULL, NULL);
346   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
347   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_SECOND);
348   gst_clock_id_unref (pending_id);
349   processed_id = gst_test_clock_process_next_clock_id (test_clock);
350   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_OK);
351   gst_clock_id_unref (processed_id);
352   gst_clock_id_unref (clock_id);
353
354   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
355   worker_thread = g_thread_create (test_wait_pending_single_shot_id_async_worker,
356       clock_id, TRUE, NULL);
357   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
358   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, 2 * GST_SECOND);
359   gst_clock_id_unref (pending_id);
360   g_thread_join (worker_thread);
361   gst_clock_id_unref (clock_id);
362
363   clock_id = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
364   worker_thread = g_thread_create (test_wait_pending_single_shot_id_async_worker,
365       clock_id, TRUE, NULL);
366   gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
367   g_thread_join (worker_thread);
368   gst_clock_id_unref (clock_id);
369
370   gst_object_unref (clock);
371 }
372
373 GST_END_TEST;
374
375 GST_START_TEST (test_wait_pending_periodic_id)
376 {
377   GstClock *clock;
378   GstTestClock *test_clock;
379   GstClockID clock_id;
380   GstClockID processed_id;
381
382   clock = gst_test_clock_new_with_start_time (GST_SECOND);
383   test_clock = GST_TEST_CLOCK (clock);
384   clock_id = gst_clock_new_periodic_id (clock, GST_SECOND, GST_MSECOND);
385
386   {
387     GThread *waiter_thread;
388
389     waiter_thread =
390         g_thread_create (test_wait_pending_periodic_id_waiter_thread, clock_id,
391         TRUE, NULL);
392
393     gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
394     gst_test_clock_set_time (test_clock, GST_SECOND);
395     processed_id = gst_test_clock_process_next_clock_id (test_clock);
396     assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC, GST_CLOCK_OK);
397     gst_clock_id_unref (processed_id);
398
399     g_thread_join (waiter_thread);
400   }
401
402   {
403     guint i;
404     GThread *waiter_thread;
405
406     for (i = 0; i < 3; i++) {
407       g_assert (!gst_test_clock_peek_next_pending_id (test_clock, NULL));
408       g_usleep (G_USEC_PER_SEC / 10 / 10);
409     }
410
411     waiter_thread =
412         g_thread_create (test_wait_pending_periodic_id_waiter_thread, clock_id,
413         TRUE, NULL);
414
415     gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
416     gst_clock_id_unschedule (clock_id);
417
418     g_thread_join (waiter_thread);
419   }
420
421   gst_clock_id_unref (clock_id);
422   gst_object_unref (clock);
423 }
424
425 GST_END_TEST;
426
427 GST_START_TEST (test_single_shot_sync_past)
428 {
429   GstClock *clock;
430   GstTestClock *test_clock;
431   GstClockID clock_id;
432   GstClockTimeDiff jitter;
433   GtuClockWaitContext *wait_ctx;
434
435   clock = gst_test_clock_new_with_start_time (GST_SECOND);
436   test_clock = GST_TEST_CLOCK (clock);
437
438   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
439   wait_ctx =
440       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
441   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_EARLY);
442   g_assert_cmpint (jitter, ==, 1);
443   gst_clock_id_unref (clock_id);
444
445   gst_object_unref (clock);
446 }
447
448 GST_END_TEST;
449
450 GST_START_TEST (test_single_shot_sync_present)
451 {
452   GstClock *clock;
453   GstTestClock *test_clock;
454   GstClockID clock_id;
455   GstClockTimeDiff jitter;
456   GtuClockWaitContext *wait_ctx;
457
458   clock = gst_test_clock_new_with_start_time (GST_SECOND);
459   test_clock = GST_TEST_CLOCK (clock);
460
461   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
462   wait_ctx =
463       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
464   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_OK);
465   g_assert_cmpint (jitter, ==, 0);
466   gst_clock_id_unref (clock_id);
467
468   gst_object_unref (clock);
469 }
470
471 GST_END_TEST;
472
473 GST_START_TEST (test_single_shot_sync_future)
474 {
475   GstClock *clock;
476   GstTestClock *test_clock;
477   GstClockID clock_id;
478   GstClockTimeDiff jitter;
479   GtuClockWaitContext *wait_ctx;
480
481   clock = gst_test_clock_new_with_start_time (GST_SECOND);
482   test_clock = GST_TEST_CLOCK (clock);
483
484   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
485   wait_ctx =
486       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
487   gst_test_clock_advance_time (test_clock, GST_SECOND);
488   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_OK);
489   g_assert_cmpint (jitter, ==, -GST_SECOND);
490   gst_clock_id_unref (clock_id);
491
492   gst_object_unref (clock);
493 }
494
495 GST_END_TEST;
496
497 GST_START_TEST (test_single_shot_sync_unschedule)
498 {
499   GstClock *clock;
500   GstTestClock *test_clock;
501   GstClockID clock_id;
502   GtuClockWaitContext *wait_ctx;
503
504   clock = gst_test_clock_new_with_start_time (GST_SECOND);
505   test_clock = GST_TEST_CLOCK (clock);
506
507   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
508   gst_clock_id_unschedule (clock_id);
509   gst_clock_id_unref (clock_id);
510
511   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
512   wait_ctx = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
513   gst_clock_id_unschedule (clock_id);
514   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx)
515       == GST_CLOCK_UNSCHEDULED);
516   gst_clock_id_unref (clock_id);
517
518   gst_object_unref (clock);
519 }
520
521 GST_END_TEST;
522
523 GST_START_TEST (test_single_shot_sync_ordering)
524 {
525   GstClock *clock;
526   GstTestClock *test_clock;
527   GstClockID clock_id_a, clock_id_b;
528   GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
529
530   clock = gst_test_clock_new_with_start_time (GST_SECOND);
531   test_clock = GST_TEST_CLOCK (clock);
532
533   clock_id_a = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
534   wait_ctx_a =
535       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_a, NULL);
536
537   gst_test_clock_advance_time (test_clock, GST_SECOND);
538
539   clock_id_b = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
540   wait_ctx_b =
541       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b, NULL);
542
543   gst_test_clock_advance_time (test_clock, GST_SECOND);
544
545   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_b) == GST_CLOCK_OK);
546   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_a) == GST_CLOCK_OK);
547
548   gst_clock_id_unref (clock_id_b);
549   gst_clock_id_unref (clock_id_a);
550
551   gst_object_unref (clock);
552 }
553
554 GST_END_TEST;
555
556 GST_START_TEST (test_single_shot_sync_ordering_parallel)
557 {
558   GstClock *clock;
559   GstTestClock *test_clock;
560   GstClockID clock_id_a, clock_id_b;
561   GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
562
563   clock = gst_test_clock_new_with_start_time (GST_SECOND);
564   test_clock = GST_TEST_CLOCK (clock);
565
566   clock_id_a = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
567   clock_id_b = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
568   wait_ctx_a = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_a,
569       NULL);
570   wait_ctx_b = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b,
571       NULL);
572
573   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
574       2 * GST_SECOND);
575   gst_test_clock_advance_time (test_clock, GST_SECOND);
576   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_b) == GST_CLOCK_OK);
577
578   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
579       3 * GST_SECOND);
580   gst_test_clock_advance_time (test_clock, GST_SECOND);
581   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_a) == GST_CLOCK_OK);
582
583   gst_clock_id_unref (clock_id_b);
584   gst_clock_id_unref (clock_id_a);
585
586   gst_object_unref (clock);
587 }
588
589 GST_END_TEST;
590
591 GST_START_TEST (test_single_shot_sync_simultaneous_no_timeout)
592 {
593   GstClock *clock;
594   GstTestClock *test_clock;
595   GstClockID clock_id_a;
596   GstClockID clock_id_b;
597   SyncClockWaitContext context_a;
598   SyncClockWaitContext context_b;
599   GThread *worker_thread_a;
600   GThread *worker_thread_b;
601   GstClockID processed_id;
602   GstClockID pending_id;
603
604   clock = gst_test_clock_new_with_start_time (GST_SECOND);
605   test_clock = GST_TEST_CLOCK (clock);
606
607   clock_id_a = gst_clock_new_single_shot_id (clock, 5 * GST_SECOND);
608   clock_id_b = gst_clock_new_single_shot_id (clock, 6 * GST_SECOND);
609
610   context_a.clock_id = gst_clock_id_ref (clock_id_a);
611   context_a.jitter = 0;
612   context_b.clock_id = gst_clock_id_ref (clock_id_b);
613   context_b.jitter = 0;
614
615   gst_test_clock_wait_for_pending_id_count (test_clock, 0);
616
617   worker_thread_b = g_thread_create (test_wait_pending_single_shot_id_sync_worker,
618       &context_b, TRUE, NULL);
619
620   gst_test_clock_wait_for_pending_id_count (test_clock, 1);
621   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
622   assert_pending_id (pending_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE, 6 * GST_SECOND);
623   gst_clock_id_unref (pending_id);
624
625   worker_thread_a = g_thread_create (test_wait_pending_single_shot_id_sync_worker,
626       &context_a, TRUE, NULL);
627
628   gst_test_clock_wait_for_pending_id_count (test_clock, 2);
629   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
630   assert_pending_id (pending_id, clock_id_a, GST_CLOCK_ENTRY_SINGLE, 5 * GST_SECOND);
631   gst_clock_id_unref (pending_id);
632
633   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
634       5 * GST_SECOND);
635   gst_test_clock_advance_time (test_clock, 5 * GST_SECOND);
636   processed_id = gst_test_clock_process_next_clock_id (test_clock);
637   assert_processed_id (processed_id, clock_id_a, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_OK);
638   gst_clock_id_unref (processed_id);
639
640   gst_test_clock_wait_for_pending_id_count (test_clock, 1);
641   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
642   assert_pending_id (pending_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE, 6 * GST_SECOND);
643   gst_clock_id_unref (pending_id);
644
645   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
646       6 * GST_SECOND);
647   gst_test_clock_advance_time (test_clock, 6 * GST_SECOND);
648   processed_id = gst_test_clock_process_next_clock_id (test_clock);
649   assert_processed_id (processed_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_OK);
650   gst_clock_id_unref (processed_id);
651
652   gst_test_clock_wait_for_pending_id_count (test_clock, 0);
653
654   g_thread_join (worker_thread_a);
655   g_thread_join (worker_thread_b);
656
657   g_assert_cmpuint (context_a.jitter, ==, -4 * GST_SECOND);
658   g_assert_cmpuint (context_b.jitter, ==, -5 * GST_SECOND);
659
660   gst_clock_id_unref (context_a.clock_id);
661   gst_clock_id_unref (context_b.clock_id);
662
663   gst_clock_id_unref (clock_id_a);
664   gst_clock_id_unref (clock_id_b);
665
666   gst_object_unref (clock);
667 }
668
669 GST_END_TEST;
670
671 GST_START_TEST (test_single_shot_async_past)
672 {
673   GstClock *clock;
674   GstClockID clock_id;
675   GstClockID processed_id;
676   gboolean wait_complete = FALSE;
677
678   clock = gst_test_clock_new_with_start_time (GST_SECOND);
679   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
680   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
681           &wait_complete, NULL) == GST_CLOCK_OK);
682   g_assert (!wait_complete);
683   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
684   g_assert (wait_complete);
685   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_EARLY);
686   gst_clock_id_unref (processed_id);
687   gst_clock_id_unref (clock_id);
688   gst_object_unref (clock);
689 }
690
691 GST_END_TEST;
692
693 GST_START_TEST (test_single_shot_async_present)
694 {
695   GstClock *clock;
696   GstClockID clock_id;
697   GstClockID processed_id;
698   gboolean wait_complete = FALSE;
699
700   clock = gst_test_clock_new_with_start_time (GST_SECOND);
701   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
702   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
703           &wait_complete, NULL) == GST_CLOCK_OK);
704   g_assert (!wait_complete);
705   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
706   g_assert (wait_complete);
707   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_OK);
708   gst_clock_id_unref (processed_id);
709   gst_clock_id_unref (clock_id);
710   gst_object_unref (clock);
711 }
712
713 GST_END_TEST;
714
715 GST_START_TEST (test_single_shot_async_future)
716 {
717   GstClock *clock;
718   GstClockID clock_id;
719   GstClockID processed_id;
720   gboolean wait_complete = FALSE;
721
722   clock = gst_test_clock_new_with_start_time (GST_SECOND);
723   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
724   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
725           &wait_complete, NULL) == GST_CLOCK_OK);
726   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
727   g_assert (processed_id == NULL);
728   g_assert (!wait_complete);
729   g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
730       == GST_CLOCK_OK);
731
732   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), GST_SECOND - 1);
733   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
734   g_assert (processed_id == NULL);
735   g_assert (!wait_complete);
736   g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
737       == GST_CLOCK_OK);
738
739   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
740   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
741   g_assert (wait_complete);
742   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_CLOCK_OK);
743   gst_clock_id_unref (processed_id);
744   g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
745       == GST_CLOCK_OK);
746
747   gst_clock_id_unref (clock_id);
748   gst_object_unref (clock);
749 }
750
751 GST_END_TEST;
752
753 GST_START_TEST (test_single_shot_async_unschedule)
754 {
755   GstClock *clock;
756   GstClockID clock_id;
757   gboolean wait_complete = FALSE;
758
759   clock = gst_test_clock_new_with_start_time (GST_SECOND);
760
761   clock_id = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
762   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
763           &wait_complete, NULL) == GST_CLOCK_OK);
764
765   gst_clock_id_unschedule (clock_id);
766
767   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 2 * GST_SECOND);
768   g_assert (gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock))
769       == NULL);
770   g_assert (!wait_complete);
771
772   gst_clock_id_unref (clock_id);
773   gst_object_unref (clock);
774 }
775
776 GST_END_TEST;
777
778 GST_START_TEST (test_periodic_sync)
779 {
780   GstClock *clock;
781   GstTestClock *test_clock;
782   GstClockID clock_id;
783   guint i;
784   const GstClockTime interval = 4 * GST_MSECOND;
785
786   clock = gst_test_clock_new ();
787   test_clock = GST_TEST_CLOCK (clock);
788
789   clock_id = gst_clock_new_periodic_id (clock, GST_SECOND, interval);
790
791   for (i = 0; i < 3; i++) {
792     GtuClockWaitContext *wait_ctx;
793     GstClockID pending_id;
794     guint j;
795
796     wait_ctx =
797         gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
798
799     gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
800     assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_PERIODIC, GST_SECOND + (i * interval));
801     gst_clock_id_unref (pending_id);
802
803     for (j = 0; j < 10; j++) {
804       g_usleep (G_USEC_PER_SEC / 10 / 10);
805       g_assert (!gst_test_util_clock_wait_context_has_completed (wait_ctx));
806     }
807
808     if (i == 0)
809       gst_test_clock_advance_time (test_clock, GST_SECOND);
810     else
811       gst_test_clock_advance_time (test_clock, interval);
812
813     gst_test_util_wait_for_clock_id_end (wait_ctx);
814   }
815
816   gst_clock_id_unref (clock_id);
817   gst_object_unref (clock);
818 }
819
820 GST_END_TEST;
821
822 GST_START_TEST (test_periodic_async)
823 {
824   GstClock *clock;
825   GstClockID clock_id;
826   GstClockID processed_id;
827   gboolean wait_complete = FALSE;
828   const GstClockTime interval = 4 * GST_MSECOND;
829
830   clock = gst_test_clock_new ();
831   clock_id = gst_clock_new_periodic_id (clock, gst_clock_get_time (clock),
832       interval);
833   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
834           &wait_complete, NULL) == GST_CLOCK_OK);
835
836   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
837   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC, GST_CLOCK_OK);
838   gst_clock_id_unref (processed_id);
839
840   g_assert (wait_complete);
841   wait_complete = FALSE;
842
843   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), interval - 1);
844   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
845   g_assert (processed_id == NULL);
846   g_assert (!wait_complete);
847
848   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
849   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
850   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC, GST_CLOCK_OK);
851   gst_clock_id_unref (processed_id);
852   g_assert (wait_complete);
853   wait_complete = FALSE;
854
855   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), interval - 1);
856   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
857   g_assert (processed_id == NULL);
858   g_assert (!wait_complete);
859
860   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
861   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
862   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC, GST_CLOCK_OK);
863   gst_clock_id_unref (processed_id);
864   g_assert (wait_complete);
865   wait_complete = FALSE;
866
867   gst_clock_id_unref (clock_id);
868   gst_object_unref (clock);
869 }
870
871 GST_END_TEST;
872
873 GST_START_TEST (test_periodic_uniqueness)
874 {
875   GstClock *clock;
876   GstTestClock *test_clock;
877   GstClockID clock_id;
878   guint i;
879   const GstClockTime interval = 4 * GST_MSECOND;
880
881   clock = gst_test_clock_new ();
882   test_clock = GST_TEST_CLOCK (clock);
883
884   clock_id = gst_clock_new_periodic_id (clock, 0, interval);
885
886   for (i = 0; i < 3; i++) {
887     GtuClockWaitContext *wait_ctx;
888     guint j;
889
890     wait_ctx =
891         gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
892
893     for (j = 0; j < 10; j++) {
894       g_usleep (G_USEC_PER_SEC / 10 / 10);
895       g_assert_cmpuint (gst_test_clock_peek_id_count (test_clock), ==, 1);
896     }
897
898     gst_test_clock_advance_time (test_clock, interval);
899     gst_test_util_wait_for_clock_id_end (wait_ctx);
900   }
901
902   gst_clock_id_unref (clock_id);
903   gst_object_unref (clock);
904 }
905
906 GST_END_TEST;
907
908 static Suite *
909 gst_test_clock_suite (void)
910 {
911   Suite *s = suite_create ("GstTestClock");
912   TCase *tc_chain = tcase_create ("testclock");
913
914   suite_add_tcase (s, tc_chain);
915
916   tcase_add_test (tc_chain, test_object_flags);
917   tcase_add_test (tc_chain, test_resolution_query);
918   tcase_add_test (tc_chain, test_start_time);
919   tcase_add_test (tc_chain, test_set_time);
920   tcase_add_test (tc_chain, test_advance_time);
921   tcase_add_test (tc_chain, test_wait_synchronous_no_timeout);
922   tcase_add_test (tc_chain, test_wait_pending_single_shot_id);
923   tcase_add_test (tc_chain, test_wait_pending_periodic_id);
924   tcase_add_test (tc_chain, test_single_shot_sync_simultaneous_no_timeout);
925   tcase_add_test (tc_chain, test_single_shot_sync_past);
926   tcase_add_test (tc_chain, test_single_shot_sync_present);
927   tcase_add_test (tc_chain, test_single_shot_sync_future);
928   tcase_add_test (tc_chain, test_single_shot_sync_unschedule);
929   tcase_add_test (tc_chain, test_single_shot_sync_ordering);
930   tcase_add_test (tc_chain, test_single_shot_sync_ordering_parallel);
931   tcase_add_test (tc_chain, test_single_shot_async_past);
932   tcase_add_test (tc_chain, test_single_shot_async_present);
933   tcase_add_test (tc_chain, test_single_shot_async_future);
934   tcase_add_test (tc_chain, test_single_shot_async_unschedule);
935   tcase_add_test (tc_chain, test_periodic_sync);
936   tcase_add_test (tc_chain, test_periodic_async);
937   tcase_add_test (tc_chain, test_periodic_uniqueness);
938
939   return s;
940 }
941
942 GST_CHECK_MAIN (gst_test_clock);