• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <gst/check/gstcheck.h>
27 #include <gst/check/gsttestclock.h>
28 
29 typedef struct
30 {
31   GstTestClock *test_clock;
32   GstClockID id;
33   GstClockTime reference;
34 } GtuClockWaitContext;
35 
36 typedef struct
37 {
38   GstClockID clock_id;
39   GstClockTimeDiff jitter;
40 } SyncClockWaitContext;
41 
42 #define assert_pending_id(pending_id, id, type, time) \
43 G_STMT_START { \
44   GstClockEntry *entry = GST_CLOCK_ENTRY (pending_id); \
45   g_assert (entry == (id)); \
46   g_assert (GST_CLOCK_ENTRY_TYPE (entry) == (type)); \
47   g_assert_cmpuint (GST_CLOCK_ENTRY_TIME (entry), ==, (time)); \
48 } G_STMT_END
49 
50 #define assert_processed_id(processed_id, id, type, time) \
51 G_STMT_START { \
52   GstClockEntry *entry = GST_CLOCK_ENTRY (processed_id); \
53   g_assert (entry == (id)); \
54   g_assert (GST_CLOCK_ENTRY_TYPE (entry) == (type)); \
55   g_assert_cmpuint (GST_CLOCK_ENTRY_STATUS (entry), ==, (time)); \
56 } G_STMT_END
57 
58 static gpointer test_wait_pending_single_shot_id_sync_worker (gpointer data);
59 static gpointer test_wait_pending_single_shot_id_async_worker (gpointer data);
60 static gpointer test_wait_pending_periodic_id_waiter_thread (gpointer data);
61 static gboolean test_async_wait_cb (GstClock * clock, GstClockTime time,
62     GstClockID id, gpointer user_data);
63 
64 static GtuClockWaitContext *gst_test_util_wait_for_clock_id_begin (GstTestClock
65     * clock, GstClockID id, GstClockTimeDiff * jitter);
66 static GstClockReturn gst_test_util_wait_for_clock_id_end (GtuClockWaitContext *
67     wait_ctx);
68 static gboolean
69 gst_test_util_clock_wait_context_has_completed (GtuClockWaitContext * wait_ctx);
70 
71 static gpointer
test_wait_pending_single_shot_id_sync_worker(gpointer data)72 test_wait_pending_single_shot_id_sync_worker (gpointer data)
73 {
74   SyncClockWaitContext *ctx = data;
75 
76   gst_clock_id_wait (ctx->clock_id, &ctx->jitter);
77 
78   return NULL;
79 }
80 
81 static gpointer
test_wait_pending_single_shot_id_async_worker(gpointer data)82 test_wait_pending_single_shot_id_async_worker (gpointer data)
83 {
84   GstClockID clock_id = data;
85 
86   g_usleep (G_USEC_PER_SEC / 10);
87   gst_clock_id_wait_async (clock_id, test_async_wait_cb, NULL, NULL);
88 
89   return NULL;
90 }
91 
92 static gpointer
test_wait_pending_periodic_id_waiter_thread(gpointer data)93 test_wait_pending_periodic_id_waiter_thread (gpointer data)
94 {
95   GstClockID clock_id = data;
96   gst_clock_id_wait (clock_id, NULL);
97   return NULL;
98 }
99 
100 static gboolean
test_async_wait_cb(GstClock * clock,GstClockTime time,GstClockID id,gpointer user_data)101 test_async_wait_cb (GstClock * clock,
102     GstClockTime time, GstClockID id, gpointer user_data)
103 {
104 
105   gboolean *wait_complete = user_data;
106 
107   if (wait_complete != NULL)
108     *wait_complete = TRUE;
109 
110   return TRUE;
111 }
112 
113 static GtuClockWaitContext *
gst_test_util_wait_for_clock_id_begin(GstTestClock * test_clock,GstClockID id,GstClockTimeDiff * jitter)114 gst_test_util_wait_for_clock_id_begin (GstTestClock * test_clock, GstClockID id,
115     GstClockTimeDiff * jitter)
116 {
117   GtuClockWaitContext *wait_ctx;
118 
119   wait_ctx = g_slice_new (GtuClockWaitContext);
120   wait_ctx->test_clock = gst_object_ref (test_clock);
121   wait_ctx->reference = gst_clock_get_time (GST_CLOCK (wait_ctx->test_clock));
122   wait_ctx->id = gst_clock_id_ref (id);
123 
124   if (jitter) {
125     GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
126     GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
127     GstClockTime reference = wait_ctx->reference;
128 
129     *jitter = GST_CLOCK_DIFF (requested, reference);
130   }
131 
132   if (!gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id)) {
133     GstClockClass *klass = GST_CLOCK_GET_CLASS (wait_ctx->test_clock);
134     GstClock *clock = GST_CLOCK (wait_ctx->test_clock);
135     g_assert (klass->wait_async (clock, wait_ctx->id) == GST_CLOCK_OK);
136   }
137 
138   g_assert (gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
139   g_assert_cmpint (gst_test_clock_peek_id_count (wait_ctx->test_clock), >, 0);
140 
141   return wait_ctx;
142 }
143 
144 static GstClockReturn
gst_test_util_wait_for_clock_id_end(GtuClockWaitContext * wait_ctx)145 gst_test_util_wait_for_clock_id_end (GtuClockWaitContext * wait_ctx)
146 {
147   GstClockReturn status = GST_CLOCK_ERROR;
148   GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
149 
150   if (G_UNLIKELY (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED)) {
151     status = GST_CLOCK_UNSCHEDULED;
152   } else {
153     GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
154     GstClockTimeDiff diff;
155 
156     g_assert (gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
157 
158     diff = GST_CLOCK_DIFF (requested, wait_ctx->reference);
159 
160     if (diff > 0) {
161       status = GST_CLOCK_EARLY;
162     } else {
163       status = GST_CLOCK_OK;
164     }
165 
166     g_atomic_int_set (&GST_CLOCK_ENTRY_STATUS (entry), status);
167   }
168 
169   if (GST_CLOCK_ENTRY_TYPE (entry) == GST_CLOCK_ENTRY_SINGLE) {
170     GstClockClass *klass = GST_CLOCK_GET_CLASS (wait_ctx->test_clock);
171     GstClock *clock = GST_CLOCK (wait_ctx->test_clock);
172 
173     klass->unschedule (clock, wait_ctx->id);
174     g_assert (!gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
175   } else {
176     GST_CLOCK_ENTRY_TIME (entry) += GST_CLOCK_ENTRY_INTERVAL (entry);
177     g_assert (gst_test_clock_has_id (wait_ctx->test_clock, wait_ctx->id));
178   }
179 
180   gst_clock_id_unref (wait_ctx->id);
181   gst_object_unref (wait_ctx->test_clock);
182   g_slice_free (GtuClockWaitContext, wait_ctx);
183 
184   return status;
185 }
186 
187 static gboolean
gst_test_util_clock_wait_context_has_completed(GtuClockWaitContext * wait_ctx)188 gst_test_util_clock_wait_context_has_completed (GtuClockWaitContext * wait_ctx)
189 {
190   GstClock *clock = GST_CLOCK (wait_ctx->test_clock);
191   GstClockEntry *entry = GST_CLOCK_ENTRY (wait_ctx->id);
192   GstClockTime requested = GST_CLOCK_ENTRY_TIME (entry);
193   GstClockTime now = gst_clock_get_time (clock);
194 
195   return requested < now;
196 }
197 
GST_START_TEST(test_object_flags)198 GST_START_TEST (test_object_flags)
199 {
200   GstClock *clock = gst_test_clock_new ();
201   g_assert (GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC));
202   g_assert (GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_DO_SINGLE_ASYNC));
203   g_assert (GST_OBJECT_FLAG_IS_SET (clock,
204           GST_CLOCK_FLAG_CAN_DO_PERIODIC_SYNC));
205   g_assert (GST_OBJECT_FLAG_IS_SET (clock,
206           GST_CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC));
207   gst_object_unref (clock);
208 }
209 
210 GST_END_TEST;
211 
GST_START_TEST(test_resolution_query)212 GST_START_TEST (test_resolution_query)
213 {
214   GstClock *clock = gst_test_clock_new ();
215   g_assert_cmpuint (gst_clock_get_resolution (clock), ==, 1);
216   gst_object_unref (clock);
217 }
218 
219 GST_END_TEST;
220 
GST_START_TEST(test_start_time)221 GST_START_TEST (test_start_time)
222 {
223   GstClock *clock;
224   guint64 start_time;
225 
226   clock = gst_test_clock_new ();
227   g_assert_cmpuint (gst_clock_get_time (clock), ==, 0);
228   g_object_get (clock, "start-time", &start_time, NULL);
229   g_assert_cmpuint (start_time, ==, 0);
230   gst_object_unref (clock);
231 
232   clock = gst_test_clock_new_with_start_time (GST_SECOND);
233   g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND);
234   g_object_get (clock, "start-time", &start_time, NULL);
235   g_assert_cmpuint (start_time, ==, GST_SECOND);
236   gst_object_unref (clock);
237 }
238 
239 GST_END_TEST;
240 
GST_START_TEST(test_set_time)241 GST_START_TEST (test_set_time)
242 {
243   GstClock *clock = gst_test_clock_new_with_start_time (GST_SECOND);
244   gst_test_clock_set_time (GST_TEST_CLOCK (clock), GST_SECOND);
245   g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND);
246   gst_test_clock_set_time (GST_TEST_CLOCK (clock), GST_SECOND + 1);
247   g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND + 1);
248   gst_object_unref (clock);
249 }
250 
251 GST_END_TEST;
252 
GST_START_TEST(test_advance_time)253 GST_START_TEST (test_advance_time)
254 {
255   GstClock *clock = gst_test_clock_new_with_start_time (GST_SECOND);
256   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 0);
257   g_assert_cmpuint (gst_clock_get_time (clock), ==, GST_SECOND);
258   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 42 * GST_MSECOND);
259   g_assert_cmpuint (gst_clock_get_time (clock), ==,
260       GST_SECOND + (42 * GST_MSECOND));
261   gst_object_unref (clock);
262 }
263 
264 GST_END_TEST;
265 
GST_START_TEST(test_wait_synchronous_no_timeout)266 GST_START_TEST (test_wait_synchronous_no_timeout)
267 {
268   GstClock *clock;
269   GstTestClock *test_clock;
270   GstClockID clock_id;
271   GThread *worker_thread;
272   GstClockID pending_id;
273   GstClockID processed_id;
274   SyncClockWaitContext context;
275 
276   clock = gst_test_clock_new_with_start_time (GST_SECOND);
277   test_clock = GST_TEST_CLOCK (clock);
278 
279   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
280   context.clock_id = gst_clock_id_ref (clock_id);
281   context.jitter = 0;
282   worker_thread =
283       g_thread_new ("worker_thread",
284       test_wait_pending_single_shot_id_sync_worker, &context);
285   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
286   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
287       GST_SECOND - 1);
288   gst_clock_id_unref (pending_id);
289   processed_id = gst_test_clock_process_next_clock_id (test_clock);
290   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
291       GST_CLOCK_EARLY);
292   gst_clock_id_unref (processed_id);
293   g_thread_join (worker_thread);
294   g_assert_cmpuint (context.jitter, ==, 1);
295   gst_clock_id_unref (context.clock_id);
296   gst_clock_id_unref (clock_id);
297 
298   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
299   context.clock_id = gst_clock_id_ref (clock_id);
300   context.jitter = 0;
301   worker_thread =
302       g_thread_new ("worker_thread",
303       test_wait_pending_single_shot_id_sync_worker, &context);
304   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
305   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE, GST_SECOND);
306   gst_clock_id_unref (pending_id);
307   processed_id = gst_test_clock_process_next_clock_id (test_clock);
308   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
309       GST_CLOCK_OK);
310   gst_clock_id_unref (processed_id);
311   g_thread_join (worker_thread);
312   g_assert_cmpuint (context.jitter, ==, 0);
313   gst_clock_id_unref (context.clock_id);
314   gst_clock_id_unref (clock_id);
315 
316   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND + 1);
317   context.clock_id = gst_clock_id_ref (clock_id);
318   context.jitter = 0;
319   worker_thread =
320       g_thread_new ("worker_thread",
321       test_wait_pending_single_shot_id_sync_worker, &context);
322   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
323   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
324       GST_SECOND + 1);
325   gst_clock_id_unref (pending_id);
326   processed_id = gst_test_clock_process_next_clock_id (test_clock);
327   g_assert (processed_id == NULL);
328   gst_test_clock_advance_time (test_clock, 1);
329   processed_id = gst_test_clock_process_next_clock_id (test_clock);
330   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
331       GST_CLOCK_OK);
332   gst_clock_id_unref (processed_id);
333   g_thread_join (worker_thread);
334   g_assert_cmpuint (context.jitter, ==, -1);
335   gst_clock_id_unref (context.clock_id);
336   gst_clock_id_unref (clock_id);
337 
338   gst_object_unref (clock);
339 }
340 
341 GST_END_TEST;
342 
GST_START_TEST(test_wait_pending_single_shot_id)343 GST_START_TEST (test_wait_pending_single_shot_id)
344 {
345   GstClock *clock;
346   GstTestClock *test_clock;
347   GstClockID clock_id;
348   GstClockID processed_id;
349   GThread *worker_thread;
350   GstClockID pending_id;
351 
352   clock = gst_test_clock_new_with_start_time (GST_SECOND);
353   test_clock = GST_TEST_CLOCK (clock);
354 
355   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
356   gst_clock_id_wait_async (clock_id, test_async_wait_cb, NULL, 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, GST_SECOND);
359   gst_clock_id_unref (pending_id);
360   processed_id = gst_test_clock_process_next_clock_id (test_clock);
361   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
362       GST_CLOCK_OK);
363   gst_clock_id_unref (processed_id);
364   gst_clock_id_unref (clock_id);
365 
366   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
367   worker_thread =
368       g_thread_new ("worker_thread",
369       test_wait_pending_single_shot_id_async_worker, clock_id);
370   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
371   assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
372       2 * GST_SECOND);
373   gst_clock_id_unref (pending_id);
374   g_thread_join (worker_thread);
375   gst_clock_id_unref (clock_id);
376 
377   clock_id = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
378   worker_thread =
379       g_thread_new ("worker_thread",
380       test_wait_pending_single_shot_id_async_worker, clock_id);
381   gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
382   g_thread_join (worker_thread);
383   gst_clock_id_unref (clock_id);
384 
385   gst_object_unref (clock);
386 }
387 
388 GST_END_TEST;
389 
GST_START_TEST(test_wait_pending_periodic_id)390 GST_START_TEST (test_wait_pending_periodic_id)
391 {
392   GstClock *clock;
393   GstTestClock *test_clock;
394   GstClockID clock_id;
395   GstClockID processed_id;
396 
397   clock = gst_test_clock_new_with_start_time (GST_SECOND);
398   test_clock = GST_TEST_CLOCK (clock);
399   clock_id = gst_clock_new_periodic_id (clock, GST_SECOND, GST_MSECOND);
400 
401   {
402     GThread *waiter_thread;
403 
404     waiter_thread =
405         g_thread_new ("waiter_thread",
406         test_wait_pending_periodic_id_waiter_thread, clock_id);
407 
408     gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
409     gst_test_clock_set_time (test_clock, GST_SECOND);
410     processed_id = gst_test_clock_process_next_clock_id (test_clock);
411     assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
412         GST_CLOCK_OK);
413     gst_clock_id_unref (processed_id);
414 
415     g_thread_join (waiter_thread);
416   }
417 
418   {
419     guint i;
420     GThread *waiter_thread;
421 
422     for (i = 0; i < 3; i++) {
423       g_assert (!gst_test_clock_peek_next_pending_id (test_clock, NULL));
424       g_usleep (G_USEC_PER_SEC / 10 / 10);
425     }
426 
427     waiter_thread =
428         g_thread_new ("waiter_thread",
429         test_wait_pending_periodic_id_waiter_thread, clock_id);
430 
431     gst_test_clock_wait_for_next_pending_id (test_clock, NULL);
432     gst_clock_id_unschedule (clock_id);
433 
434     g_thread_join (waiter_thread);
435   }
436 
437   gst_clock_id_unref (clock_id);
438   gst_object_unref (clock);
439 }
440 
441 GST_END_TEST;
442 
GST_START_TEST(test_single_shot_sync_past)443 GST_START_TEST (test_single_shot_sync_past)
444 {
445   GstClock *clock;
446   GstTestClock *test_clock;
447   GstClockID clock_id;
448   GstClockTimeDiff jitter;
449   GtuClockWaitContext *wait_ctx;
450 
451   clock = gst_test_clock_new_with_start_time (GST_SECOND);
452   test_clock = GST_TEST_CLOCK (clock);
453 
454   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
455   wait_ctx =
456       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
457   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_EARLY);
458   g_assert_cmpint (jitter, ==, 1);
459   gst_clock_id_unref (clock_id);
460 
461   gst_object_unref (clock);
462 }
463 
464 GST_END_TEST;
465 
GST_START_TEST(test_single_shot_sync_present)466 GST_START_TEST (test_single_shot_sync_present)
467 {
468   GstClock *clock;
469   GstTestClock *test_clock;
470   GstClockID clock_id;
471   GstClockTimeDiff jitter;
472   GtuClockWaitContext *wait_ctx;
473 
474   clock = gst_test_clock_new_with_start_time (GST_SECOND);
475   test_clock = GST_TEST_CLOCK (clock);
476 
477   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
478   wait_ctx =
479       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
480   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_OK);
481   g_assert_cmpint (jitter, ==, 0);
482   gst_clock_id_unref (clock_id);
483 
484   gst_object_unref (clock);
485 }
486 
487 GST_END_TEST;
488 
GST_START_TEST(test_single_shot_sync_future)489 GST_START_TEST (test_single_shot_sync_future)
490 {
491   GstClock *clock;
492   GstTestClock *test_clock;
493   GstClockID clock_id;
494   GstClockTimeDiff jitter;
495   GtuClockWaitContext *wait_ctx;
496 
497   clock = gst_test_clock_new_with_start_time (GST_SECOND);
498   test_clock = GST_TEST_CLOCK (clock);
499 
500   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
501   wait_ctx =
502       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, &jitter);
503   gst_test_clock_advance_time (test_clock, GST_SECOND);
504   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx) == GST_CLOCK_OK);
505   g_assert_cmpint (jitter, ==, -GST_SECOND);
506   gst_clock_id_unref (clock_id);
507 
508   gst_object_unref (clock);
509 }
510 
511 GST_END_TEST;
512 
GST_START_TEST(test_single_shot_sync_unschedule)513 GST_START_TEST (test_single_shot_sync_unschedule)
514 {
515   GstClock *clock;
516   GstTestClock *test_clock;
517   GstClockID clock_id;
518   GtuClockWaitContext *wait_ctx;
519   gboolean wait_complete = FALSE;
520 
521   clock = gst_test_clock_new_with_start_time (GST_SECOND);
522   test_clock = GST_TEST_CLOCK (clock);
523 
524   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
525   gst_clock_id_unschedule (clock_id);
526   /* any wait should timeout immediately */
527   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
528           &wait_complete, NULL) == GST_CLOCK_UNSCHEDULED);
529   g_assert (gst_clock_id_wait (clock_id, NULL) == GST_CLOCK_UNSCHEDULED);
530   gst_clock_id_unref (clock_id);
531 
532   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
533   wait_ctx = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
534   gst_clock_id_unschedule (clock_id);
535   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx)
536       == GST_CLOCK_UNSCHEDULED);
537   gst_clock_id_unref (clock_id);
538 
539   gst_object_unref (clock);
540 }
541 
542 GST_END_TEST;
543 
GST_START_TEST(test_single_shot_sync_ordering)544 GST_START_TEST (test_single_shot_sync_ordering)
545 {
546   GstClock *clock;
547   GstTestClock *test_clock;
548   GstClockID clock_id_a, clock_id_b;
549   GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
550 
551   clock = gst_test_clock_new_with_start_time (GST_SECOND);
552   test_clock = GST_TEST_CLOCK (clock);
553 
554   clock_id_a = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
555   wait_ctx_a =
556       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_a, NULL);
557 
558   gst_test_clock_advance_time (test_clock, GST_SECOND);
559 
560   clock_id_b = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
561   wait_ctx_b =
562       gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b, NULL);
563 
564   gst_test_clock_advance_time (test_clock, GST_SECOND);
565 
566   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_b) == GST_CLOCK_OK);
567   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_a) == GST_CLOCK_OK);
568 
569   gst_clock_id_unref (clock_id_b);
570   gst_clock_id_unref (clock_id_a);
571 
572   gst_object_unref (clock);
573 }
574 
575 GST_END_TEST;
576 
GST_START_TEST(test_single_shot_sync_ordering_parallel)577 GST_START_TEST (test_single_shot_sync_ordering_parallel)
578 {
579   GstClock *clock;
580   GstTestClock *test_clock;
581   GstClockID clock_id_a, clock_id_b;
582   GtuClockWaitContext *wait_ctx_a, *wait_ctx_b;
583 
584   clock = gst_test_clock_new_with_start_time (GST_SECOND);
585   test_clock = GST_TEST_CLOCK (clock);
586 
587   clock_id_a = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
588   clock_id_b = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
589   wait_ctx_a = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_a,
590       NULL);
591   wait_ctx_b = gst_test_util_wait_for_clock_id_begin (test_clock, clock_id_b,
592       NULL);
593 
594   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
595       2 * GST_SECOND);
596   gst_test_clock_advance_time (test_clock, GST_SECOND);
597   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_b) == GST_CLOCK_OK);
598 
599   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
600       3 * GST_SECOND);
601   gst_test_clock_advance_time (test_clock, GST_SECOND);
602   g_assert (gst_test_util_wait_for_clock_id_end (wait_ctx_a) == GST_CLOCK_OK);
603 
604   gst_clock_id_unref (clock_id_b);
605   gst_clock_id_unref (clock_id_a);
606 
607   gst_object_unref (clock);
608 }
609 
610 GST_END_TEST;
611 
GST_START_TEST(test_single_shot_sync_simultaneous_no_timeout)612 GST_START_TEST (test_single_shot_sync_simultaneous_no_timeout)
613 {
614   GstClock *clock;
615   GstTestClock *test_clock;
616   GstClockID clock_id_a;
617   GstClockID clock_id_b;
618   SyncClockWaitContext context_a;
619   SyncClockWaitContext context_b;
620   GThread *worker_thread_a;
621   GThread *worker_thread_b;
622   GstClockID processed_id;
623   GstClockID pending_id;
624 
625   clock = gst_test_clock_new_with_start_time (GST_SECOND);
626   test_clock = GST_TEST_CLOCK (clock);
627 
628   clock_id_a = gst_clock_new_single_shot_id (clock, 5 * GST_SECOND);
629   clock_id_b = gst_clock_new_single_shot_id (clock, 6 * GST_SECOND);
630 
631   context_a.clock_id = gst_clock_id_ref (clock_id_a);
632   context_a.jitter = 0;
633   context_b.clock_id = gst_clock_id_ref (clock_id_b);
634   context_b.jitter = 0;
635 
636   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 0, NULL);
637 
638   worker_thread_b =
639       g_thread_new ("worker_thread_b",
640       test_wait_pending_single_shot_id_sync_worker, &context_b);
641 
642   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 1, NULL);
643   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
644   assert_pending_id (pending_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE,
645       6 * GST_SECOND);
646   gst_clock_id_unref (pending_id);
647 
648   worker_thread_a =
649       g_thread_new ("worker_thread_a",
650       test_wait_pending_single_shot_id_sync_worker, &context_a);
651 
652   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 2, NULL);
653   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
654   assert_pending_id (pending_id, clock_id_a, GST_CLOCK_ENTRY_SINGLE,
655       5 * GST_SECOND);
656   gst_clock_id_unref (pending_id);
657 
658   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
659       5 * GST_SECOND);
660   gst_test_clock_advance_time (test_clock, 5 * GST_SECOND);
661   processed_id = gst_test_clock_process_next_clock_id (test_clock);
662   assert_processed_id (processed_id, clock_id_a, GST_CLOCK_ENTRY_SINGLE,
663       GST_CLOCK_OK);
664   gst_clock_id_unref (processed_id);
665 
666   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 1, NULL);
667   gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
668   assert_pending_id (pending_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE,
669       6 * GST_SECOND);
670   gst_clock_id_unref (pending_id);
671 
672   g_assert_cmpuint (gst_test_clock_get_next_entry_time (test_clock), ==,
673       6 * GST_SECOND);
674   gst_test_clock_advance_time (test_clock, 6 * GST_SECOND);
675   processed_id = gst_test_clock_process_next_clock_id (test_clock);
676   assert_processed_id (processed_id, clock_id_b, GST_CLOCK_ENTRY_SINGLE,
677       GST_CLOCK_OK);
678   gst_clock_id_unref (processed_id);
679 
680   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 0, NULL);
681 
682   g_thread_join (worker_thread_a);
683   g_thread_join (worker_thread_b);
684 
685   g_assert_cmpuint (context_a.jitter, ==, -4 * GST_SECOND);
686   g_assert_cmpuint (context_b.jitter, ==, -5 * GST_SECOND);
687 
688   gst_clock_id_unref (context_a.clock_id);
689   gst_clock_id_unref (context_b.clock_id);
690 
691   gst_clock_id_unref (clock_id_a);
692   gst_clock_id_unref (clock_id_b);
693 
694   gst_object_unref (clock);
695 }
696 
697 GST_END_TEST;
698 
GST_START_TEST(test_processing_multiple_ids)699 GST_START_TEST (test_processing_multiple_ids)
700 {
701   GstClock *clock;
702   GstTestClock *test_clock;
703   GstClockID clock_id_a;
704   GstClockID clock_id_b;
705   SyncClockWaitContext context_a;
706   SyncClockWaitContext context_b;
707   GThread *worker_thread_a;
708   GThread *worker_thread_b;
709   GList *pending_list = NULL;
710 
711   clock = gst_test_clock_new_with_start_time (GST_SECOND);
712   test_clock = GST_TEST_CLOCK (clock);
713 
714   /* register a wait for 5 seconds */
715   clock_id_a = gst_clock_new_single_shot_id (clock, 5 * GST_SECOND);
716   context_a.clock_id = gst_clock_id_ref (clock_id_a);
717   context_a.jitter = 0;
718   worker_thread_a =
719       g_thread_new ("worker_thread_a",
720       test_wait_pending_single_shot_id_sync_worker, &context_a);
721 
722   /* register another wait for 6 seconds */
723   clock_id_b = gst_clock_new_single_shot_id (clock, 6 * GST_SECOND);
724   context_b.clock_id = gst_clock_id_ref (clock_id_b);
725   context_b.jitter = 0;
726   worker_thread_b =
727       g_thread_new ("worker_thread_b",
728       test_wait_pending_single_shot_id_sync_worker, &context_b);
729 
730   /* wait for two waits */
731   gst_test_clock_wait_for_multiple_pending_ids (test_clock, 2, &pending_list);
732 
733   /* assert they are correct */
734   assert_pending_id (pending_list->data, clock_id_a, GST_CLOCK_ENTRY_SINGLE,
735       5 * GST_SECOND);
736   assert_pending_id (pending_list->next->data, clock_id_b,
737       GST_CLOCK_ENTRY_SINGLE, 6 * GST_SECOND);
738 
739   /* verify we are waiting for 6 seconds as the latest time */
740   fail_unless_equals_int64 (6 * GST_SECOND,
741       gst_test_clock_id_list_get_latest_time (pending_list));
742 
743   /* process both ID's at the same time */
744   gst_test_clock_process_id_list (test_clock, pending_list);
745   g_list_free_full (pending_list, (GDestroyNotify) gst_clock_id_unref);
746 
747   g_thread_join (worker_thread_a);
748   g_thread_join (worker_thread_b);
749 
750   fail_unless_equals_int64 (-4 * GST_SECOND, context_a.jitter);
751   fail_unless_equals_int64 (-5 * GST_SECOND, context_b.jitter);
752 
753   gst_clock_id_unref (context_a.clock_id);
754   gst_clock_id_unref (context_b.clock_id);
755 
756   gst_clock_id_unref (clock_id_a);
757   gst_clock_id_unref (clock_id_b);
758 
759   gst_object_unref (clock);
760 }
761 
762 GST_END_TEST;
763 
GST_START_TEST(test_single_shot_async_past)764 GST_START_TEST (test_single_shot_async_past)
765 {
766   GstClock *clock;
767   GstClockID clock_id;
768   GstClockID processed_id;
769   gboolean wait_complete = FALSE;
770 
771   clock = gst_test_clock_new_with_start_time (GST_SECOND);
772   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND - 1);
773   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
774           &wait_complete, NULL) == GST_CLOCK_OK);
775   g_assert (!wait_complete);
776   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
777   g_assert (wait_complete);
778   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
779       GST_CLOCK_EARLY);
780   gst_clock_id_unref (processed_id);
781   gst_clock_id_unref (clock_id);
782   gst_object_unref (clock);
783 }
784 
785 GST_END_TEST;
786 
GST_START_TEST(test_single_shot_async_present)787 GST_START_TEST (test_single_shot_async_present)
788 {
789   GstClock *clock;
790   GstClockID clock_id;
791   GstClockID processed_id;
792   gboolean wait_complete = FALSE;
793 
794   clock = gst_test_clock_new_with_start_time (GST_SECOND);
795   clock_id = gst_clock_new_single_shot_id (clock, GST_SECOND);
796   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
797           &wait_complete, NULL) == GST_CLOCK_OK);
798   g_assert (!wait_complete);
799   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
800   g_assert (wait_complete);
801   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
802       GST_CLOCK_OK);
803   gst_clock_id_unref (processed_id);
804   gst_clock_id_unref (clock_id);
805   gst_object_unref (clock);
806 }
807 
808 GST_END_TEST;
809 
GST_START_TEST(test_single_shot_async_future)810 GST_START_TEST (test_single_shot_async_future)
811 {
812   GstClock *clock;
813   GstClockID clock_id;
814   GstClockID processed_id;
815   gboolean wait_complete = FALSE;
816 
817   clock = gst_test_clock_new_with_start_time (GST_SECOND);
818   clock_id = gst_clock_new_single_shot_id (clock, 2 * GST_SECOND);
819   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
820           &wait_complete, NULL) == GST_CLOCK_OK);
821   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
822   g_assert (processed_id == NULL);
823   g_assert (!wait_complete);
824   g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
825       == GST_CLOCK_OK);
826 
827   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), GST_SECOND - 1);
828   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
829   g_assert (processed_id == NULL);
830   g_assert (!wait_complete);
831   g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
832       == GST_CLOCK_OK);
833 
834   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
835   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
836   g_assert (wait_complete);
837   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_SINGLE,
838       GST_CLOCK_OK);
839   gst_clock_id_unref (processed_id);
840   g_assert (GST_CLOCK_ENTRY_STATUS (GST_CLOCK_ENTRY (clock_id))
841       == GST_CLOCK_OK);
842 
843   gst_clock_id_unref (clock_id);
844   gst_object_unref (clock);
845 }
846 
847 GST_END_TEST;
848 
GST_START_TEST(test_single_shot_async_unschedule)849 GST_START_TEST (test_single_shot_async_unschedule)
850 {
851   GstClock *clock;
852   GstClockID clock_id;
853   gboolean wait_complete = FALSE;
854 
855   clock = gst_test_clock_new_with_start_time (GST_SECOND);
856 
857   clock_id = gst_clock_new_single_shot_id (clock, 3 * GST_SECOND);
858   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
859           &wait_complete, NULL) == GST_CLOCK_OK);
860 
861   gst_clock_id_unschedule (clock_id);
862 
863   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 2 * GST_SECOND);
864   g_assert (gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock))
865       == NULL);
866   g_assert (!wait_complete);
867 
868   gst_clock_id_unref (clock_id);
869   gst_object_unref (clock);
870 }
871 
872 GST_END_TEST;
873 
GST_START_TEST(test_periodic_sync)874 GST_START_TEST (test_periodic_sync)
875 {
876   GstClock *clock;
877   GstTestClock *test_clock;
878   GstClockID clock_id;
879   guint i;
880   const GstClockTime interval = 4 * GST_MSECOND;
881 
882   clock = gst_test_clock_new ();
883   test_clock = GST_TEST_CLOCK (clock);
884 
885   clock_id = gst_clock_new_periodic_id (clock, GST_SECOND, interval);
886 
887   for (i = 0; i < 3; i++) {
888     GtuClockWaitContext *wait_ctx;
889     GstClockID pending_id;
890     guint j;
891 
892     wait_ctx =
893         gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
894 
895     gst_test_clock_wait_for_next_pending_id (test_clock, &pending_id);
896     assert_pending_id (pending_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
897         GST_SECOND + (i * interval));
898     gst_clock_id_unref (pending_id);
899 
900     for (j = 0; j < 10; j++) {
901       g_usleep (G_USEC_PER_SEC / 10 / 10);
902       g_assert (!gst_test_util_clock_wait_context_has_completed (wait_ctx));
903     }
904 
905     if (i == 0)
906       gst_test_clock_advance_time (test_clock, GST_SECOND);
907     else
908       gst_test_clock_advance_time (test_clock, interval);
909 
910     gst_test_util_wait_for_clock_id_end (wait_ctx);
911   }
912 
913   gst_clock_id_unref (clock_id);
914   gst_object_unref (clock);
915 }
916 
917 GST_END_TEST;
918 
GST_START_TEST(test_periodic_async)919 GST_START_TEST (test_periodic_async)
920 {
921   GstClock *clock;
922   GstClockID clock_id;
923   GstClockID processed_id;
924   gboolean wait_complete = FALSE;
925   const GstClockTime interval = 4 * GST_MSECOND;
926 
927   clock = gst_test_clock_new ();
928   clock_id = gst_clock_new_periodic_id (clock, gst_clock_get_time (clock),
929       interval);
930   g_assert (gst_clock_id_wait_async (clock_id, test_async_wait_cb,
931           &wait_complete, NULL) == GST_CLOCK_OK);
932 
933   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
934   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
935       GST_CLOCK_OK);
936   gst_clock_id_unref (processed_id);
937 
938   g_assert (wait_complete);
939   wait_complete = FALSE;
940 
941   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), interval - 1);
942   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
943   g_assert (processed_id == NULL);
944   g_assert (!wait_complete);
945 
946   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
947   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
948   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
949       GST_CLOCK_OK);
950   gst_clock_id_unref (processed_id);
951   g_assert (wait_complete);
952   wait_complete = FALSE;
953 
954   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), interval - 1);
955   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
956   g_assert (processed_id == NULL);
957   g_assert (!wait_complete);
958 
959   gst_test_clock_advance_time (GST_TEST_CLOCK (clock), 1);
960   processed_id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (clock));
961   assert_processed_id (processed_id, clock_id, GST_CLOCK_ENTRY_PERIODIC,
962       GST_CLOCK_OK);
963   gst_clock_id_unref (processed_id);
964   g_assert (wait_complete);
965   wait_complete = FALSE;
966 
967   gst_clock_id_unref (clock_id);
968   gst_object_unref (clock);
969 }
970 
971 GST_END_TEST;
972 
GST_START_TEST(test_periodic_uniqueness)973 GST_START_TEST (test_periodic_uniqueness)
974 {
975   GstClock *clock;
976   GstTestClock *test_clock;
977   GstClockID clock_id;
978   guint i;
979   const GstClockTime interval = 4 * GST_MSECOND;
980 
981   clock = gst_test_clock_new ();
982   test_clock = GST_TEST_CLOCK (clock);
983 
984   clock_id = gst_clock_new_periodic_id (clock, 0, interval);
985 
986   for (i = 0; i < 3; i++) {
987     GtuClockWaitContext *wait_ctx;
988     guint j;
989 
990     wait_ctx =
991         gst_test_util_wait_for_clock_id_begin (test_clock, clock_id, NULL);
992 
993     for (j = 0; j < 10; j++) {
994       g_usleep (G_USEC_PER_SEC / 10 / 10);
995       g_assert_cmpuint (gst_test_clock_peek_id_count (test_clock), ==, 1);
996     }
997 
998     gst_test_clock_advance_time (test_clock, interval);
999     gst_test_util_wait_for_clock_id_end (wait_ctx);
1000   }
1001 
1002   gst_clock_id_unref (clock_id);
1003   gst_object_unref (clock);
1004 }
1005 
1006 GST_END_TEST;
1007 
GST_START_TEST(test_crank)1008 GST_START_TEST (test_crank)
1009 {
1010   GstClock *clock;
1011   GstTestClock *test_clock;
1012   GstClockID clock_id;
1013   SyncClockWaitContext context;
1014   GThread *worker_thread;
1015 
1016   clock = gst_test_clock_new_with_start_time (GST_SECOND);
1017   test_clock = GST_TEST_CLOCK (clock);
1018 
1019   /* register a wait for 5 seconds */
1020   clock_id = gst_clock_new_single_shot_id (clock, 5 * GST_SECOND);
1021   context.clock_id = gst_clock_id_ref (clock_id);
1022   context.jitter = 0;
1023   worker_thread =
1024       g_thread_new ("worker_thread_a",
1025       test_wait_pending_single_shot_id_sync_worker, &context);
1026 
1027   /* crank */
1028   gst_test_clock_crank (test_clock);
1029 
1030   /* the clock should have advanced and the wait released */
1031   g_thread_join (worker_thread);
1032 
1033   /* 4 seconds was spent waiting for the clock */
1034   fail_unless_equals_int64 (-4 * GST_SECOND, context.jitter);
1035 
1036   /* and the clock is now at 5 seconds */
1037   fail_unless_equals_int64 (5 * GST_SECOND, gst_clock_get_time (clock));
1038 
1039   gst_clock_id_unref (context.clock_id);
1040   gst_clock_id_unref (clock_id);
1041   gst_object_unref (clock);
1042 }
1043 
1044 GST_END_TEST;
1045 
1046 static Suite *
gst_test_clock_suite(void)1047 gst_test_clock_suite (void)
1048 {
1049   Suite *s = suite_create ("GstTestClock");
1050   TCase *tc_chain = tcase_create ("testclock");
1051 
1052   suite_add_tcase (s, tc_chain);
1053 
1054   tcase_add_test (tc_chain, test_object_flags);
1055   tcase_add_test (tc_chain, test_resolution_query);
1056   tcase_add_test (tc_chain, test_start_time);
1057   tcase_add_test (tc_chain, test_set_time);
1058   tcase_add_test (tc_chain, test_advance_time);
1059   tcase_add_test (tc_chain, test_wait_synchronous_no_timeout);
1060   tcase_add_test (tc_chain, test_wait_pending_single_shot_id);
1061   tcase_add_test (tc_chain, test_wait_pending_periodic_id);
1062   tcase_add_test (tc_chain, test_single_shot_sync_simultaneous_no_timeout);
1063   tcase_add_test (tc_chain, test_processing_multiple_ids);
1064   tcase_add_test (tc_chain, test_single_shot_sync_past);
1065   tcase_add_test (tc_chain, test_single_shot_sync_present);
1066   tcase_add_test (tc_chain, test_single_shot_sync_future);
1067   tcase_add_test (tc_chain, test_single_shot_sync_unschedule);
1068   tcase_add_test (tc_chain, test_single_shot_sync_ordering);
1069   tcase_add_test (tc_chain, test_single_shot_sync_ordering_parallel);
1070   tcase_add_test (tc_chain, test_single_shot_async_past);
1071   tcase_add_test (tc_chain, test_single_shot_async_present);
1072   tcase_add_test (tc_chain, test_single_shot_async_future);
1073   tcase_add_test (tc_chain, test_single_shot_async_unschedule);
1074   tcase_add_test (tc_chain, test_periodic_sync);
1075   tcase_add_test (tc_chain, test_periodic_async);
1076   tcase_add_test (tc_chain, test_periodic_uniqueness);
1077   tcase_add_test (tc_chain, test_crank);
1078 
1079   return s;
1080 }
1081 
1082 GST_CHECK_MAIN (gst_test_clock);
1083