gstclock.c 15.7 KB
Newer Older
1 2 3 4 5
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * gstclock.c: Clock subsystem for maintaining time sync
Wim Taymans's avatar
Wim Taymans committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <sys/time.h>
24

25
/* #define GST_DEBUG_ENABLED */
26 27
#include "gst_private.h"

28
#include "gstclock.h"
29 30
#include "gstlog.h"
#include "gstmemchunk.h"
Wim Taymans's avatar
Wim Taymans committed
31

32 33 34 35 36
enum {
  ARG_0,
  ARG_STATS,
};

37
static GstMemChunk *_gst_clock_entries_chunk;
Wim Taymans's avatar
Wim Taymans committed
38

39 40
static void		gst_clock_class_init		(GstClockClass *klass);
static void		gst_clock_init			(GstClock *clock);
41 42 43 44 45
static void             gst_clock_set_property		(GObject *object, guint prop_id, 
							 const GValue *value, GParamSpec *pspec);
static void             gst_clock_get_property		(GObject *object, guint prop_id, 
							 GValue *value, GParamSpec * pspec);
static void		gst_clock_update_stats		(GstClock *clock);
46

47

48 49 50
static GstObjectClass *parent_class = NULL;
/* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */

51 52
static GMutex *_gst_clock_mutex;
static GCond  *_gst_clock_cond;
53

54 55 56 57 58
static inline GstClockID
gst_clock_entry_new (GstClock *clock, GstClockTime time, 
		     GstClockTime interval, GstClockEntryType type)
{
  GstClockEntry *entry;
59

60
  entry = gst_mem_chunk_alloc (_gst_clock_entries_chunk);
61

62 63 64 65 66
  entry->clock = clock;
  entry->time = time;
  entry->interval = time;
  entry->type = type;
  entry->status = GST_CLOCK_ENTRY_OK;
67

68 69
  return (GstClockID) entry;
}
70

71 72 73 74 75 76 77 78 79 80 81 82 83
/**
 * gst_clock_new_single_shot_id
 * @clock: The clockid to get a single shot notification from
 * @time: the requested time
 *
 * Get an ID from the given clock to trigger a single shot 
 * notification at the requested time.
 *
 * Returns: An id that can be used to request the time notification.
 */
GstClockID
gst_clock_new_single_shot_id (GstClock *clock, GstClockTime time)
{
84 85
  g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);

86 87 88 89 90 91 92
  return gst_clock_entry_new (clock, 
		  	      time, 
			      GST_CLOCK_TIME_NONE, 
			      GST_CLOCK_ENTRY_SINGLE);
}

/**
Wim Taymans's avatar
Wim Taymans committed
93
 * gst_clock_new_periodic_id
94 95 96 97 98 99 100 101 102 103 104 105 106 107
 * @clock: The clockid to get a periodic notification id from
 * @start_time: the requested start time
 * @interval: the requested interval
 *
 * Get an ID from the given clock to trigger a periodic notification.
 * The periodeic notifications will be start at time start_time and
 * will then be fired with the given interval.
 *
 * Returns: An id that can be used to request the time notification.
 */
GstClockID
gst_clock_new_periodic_id (GstClock *clock, GstClockTime start_time,
                           GstClockTime interval)
{
108 109 110 111
  g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
  g_return_val_if_fail (start_time != GST_CLOCK_TIME_NONE, NULL);
  g_return_val_if_fail (interval != 0, NULL);

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
  return gst_clock_entry_new (clock, 
		  	      start_time, 
			      interval, 
			      GST_CLOCK_ENTRY_PERIODIC);
}

/**
 * gst_clock_id_get_time
 * @id: The clockid to query
 *
 * Get the time of the clock ID
 *
 * Returns: the time of the given clock id
 */
GstClockTime
gst_clock_id_get_time (GstClockID id)
{
  g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);

  return GST_CLOCK_ENTRY_TIME ((GstClockEntry *)id);
}


/**
 * gst_clock_id_wait
 * @id: The clockid to wait on
 * @jitter: A pointer that will contain the jitter
 *
 * Perform a blocking wait on the given ID. The jitter arg can be
 * NULL
 *
 * Returns: the result of the blocking wait.
 */
GstClockReturn
gst_clock_id_wait (GstClockID id, GstClockTimeDiff *jitter)
147 148
{
  GstClockEntry *entry;
149 150 151
  GstClock *clock;
  GstClockReturn res = GST_CLOCK_UNSUPPORTED;
  GstClockTime requested;
Wim Taymans's avatar
Wim Taymans committed
152
  GstClockClass *cclass;
153 154
  
  g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
155

156 157
  entry = (GstClockEntry *) id;
  requested = GST_CLOCK_ENTRY_TIME (entry);
158 159 160 161 162 163 164

  if (requested == GST_CLOCK_TIME_NONE) {
    res = GST_CLOCK_TIMEOUT;
    goto done;
  }
  
  clock = GST_CLOCK_ENTRY_CLOCK (entry);
Wim Taymans's avatar
Wim Taymans committed
165
  cclass = GST_CLOCK_GET_CLASS (clock);
166
  
Wim Taymans's avatar
Wim Taymans committed
167
  if (cclass->wait) {
168
    GstClockTime now;
169

170
    do {
Wim Taymans's avatar
Wim Taymans committed
171
      res = cclass->wait (clock, entry);
172 173 174 175 176 177 178 179 180 181 182 183 184
    }
    while (res == GST_CLOCK_ENTRY_RESTART);

    if (jitter) {
      now = gst_clock_get_time (clock);
      *jitter = now - requested;
    }

    if (clock->stats) {
      gst_clock_update_stats (clock);
    }
  }

185
done:
186 187 188 189 190 191 192 193
  if (entry->type == GST_CLOCK_ENTRY_SINGLE) {
    gst_clock_id_free (id);
  }

  return res;
}

/**
Wim Taymans's avatar
Wim Taymans committed
194 195
 * gst_clock_id_wait_async:
 * @id: a #GstClockID to wait on
196 197 198
 * @func: The callback function 
 * @user_data: User data passed in the calback
 *
Wim Taymans's avatar
Wim Taymans committed
199 200
 * Register a callback on the given clockid with the given
 * function and user_data.
201
 *
202
 * Returns: the result of the non blocking wait.
203 204 205 206 207 208 209 210
 */
GstClockReturn
gst_clock_id_wait_async (GstClockID id,
		         GstClockCallback func, gpointer user_data)
{
  GstClockEntry *entry;
  GstClock *clock;
  GstClockReturn res = GST_CLOCK_UNSUPPORTED;
Wim Taymans's avatar
Wim Taymans committed
211
  GstClockClass *cclass;
212 213
  
  g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
214
  g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
215 216 217 218

  entry = (GstClockEntry *) id;
  clock = entry->clock;

219 220 221 222 223
  if (GST_CLOCK_ENTRY_TIME (entry) == GST_CLOCK_TIME_NONE) {
    (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
    return GST_CLOCK_TIMEOUT;
  }

Wim Taymans's avatar
Wim Taymans committed
224 225 226 227 228 229 230
  cclass = GST_CLOCK_GET_CLASS (clock);

  if (cclass->wait_async) {
    entry->func = func;
    entry->user_data = user_data;

    res = cclass->wait_async (clock, entry);
231 232 233 234 235 236
  }

  return res;
}

/**
Wim Taymans's avatar
Wim Taymans committed
237 238
 * gst_clock_id_unschedule:
 * @id: The id to unschedule
239 240 241 242 243 244 245 246
 *
 * Cancel an outstanding async notification request with the given ID.
 */
void
gst_clock_id_unschedule (GstClockID id)
{
  GstClockEntry *entry;
  GstClock *clock;
Wim Taymans's avatar
Wim Taymans committed
247
  GstClockClass *cclass;
248 249 250 251 252
  
  g_return_if_fail (id != NULL);

  entry = (GstClockEntry *) id;
  clock = entry->clock;
253

Wim Taymans's avatar
Wim Taymans committed
254 255 256 257
  cclass = GST_CLOCK_GET_CLASS (clock);

  if (cclass->unschedule)
    cclass->unschedule (clock, entry);
258 259
}

260
/**
Wim Taymans's avatar
Wim Taymans committed
261
 * gst_clock_id_free:
262 263 264 265 266 267
 * @id: The clockid to free
 *
 * Free the resources held by the given id
 */
void
gst_clock_id_free (GstClockID id)
268
{
269 270
  g_return_if_fail (id != NULL);

271 272
  gst_mem_chunk_free (_gst_clock_entries_chunk, id);
}
273

274
/**
Wim Taymans's avatar
Wim Taymans committed
275
 * gst_clock_id_unlock:
276 277 278 279 280 281 282 283 284
 * @id: The clockid to unlock
 *
 * Unlock the givan ClockID.
 */
void
gst_clock_id_unlock (GstClockID id)
{
  GstClockEntry *entry;
  GstClock *clock;
Wim Taymans's avatar
Wim Taymans committed
285
  GstClockClass *cclass;
286 287 288 289 290 291
  
  g_return_if_fail (id != NULL);

  entry = (GstClockEntry *) id;
  clock = entry->clock;

Wim Taymans's avatar
Wim Taymans committed
292 293 294 295
  cclass = GST_CLOCK_GET_CLASS (clock);

  if (cclass->unlock)
    cclass->unlock (clock, entry);
296 297
}

298 299 300 301

/**
 * GstClock abstract base class implementation
 */
302 303
GType
gst_clock_get_type (void)
Wim Taymans's avatar
Wim Taymans committed
304
{
305 306 307 308
  static GType clock_type = 0;

  if (!clock_type) {
    static const GTypeInfo clock_info = {
309
      sizeof (GstClockClass),
310 311 312 313 314
      NULL,
      NULL,
      (GClassInitFunc) gst_clock_class_init,
      NULL,
      NULL,
315
      sizeof (GstClock),
316 317 318 319 320
      4,
      (GInstanceInitFunc) gst_clock_init,
      NULL
    };
    clock_type = g_type_register_static (GST_TYPE_OBJECT, "GstClock", 
321
		    			 &clock_info,  G_TYPE_FLAG_ABSTRACT);
322 323 324
  }
  return clock_type;
}
325

326 327 328 329 330
static void
gst_clock_class_init (GstClockClass *klass)
{
  GObjectClass *gobject_class;
  GstObjectClass *gstobject_class;
331

332 333
  gobject_class = (GObjectClass*) klass;
  gstobject_class = (GstObjectClass*) klass;
334

335
  parent_class = g_type_class_ref (GST_TYPE_OBJECT);
336

Wim Taymans's avatar
Wim Taymans committed
337 338 339
  if (!g_thread_supported ())
    g_thread_init (NULL);

340
  _gst_clock_entries_chunk = gst_mem_chunk_new ("GstClockEntries",
341 342
                     sizeof (GstClockEntry), sizeof (GstClockEntry) * 32,
                     G_ALLOC_AND_FREE);
343 344 345 346 347 348 349 350 351 352

  _gst_clock_mutex = g_mutex_new ();
  _gst_clock_cond  = g_cond_new ();

  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_clock_set_property);
  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_clock_get_property);

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STATS,
    g_param_spec_boolean ("stats", "Stats", "Enable clock stats",
                          FALSE, G_PARAM_READWRITE));
Wim Taymans's avatar
Wim Taymans committed
353 354
}

355 356
static void
gst_clock_init (GstClock *clock)
Wim Taymans's avatar
Wim Taymans committed
357
{
358 359 360
  clock->speed = 1.0;
  clock->active = FALSE;
  clock->start_time = 0;
361 362
  clock->last_time = 0;
  clock->entries = NULL;
363 364
  clock->flags = 0;
  clock->stats = FALSE;
365 366 367

  clock->active_mutex = g_mutex_new ();
  clock->active_cond = g_cond_new ();
Wim Taymans's avatar
Wim Taymans committed
368 369
}

Wim Taymans's avatar
Wim Taymans committed
370 371
/**
 * gst_clock_set_speed
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
372 373
 * @clock: a #GstClock to modify
 * @speed: the speed to set on the clock
Wim Taymans's avatar
Wim Taymans committed
374
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
375
 * Sets the speed on the given clock. 1.0 is the default 
Wim Taymans's avatar
Wim Taymans committed
376
 * speed.
377 378
 *
 * Returns: the new speed of the clock.
Wim Taymans's avatar
Wim Taymans committed
379
 */
380
gdouble
Wim Taymans's avatar
Wim Taymans committed
381 382
gst_clock_set_speed (GstClock *clock, gdouble speed)
{
Wim Taymans's avatar
Wim Taymans committed
383 384
  GstClockClass *cclass;

385 386
  g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0);

Wim Taymans's avatar
Wim Taymans committed
387 388 389 390
  cclass = GST_CLOCK_GET_CLASS (clock);

  if (cclass->change_speed)
    clock->speed = cclass->change_speed (clock, clock->speed, speed);
Wim Taymans's avatar
Wim Taymans committed
391

392
  return clock->speed;
Wim Taymans's avatar
Wim Taymans committed
393 394 395 396
}

/**
 * gst_clock_get_speed
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
397
 * @clock: a #GstClock to query
Wim Taymans's avatar
Wim Taymans committed
398
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
399
 * Gets the speed of the given clock.
Wim Taymans's avatar
Wim Taymans committed
400 401 402 403 404 405 406 407 408 409 410 411
 *
 * Returns: the speed of the clock.
 */
gdouble
gst_clock_get_speed (GstClock *clock)
{
  g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0);

  return clock->speed;
}

/**
412 413 414
 * gst_clock_set_resolution
 * @clock: The clock set the resolution on
 * @resolution: The resolution to set
Wim Taymans's avatar
Wim Taymans committed
415
 *
416 417 418
 * Set the accuracy of the clock.
 *
 * Returns: the new resolution of the clock.
Wim Taymans's avatar
Wim Taymans committed
419
 */
420 421
guint64
gst_clock_set_resolution (GstClock *clock, guint64 resolution)
Wim Taymans's avatar
Wim Taymans committed
422
{
Wim Taymans's avatar
Wim Taymans committed
423 424
  GstClockClass *cclass;

425
  g_return_val_if_fail (GST_IS_CLOCK (clock), 0LL);
426
  g_return_val_if_fail (resolution != 0, 0LL);
427

Wim Taymans's avatar
Wim Taymans committed
428 429 430 431
  cclass = GST_CLOCK_GET_CLASS (clock);

  if (cclass->change_resolution)
    clock->resolution = cclass->change_resolution (clock, clock->resolution, resolution);
432

433 434
  return clock->resolution;
}
435

436 437 438 439 440 441 442 443 444 445 446
/**
 * gst_clock_get_resolution
 * @clock: The clock get the resolution of
 *
 * Get the accuracy of the clock.
 *
 * Returns: the resolution of the clock in microseconds.
 */
guint64
gst_clock_get_resolution (GstClock *clock)
{
Wim Taymans's avatar
Wim Taymans committed
447 448
  GstClockClass *cclass;

449 450
  g_return_val_if_fail (GST_IS_CLOCK (clock), 0LL);

Wim Taymans's avatar
Wim Taymans committed
451 452 453 454
  cclass = GST_CLOCK_GET_CLASS (clock);

  if (cclass->get_resolution)
    return cclass->get_resolution (clock);
455 456

  return 1LL;
Wim Taymans's avatar
Wim Taymans committed
457 458
}

Wim Taymans's avatar
Wim Taymans committed
459
/**
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
460 461 462
 * gst_clock_set_active
 * @clock: a #GstClock to set state of
 * @active: flag indicating if the clock should be activated (TRUE) or deactivated
Wim Taymans's avatar
Wim Taymans committed
463
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
464
 * Activates or deactivates the clock based on the active parameter.
Wim Taymans's avatar
Wim Taymans committed
465 466
 * As soon as the clock is activated, the time will start ticking.
 */
467
void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
468
gst_clock_set_active (GstClock *clock, gboolean active)
Wim Taymans's avatar
Wim Taymans committed
469
{
470
  GstClockTime time = 0LL;
Wim Taymans's avatar
Wim Taymans committed
471
  GstClockClass *cclass;
472

473 474 475
  g_return_if_fail (GST_IS_CLOCK (clock));

  clock->active = active;
Wim Taymans's avatar
Wim Taymans committed
476 477

  cclass = GST_CLOCK_GET_CLASS (clock);
478
	        
Wim Taymans's avatar
Wim Taymans committed
479 480
  if (cclass->get_internal_time) {
    time = cclass->get_internal_time (clock);
481
  }
482

483 484
  GST_LOCK (clock);
  if (active) {
485 486
    clock->start_time = time - clock->last_time;
    clock->accept_discont = TRUE;
487 488 489
  }
  else {
    clock->last_time = time - clock->start_time;
490
    clock->accept_discont = FALSE;
491 492
  }
  GST_UNLOCK (clock);
493 494

  g_mutex_lock (clock->active_mutex);	
495
  g_cond_broadcast (clock->active_cond);	
496
  g_mutex_unlock (clock->active_mutex);	
497 498
}

Wim Taymans's avatar
Wim Taymans committed
499 500
/**
 * gst_clock_is_active
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
501
 * @clock: a #GstClock to query
Wim Taymans's avatar
Wim Taymans committed
502 503 504 505 506
 *
 * Checks if the given clock is active.
 * 
 * Returns: TRUE if the clock is active.
 */
507 508
gboolean
gst_clock_is_active (GstClock *clock)
509
{
510
  g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
511

512
  return clock->active;
Wim Taymans's avatar
Wim Taymans committed
513 514
}

515 516 517 518 519 520 521 522 523 524
/**
 * gst_clock_reset
 * @clock: a #GstClock to reset
 *
 * Reset the clock to time 0.
 */
void
gst_clock_reset (GstClock *clock)
{
  GstClockTime time = 0LL;
Wim Taymans's avatar
Wim Taymans committed
525
  GstClockClass *cclass;
526 527 528

  g_return_if_fail (GST_IS_CLOCK (clock));

Wim Taymans's avatar
Wim Taymans committed
529 530 531 532
  cclass = GST_CLOCK_GET_CLASS (clock);
	        
  if (cclass->get_internal_time) {
    time = cclass->get_internal_time (clock);
533 534 535 536 537 538 539 540 541
  }

  GST_LOCK (clock);
  clock->active = FALSE;
  clock->start_time = time;
  clock->last_time = 0LL;
  GST_UNLOCK (clock);
}

Wim Taymans's avatar
Wim Taymans committed
542 543 544 545 546 547
/**
 * gst_clock_handle_discont
 * @clock: a #GstClock to notify of the discontinuity
 * @time: The new time
 *
 * Notifies the clock of a discontinuity in time.
548
 *
Wim Taymans's avatar
Wim Taymans committed
549 550 551 552
 * Returns: TRUE if the clock was updated. It is possible that
 * the clock was not updated by this call because only the first
 * discontinuitity in the pipeline is honoured.
 */
553 554 555 556
gboolean
gst_clock_handle_discont (GstClock *clock, guint64 time)
{
  GstClockTime itime = 0LL;
557 558 559 560

  GST_DEBUG (GST_CAT_CLOCK, "clock discont %" G_GUINT64_FORMAT
		            " %" G_GUINT64_FORMAT " %d",
			    time, clock->start_time, clock->accept_discont);
561

562 563 564
  if (time == GST_CLOCK_TIME_NONE)
    return TRUE;

565 566
  GST_LOCK (clock);
  if (clock->accept_discont) {
Wim Taymans's avatar
Wim Taymans committed
567 568 569 570 571 572
    GstClockClass *cclass;

    cclass = GST_CLOCK_GET_CLASS (clock);
	  
    if (cclass->get_internal_time) {
      itime = cclass->get_internal_time (clock);
573 574 575 576
    }
  }
  else {
    GST_UNLOCK (clock);
577 578 579
    GST_DEBUG (GST_CAT_CLOCK, "clock discont refused %" G_GUINT64_FORMAT
		              " %" G_GUINT64_FORMAT,
			      time, clock->start_time);
580 581 582 583 584 585 586 587
    return FALSE;
  }

  clock->start_time = itime - time;
  clock->last_time = time;
  clock->accept_discont = FALSE;
  GST_UNLOCK (clock);

588 589
  GST_DEBUG (GST_CAT_CLOCK, "new time %" G_GUINT64_FORMAT,
	     gst_clock_get_time (clock));
590

591 592 593
  g_mutex_lock (clock->active_mutex);
  g_cond_broadcast (clock->active_cond);
  g_mutex_unlock (clock->active_mutex);
594 595 596 597

  return TRUE;
}

Wim Taymans's avatar
Wim Taymans committed
598 599
/**
 * gst_clock_get_time
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
600
 * @clock: a #GstClock to query
Wim Taymans's avatar
Wim Taymans committed
601
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
602
 * Gets the current time of the given clock. The time is always
Wim Taymans's avatar
Wim Taymans committed
603
 * monotonically increasing.
604
 *
Wim Taymans's avatar
Wim Taymans committed
605 606
 * Returns: the time of the clock.
 */
607 608 609
GstClockTime
gst_clock_get_time (GstClock *clock)
{
610 611
  GstClockTime ret = 0LL;

612 613
  g_return_val_if_fail (GST_IS_CLOCK (clock), 0LL);

614 615 616 617 618
  if (!clock->active) {
    /* clock is not activen return previous time */
    ret = clock->last_time;
  }
  else {
Wim Taymans's avatar
Wim Taymans committed
619 620 621 622 623 624
    GstClockClass *cclass;

    cclass = GST_CLOCK_GET_CLASS (clock);

    if (cclass->get_internal_time) {
      ret = cclass->get_internal_time (clock) - clock->start_time;
625 626
    }
    /* make sure the time is increasing, else return last_time */
627
    if ((gint64) ret < (gint64) clock->last_time) {
628 629 630 631 632 633
      ret = clock->last_time;
    }
    else {
      clock->last_time = ret;
    }
  }
634

635
  return ret;
636 637
}

Wim Taymans's avatar
Wim Taymans committed
638 639 640 641 642 643 644 645
/**
 * gst_clock_get_next_id
 * @clock: The clock to query
 *
 * Get the clockid of the next event.
 *
 * Returns: a clockid or NULL is no event is pending.
 */
646 647 648 649 650
GstClockID
gst_clock_get_next_id (GstClock *clock)
{
  GstClockEntry *entry = NULL;

651 652
  g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);

653 654 655 656 657 658 659 660 661
  GST_LOCK (clock);
  if (clock->entries)
    entry = GST_CLOCK_ENTRY (clock->entries->data);
  GST_UNLOCK (clock);

  return (GstClockID *) entry;
}

static void
662
gst_clock_update_stats (GstClock *clock)
663
{
664 665
}

666 667 668
static void
gst_clock_set_property (GObject *object, guint prop_id,
     		        const GValue *value, GParamSpec *pspec)
669
{
670 671 672 673 674 675 676 677 678 679 680 681
  GstClock *clock;
	     
  clock = GST_CLOCK (object);

  switch (prop_id) {
    case ARG_STATS:
      clock->stats = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
   }
Wim Taymans's avatar
Wim Taymans committed
682
}
683

684 685 686
static void
gst_clock_get_property (GObject *object, guint prop_id, 
			GValue *value, GParamSpec * pspec)
687
{
688 689 690 691 692 693 694 695 696 697 698 699
  GstClock *clock;
	     
  clock = GST_CLOCK (object);

  switch (prop_id) {
    case ARG_STATS:
      g_value_set_boolean (value, clock->stats);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
   }
700
}