gstclock.c 4.61 KB
Newer Older
Wim Taymans's avatar
Wim Taymans committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* Gnome-Streamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * 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>
21
//#define DEBUG_ENABLED
Wim Taymans's avatar
Wim Taymans committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#include <gstclock.h>

static GstClock *the_system_clock = NULL;

/**
 * gst_clock_new:
 * @name: the name of the new clock
 *
 * create a new clock element
 *
 * Returns: the new clock element
 */
GstClock *gst_clock_new(gchar *name) {
  GstClock *clock = (GstClock *) g_malloc(sizeof(GstClock));
  clock->name = g_strdup(name);
  clock->sinkobjects = NULL;
  clock->sinkmutex = g_mutex_new();
  clock->lock = g_mutex_new();
  g_mutex_lock(clock->sinkmutex);
41 42 43
  clock->num = 0;
  clock->num_locked = 0;
  clock->locking = FALSE;
Wim Taymans's avatar
Wim Taymans committed
44 45 46 47 48 49 50 51 52 53 54 55 56
  return clock;
}

GstClock *gst_clock_get_system() {
  if (the_system_clock == NULL) {
    the_system_clock = gst_clock_new("system_clock");
    gst_clock_reset(the_system_clock);
  }
  return the_system_clock;
}

void gst_clock_register(GstClock *clock, GstObject *obj) {
  if (GST_IS_SINK(obj)) {
57
    DEBUG("gst_clock: setting registered sink object 0x%p\n", obj);
Wim Taymans's avatar
Wim Taymans committed
58
    clock->sinkobjects = g_list_append(clock->sinkobjects, obj);
59
    clock->num++;
Wim Taymans's avatar
Wim Taymans committed
60 61 62 63 64
  }
}

void gst_clock_set(GstClock *clock, GstClockTime time) {
  struct timeval tfnow;
65
  GstClockTime now;
Wim Taymans's avatar
Wim Taymans committed
66

67 68
  gettimeofday(&tfnow, (struct timezone *)NULL);
  now = tfnow.tv_sec*1000000LL+tfnow.tv_usec;
Wim Taymans's avatar
Wim Taymans committed
69
  g_mutex_lock(clock->lock);
70 71 72 73 74 75 76 77 78 79
  clock->start_time = now - time;
  g_mutex_unlock(clock->lock);
  DEBUG("gst_clock: setting clock to %llu %llu %llu\n", time, now, clock->start_time);
}

GstClockTimeDiff gst_clock_current_diff(GstClock *clock, GstClockTime time)
{
  struct timeval tfnow;
  GstClockTime now;

Wim Taymans's avatar
Wim Taymans committed
80
  gettimeofday(&tfnow, (struct timezone *)NULL);
81 82 83
  g_mutex_lock(clock->lock);
  now = ((guint64)tfnow.tv_sec*1000000LL+tfnow.tv_usec) - (guint64)clock->start_time; 
  //if (clock->locking) now = 0;
Wim Taymans's avatar
Wim Taymans committed
84
  g_mutex_unlock(clock->lock);
85 86 87 88

  //DEBUG("gst_clock: diff with for time %08llu %08lld %08lld %08llu\n", time, now, GST_CLOCK_DIFF(time, now), clock->start_time);

  return GST_CLOCK_DIFF(time, now);
Wim Taymans's avatar
Wim Taymans committed
89 90 91 92 93 94
}

void gst_clock_reset(GstClock *clock) {
  struct timeval tfnow;

  gettimeofday(&tfnow, (struct timezone *)NULL);
95 96
  g_mutex_lock(clock->lock);
  clock->start_time = ((guint64)tfnow.tv_sec)*1000000LL+tfnow.tv_usec;
Wim Taymans's avatar
Wim Taymans committed
97 98 99
  clock->current_time = clock->start_time;
  clock->adjust = 0LL;
  DEBUG("gst_clock: setting start clock %llu\n", clock->start_time);
100 101
  //clock->locking = TRUE;
  g_mutex_unlock(clock->lock);
Wim Taymans's avatar
Wim Taymans committed
102 103 104 105
}

void gst_clock_wait(GstClock *clock, GstClockTime time, GstObject *obj) {
  struct timeval tfnow;
106
  GstClockTime now;
Wim Taymans's avatar
Wim Taymans committed
107 108
  GstClockTimeDiff diff;

109
  //DEBUG("gst_clock: requesting clock object 0x%p %08llu %08llu\n", obj, time, clock->current_time);
Wim Taymans's avatar
Wim Taymans committed
110 111

  gettimeofday(&tfnow, (struct timezone *)NULL);
112 113
  g_mutex_lock(clock->lock);
  now = tfnow.tv_sec*1000000LL+tfnow.tv_usec - clock->start_time;
Wim Taymans's avatar
Wim Taymans committed
114 115
  //now = clock->current_time + clock->adjust;

116
  diff = GST_CLOCK_DIFF(time, now);
Wim Taymans's avatar
Wim Taymans committed
117
  // if we are not behind wait a bit
118
  DEBUG("gst_clock: %s waiting for time %08llu %08llu %08lld\n", gst_element_get_name(GST_ELEMENT(obj)), time, now, diff);
Wim Taymans's avatar
Wim Taymans committed
119
   
120 121 122
  g_mutex_unlock(clock->lock);
  if (diff > 10000 ) {
    tfnow.tv_usec = (diff % 1000000);
Wim Taymans's avatar
Wim Taymans committed
123 124
    tfnow.tv_sec = diff / 1000000;
    // FIXME, this piece of code does not work with egcs optimisations on, had to use the following line
125 126 127
    if (!tfnow.tv_sec) {
      select(0, NULL, NULL, NULL, &tfnow);
    }
128 129
    else printf("gst_clock: %s waiting %u %llu %llu %llu seconds\n", gst_element_get_name(GST_ELEMENT(obj)), 
		    (int)tfnow.tv_sec, now, diff, time);
Wim Taymans's avatar
Wim Taymans committed
130
    //DEBUG("gst_clock: 0x%p waiting for time %llu %llu %lld %llu\n", obj, time, target, diff, now);
131 132
    //DEBUG("waiting %d.%08d\n",tfnow.tv_sec, tfnow.tv_usec);
    //DEBUG("gst_clock: 0x%p waiting done time %llu \n", obj, time);
Wim Taymans's avatar
Wim Taymans committed
133
  }
134
  DEBUG("gst_clock: %s waiting for time %08llu %08llu %08lld done \n", gst_element_get_name(GST_ELEMENT(obj)), time, now, diff);
Wim Taymans's avatar
Wim Taymans committed
135 136 137 138
 // clock->current_time = clock->start_time + time;
  //gst_clock_set(clock, time);

}