testclock: add crank method
[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 =
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,
284       GST_SECOND - 1);
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,
288       GST_CLOCK_EARLY);
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);
294
295   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
296   context.clock_id = gst_clock_id_ref (clock_id);
297   context.jitter = 0;
298   worker_thread =
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,
306       GST_CLOCK_OK);
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);
312
313   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND + 1);
314   context.clock_id = gst_clock_id_ref (clock_id);
315   context.jitter = 0;
316   worker_thread =
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,
321       GST_SECOND + 1);
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,
328       GST_CLOCK_OK);
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);
334
335   gst_object_unref (clock);
336 }
337
338 GST_END_TEST;
339
340 GST_START_TEST (test_wait_pending_single_shot_id)
341 {
342   GstClock *clock;
343   GstTestClock *test_clock;
344   GstClockID clock_id;
345   GstClockID processed_id;
346   GThread *worker_thread;
347   GstClockID pending_id;
348
349   clock = gst_test_clock_new_with_start_time (GST_SECOND);
350   test_clock = GST_TEST_CLOCK (clock);
351
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,
359       GST_CLOCK_OK);
360   gst_clock_id_unref (processed_id);
361   gst_clock_id_unref (clock_id);
362
363   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
364   worker_thread =
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,
369       2 * GST_SECOND);
370   gst_clock_id_unref (pending_id);
371   g_thread_join (worker_thread);
372   gst_clock_id_unref (clock_id);
373
374   clock_id = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
375   worker_thread =
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);
381
382   gst_object_unref (clock);
383 }
384
385 GST_END_TEST;
386
387 GST_START_TEST (test_wait_pending_periodic_id)
388 {
389   GstClock *clock;
390   GstTestClock *test_clock;
391   GstClockID clock_id;
392   GstClockID processed_id;
393
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);
397
398   {
399     GThread *waiter_thread;
400
401     waiter_thread =
402         g_thread_new ("waiter_thread",
403         test_wait_pending_periodic_id_waiter_thread, clock_id);
404
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,
409         GST_CLOCK_OK);
410     gst_clock_id_unref (processed_id);
411
412     g_thread_join (waiter_thread);
413   }
414
415   {
416     guint i;
417     GThread *waiter_thread;
418
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);
422     }
423
424     waiter_thread =
425         g_thread_new ("waiter_thread",
426         test_wait_pending_periodic_id_waiter_thread, clock_id);
427
428     gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
429     gst_clock_id_unschedule (clock_id);
430
431     g_thread_join (waiter_thread);
432   }
433
434   gst_clock_id_unref (clock_id);
435   gst_object_unref (clock);
436 }
437
438 GST_END_TEST;
439
440 GST_START_TEST (test_single_shot_sync_past)
441 {
442   GstClock *clock;
443   GstTestClock *test_clock;
444   GstClockID clock_id;
445   GstClockTimeDiff jitter;
446   GtuClockWaitContext *wait_ctx;
447
448   clock = gst_test_clock_new_with_start_time (GST_SECOND);
449   test_clock = GST_TEST_CLOCK (clock);
450
451   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
452   wait_ctx =
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);
457
458   gst_object_unref (clock);
459 }
460
461 GST_END_TEST;
462
463 GST_START_TEST (test_single_shot_sync_present)
464 {
465   GstClock *clock;
466   GstTestClock *test_clock;
467   GstClockID clock_id;
468   GstClockTimeDiff jitter;
469   GtuClockWaitContext *wait_ctx;
470
471   clock = gst_test_clock_new_with_start_time (GST_SECOND);
472   test_clock = GST_TEST_CLOCK (clock);
473
474   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
475   wait_ctx =
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);
480
481   gst_object_unref (clock);
482 }
483
484 GST_END_TEST;
485
486 GST_START_TEST (test_single_shot_sync_future)
487 {
488   GstClock *clock;
489   GstTestClock *test_clock;
490   GstClockID clock_id;
491   GstClockTimeDiff jitter;
492   GtuClockWaitContext *wait_ctx;
493
494   clock = gst_test_clock_new_with_start_time (GST_SECOND);
495   test_clock = GST_TEST_CLOCK (clock);
496
497   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
498   wait_ctx =
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);
504
505   gst_object_unref (clock);
506 }
507
508 GST_END_TEST;
509
510 GST_START_TEST (test_single_shot_sync_unschedule)
511 {
512   GstClock *clock;
513   GstTestClock *test_clock;
514   GstClockID clock_id;
515   GtuClockWaitContext *wait_ctx;
516   gboolean wait_complete = FALSE;
517
518   clock = gst_test_clock_new_with_start_time (GST_SECOND);
519   test_clock = GST_TEST_CLOCK (clock);
520
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);
528
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);
535
536   gst_object_unref (clock);
537 }
538
539 GST_END_TEST;
540
541 GST_START_TEST (test_single_shot_sync_ordering)
542 {
543   GstClock *clock;
544   GstTestClock *test_clock;
545   GstClockID clock_id_a, clock_id_b;
546   GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
547
548   clock = gst_test_clock_new_with_start_time (GST_SECOND);
549   test_clock = GST_TEST_CLOCK (clock);
550
551   clock_id_a = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
552   wait_ctx_a =
553       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_a, NULL);
554
555   gst_test_clock_advance_time (test_clock, GST_SECOND);
556
557   clock_id_b = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
558   wait_ctx_b =
559       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b, NULL);
560
561   gst_test_clock_advance_time (test_clock, GST_SECOND);
562
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);
565
566   gst_clock_id_unref (clock_id_b);
567   gst_clock_id_unref (clock_id_a);
568
569   gst_object_unref (clock);
570 }
571
572 GST_END_TEST;
573
574 GST_START_TEST (test_single_shot_sync_ordering_parallel)
575 {
576   GstClock *clock;
577   GstTestClock *test_clock;
578   GstClockID clock_id_a, clock_id_b;
579   GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
580
581   clock = gst_test_clock_new_with_start_time (GST_SECOND);
582   test_clock = GST_TEST_CLOCK (clock);
583
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,
587       NULL);
588   wait_ctx_b = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b,
589       NULL);
590
591   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
592       2 * GST_SECOND);
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);
595
596   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
597       3 * GST_SECOND);
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);
600
601   gst_clock_id_unref (clock_id_b);
602   gst_clock_id_unref (clock_id_a);
603
604   gst_object_unref (clock);
605 }
606
607 GST_END_TEST;
608
609 GST_START_TEST (test_single_shot_sync_simultaneous_no_timeout)
610 {
611   GstClock *clock;
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;
621
622   clock = gst_test_clock_new_with_start_time (GST_SECOND);
623   test_clock = GST_TEST_CLOCK (clock);
624
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);
627
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;
632
633   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 0, NULL);
634
635   worker_thread_b =
636       g_thread_new ("worker_thread_b",
637       test_wait_pending_single_shot_id_sync_worker, &context_b);
638
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,
642       6 * GST_SECOND);
643   gst_clock_id_unref (pending_id);
644
645   worker_thread_a =
646       g_thread_new ("worker_thread_a",
647       test_wait_pending_single_shot_id_sync_worker, &context_a);
648
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,
652       5 * GST_SECOND);
653   gst_clock_id_unref (pending_id);
654
655   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
656       5 * GST_SECOND);
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,
660       GST_CLOCK_OK);
661   gst_clock_id_unref (processed_id);
662
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,
666       6 * GST_SECOND);
667   gst_clock_id_unref (pending_id);
668
669   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
670       6 * GST_SECOND);
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,
674       GST_CLOCK_OK);
675   gst_clock_id_unref (processed_id);
676
677   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 0, NULL);
678
679   g_thread_join (worker_thread_a);
680   g_thread_join (worker_thread_b);
681
682   g_assert_cmpuint (context_a.jitter, ==, -4 * GST_SECOND);
683   g_assert_cmpuint (context_b.jitter, ==, -5 * GST_SECOND);
684
685   gst_clock_id_unref (context_a.clock_id);
686   gst_clock_id_unref (context_b.clock_id);
687
688   gst_clock_id_unref (clock_id_a);
689   gst_clock_id_unref (clock_id_b);
690
691   gst_object_unref (clock);
692 }
693
694 GST_END_TEST;
695
696 GST_START_TEST (test_processing_multiple_ids)
697 {
698   GstClock *clock;
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;
707
708   clock = gst_test_clock_new_with_start_time (GST_SECOND);
709   test_clock = GST_TEST_CLOCK (clock);
710
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;
715   worker_thread_a =
716       g_thread_new ("worker_thread_a",
717       test_wait_pending_single_shot_id_sync_worker, &context_a);
718
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;
723   worker_thread_b =
724       g_thread_new ("worker_thread_b",
725       test_wait_pending_single_shot_id_sync_worker, &context_b);
726
727   /* wait for two waits */
728   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 2, &pending_list);
729
730   /* assert they are correct */
731   assert_pending_id (pending_list->data, clock_id_a, GST_CLOCK_ENTRY_SINGLE,
732       5 * GST_SECOND);
733   assert_pending_id (pending_list->next->data, clock_id_b,
734       GST_CLOCK_ENTRY_SINGLE, 6 * GST_SECOND);
735
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));
739
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);
743
744   g_thread_join (worker_thread_a);
745   g_thread_join (worker_thread_b);
746
747   fail_unless_equals_int64 (-4 * GST_SECOND, context_a.jitter);
748   fail_unless_equals_int64 (-5 * GST_SECOND, context_b.jitter);
749
750   gst_clock_id_unref (context_a.clock_id);
751   gst_clock_id_unref (context_b.clock_id);
752
753   gst_clock_id_unref (clock_id_a);
754   gst_clock_id_unref (clock_id_b);
755
756   gst_object_unref (clock);
757 }
758
759 GST_END_TEST;
760
761 GST_START_TEST (test_single_shot_async_past)
762 {
763   GstClock *clock;
764   GstClockID clock_id;
765   GstClockID processed_id;
766   gboolean wait_complete = FALSE;
767
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,
776       GST_CLOCK_EARLY);
777   gst_clock_id_unref (processed_id);
778   gst_clock_id_unref (clock_id);
779   gst_object_unref (clock);
780 }
781
782 GST_END_TEST;
783
784 GST_START_TEST (test_single_shot_async_present)
785 {
786   GstClock *clock;
787   GstClockID clock_id;
788   GstClockID processed_id;
789   gboolean wait_complete = FALSE;
790
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,
799       GST_CLOCK_OK);
800   gst_clock_id_unref (processed_id);
801   gst_clock_id_unref (clock_id);
802   gst_object_unref (clock);
803 }
804
805 GST_END_TEST;
806
807 GST_START_TEST (test_single_shot_async_future)
808 {
809   GstClock *clock;
810   GstClockID clock_id;
811   GstClockID processed_id;
812   gboolean wait_complete = FALSE;
813
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))
822       == GST_CLOCK_OK);
823
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))
829       == GST_CLOCK_OK);
830
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,
835       GST_CLOCK_OK);
836   gst_clock_id_unref (processed_id);
837   g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
838       == GST_CLOCK_OK);
839
840   gst_clock_id_unref (clock_id);
841   gst_object_unref (clock);
842 }
843
844 GST_END_TEST;
845
846 GST_START_TEST (test_single_shot_async_unschedule)
847 {
848   GstClock *clock;
849   GstClockID clock_id;
850   gboolean wait_complete = FALSE;
851
852   clock = gst_test_clock_new_with_start_time (GST_SECOND);
853
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);
857
858   gst_clock_id_unschedule (clock_id);
859
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))
862       == NULL);
863   g_assert (!wait_complete);
864
865   gst_clock_id_unref (clock_id);
866   gst_object_unref (clock);
867 }
868
869 GST_END_TEST;
870
871 GST_START_TEST (test_periodic_sync)
872 {
873   GstClock *clock;
874   GstTestClock *test_clock;
875   GstClockID clock_id;
876   guint i;
877   const GstClockTime interval = 4 * GST_MSECOND;
878
879   clock = gst_test_clock_new ();
880   test_clock = GST_TEST_CLOCK (clock);
881
882   clock_id = gst_clock_new_periodic_id (clock, GST_SECOND, interval);
883
884   for (i = 0; i < 3; i++) {
885     GtuClockWaitContext *wait_ctx;
886     GstClockID pending_id;
887     guint j;
888
889     wait_ctx =
890         gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
891
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);
896
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));
900     }
901
902     if (i == 0)
903       gst_test_clock_advance_time (test_clock, GST_SECOND);
904     else
905       gst_test_clock_advance_time (test_clock, interval);
906
907     gst_test_util_wait_for_clock_id_end (wait_ctx);
908   }
909
910   gst_clock_id_unref (clock_id);
911   gst_object_unref (clock);
912 }
913
914 GST_END_TEST;
915
916 GST_START_TEST (test_periodic_async)
917 {
918   GstClock *clock;
919   GstClockID clock_id;
920   GstClockID processed_id;
921   gboolean wait_complete = FALSE;
922   const GstClockTime interval = 4 * GST_MSECOND;
923
924   clock = gst_test_clock_new ();
925   clock_id = gst_clock_new_periodic_id (clock, gst_clock_get_time (clock),
926       interval);
927   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
928           &wait_complete, NULL) == GST_CLOCK_OK);
929
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,
932       GST_CLOCK_OK);
933   gst_clock_id_unref (processed_id);
934
935   g_assert (wait_complete);
936   wait_complete = FALSE;
937
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);
942
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,
946       GST_CLOCK_OK);
947   gst_clock_id_unref (processed_id);
948   g_assert (wait_complete);
949   wait_complete = FALSE;
950
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);
955
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,
959       GST_CLOCK_OK);
960   gst_clock_id_unref (processed_id);
961   g_assert (wait_complete);
962   wait_complete = FALSE;
963
964   gst_clock_id_unref (clock_id);
965   gst_object_unref (clock);
966 }
967
968 GST_END_TEST;
969
970 GST_START_TEST (test_periodic_uniqueness)
971 {
972   GstClock *clock;
973   GstTestClock *test_clock;
974   GstClockID clock_id;
975   guint i;
976   const GstClockTime interval = 4 * GST_MSECOND;
977
978   clock = gst_test_clock_new ();
979   test_clock = GST_TEST_CLOCK (clock);
980
981   clock_id = gst_clock_new_periodic_id (clock, 0, interval);
982
983   for (i = 0; i < 3; i++) {
984     GtuClockWaitContext *wait_ctx;
985     guint j;
986
987     wait_ctx =
988         gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
989
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);
993     }
994
995     gst_test_clock_advance_time (test_clock, interval);
996     gst_test_util_wait_for_clock_id_end (wait_ctx);
997   }
998
999   gst_clock_id_unref (clock_id);
1000   gst_object_unref (clock);
1001 }
1002
1003 GST_END_TEST;
1004
1005 GST_START_TEST (test_crank)
1006 {
1007   GstClock *clock;
1008   GstTestClock *test_clock;
1009   GstClockID clock_id;
1010   SyncClockWaitContext context;
1011   GThread *worker_thread;
1012
1013   clock = gst_test_clock_new_with_start_time (GST_SECOND);
1014   test_clock = GST_TEST_CLOCK (clock);
1015
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);
1019   context.jitter = 0;
1020   worker_thread =
1021       g_thread_new ("worker_thread_a",
1022       test_wait_pending_single_shot_id_sync_worker, &context);
1023
1024   /* crank */
1025   gst_test_clock_crank (test_clock);
1026
1027   /* the clock should have advanced and the wait released */
1028   g_thread_join (worker_thread);
1029
1030   /* 4 seconds was spent waiting for the clock */
1031   fail_unless_equals_int64 (-4 * GST_SECOND, context.jitter);
1032
1033   /* and the clock is now at 5 seconds */
1034   fail_unless_equals_int64 (5 * GST_SECOND, gst_clock_get_time (clock));
1035
1036   gst_clock_id_unref (context.clock_id);
1037   gst_clock_id_unref (clock_id);
1038   gst_object_unref (clock);
1039 }
1040
1041 GST_END_TEST;
1042
1043 static Suite *
1044 gst_test_clock_suite (void)
1045 {
1046   Suite *s = suite_create ("GstTestClock");
1047   TCase *tc_chain = tcase_create ("testclock");
1048
1049   suite_add_tcase (s, tc_chain);
1050
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);
1075
1076   return s;
1077 }
1078
1079 GST_CHECK_MAIN (gst_test_clock);