diff options
Diffstat (limited to 'sys/oss/gstossclock.c')
-rw-r--r-- | sys/oss/gstossclock.c | 261 |
1 files changed, 28 insertions, 233 deletions
diff --git a/sys/oss/gstossclock.c b/sys/oss/gstossclock.c index 5b3f16fb..0a763627 100644 --- a/sys/oss/gstossclock.c +++ b/sys/oss/gstossclock.c @@ -22,31 +22,10 @@ #include "gstossclock.h" -static GMemChunk *_gst_clock_entries_chunk; -static GMutex *_gst_clock_entries_chunk_lock; -static GList *_gst_clock_entries_pool; - -typedef struct _GstClockEntry GstClockEntry; - -typedef enum { - GST_ENTRY_OK, - GST_ENTRY_RESTART, -} GstEntryStatus; - -struct _GstClockEntry { - GstClockTime time; - GstEntryStatus status; - GMutex *lock; - GCond *cond; -}; - static void gst_oss_clock_class_init (GstOssClockClass *klass); static void gst_oss_clock_init (GstOssClock *clock); -static void gst_oss_clock_reset (GstClock *clock); -static void gst_oss_clock_activate (GstClock *clock, gboolean activate); -static void gst_oss_clock_set_time (GstClock *clock, GstClockTime time); -static GstClockReturn gst_oss_clock_wait (GstClock *clock, GstClockTime time); +static GstClockTime gst_oss_clock_get_internal_time (GstClock *clock); static GstSystemClockClass *parent_class = NULL; /* static guint gst_oss_clock_signals[LAST_SIGNAL] = { 0 }; */ @@ -89,241 +68,57 @@ gst_oss_clock_class_init (GstOssClockClass *klass) parent_class = g_type_class_ref (GST_TYPE_SYSTEM_CLOCK); - gstclock_class->reset = gst_oss_clock_reset; - gstclock_class->activate = gst_oss_clock_activate; - gstclock_class->set_time = gst_oss_clock_set_time; - gstclock_class->wait = gst_oss_clock_wait; + gstclock_class->get_internal_time = gst_oss_clock_get_internal_time; } static void gst_oss_clock_init (GstOssClock *clock) { gst_object_set_name (GST_OBJECT (clock), "GstOssClock"); - clock->is_updated = FALSE; -} - -#define GST_CLOCK_ENTRY(entry) ((GstClockEntry *)(entry)) -#define GST_CLOCK_ENTRY_TIME(entry) (((GstClockEntry *)(entry))->time) -#define GST_CLOCK_ENTRY_LOCK(entry) (g_mutex_lock ((entry)->lock)) -#define GST_CLOCK_ENTRY_UNLOCK(entry) (g_mutex_unlock ((entry)->lock)) -#define GST_CLOCK_ENTRY_SIGNAL(entry) (g_cond_signal ((entry)->cond)) -#define GST_CLOCK_ENTRY_WAIT(entry) (g_cond_wait (entry->cond, entry->lock)) -#define GST_CLOCK_ENTRY_TIMED_WAIT(entry, time) (g_cond_timed_wait (entry->cond, entry->lock, (time))) - -static GstClockEntry* -gst_clock_entry_new (GstClockTime time) -{ - GstClockEntry *entry; - - g_mutex_lock (_gst_clock_entries_chunk_lock); - if (_gst_clock_entries_pool) { - entry = GST_CLOCK_ENTRY (_gst_clock_entries_pool->data); - - _gst_clock_entries_pool = g_list_remove (_gst_clock_entries_pool, entry); - g_mutex_unlock (_gst_clock_entries_chunk_lock); - } - else { - entry = g_mem_chunk_alloc (_gst_clock_entries_chunk); - g_mutex_unlock (_gst_clock_entries_chunk_lock); - - entry->lock = g_mutex_new (); - entry->cond = g_cond_new (); - } - - entry->time = time; - - return entry; -} -static void -gst_clock_entry_free (GstClockEntry *entry) -{ - g_mutex_lock (_gst_clock_entries_chunk_lock); - _gst_clock_entries_pool = g_list_prepend (_gst_clock_entries_pool, entry); - g_mutex_unlock (_gst_clock_entries_chunk_lock); + clock->prev1 = 0; + clock->prev2 = 0; } GstOssClock* -gst_oss_clock_new (gchar *name, GstElement *owner) +gst_oss_clock_new (gchar *name, GstOssClockGetTimeFunc func, gpointer user_data) { GstOssClock *oss_clock = GST_OSS_CLOCK (g_object_new (GST_TYPE_OSS_CLOCK, NULL)); - oss_clock->entries = NULL; - oss_clock->current_time = 0; - oss_clock->next_time = 0; - - _gst_clock_entries_chunk = g_mem_chunk_new ("GstClockEntries", - sizeof (GstClockEntry), sizeof (GstClockEntry) * 32, - G_ALLOC_AND_FREE); - _gst_clock_entries_chunk_lock = g_mutex_new (); - _gst_clock_entries_pool = NULL; + oss_clock->func = func; + oss_clock->user_data = user_data; + oss_clock->adjust = 0; return oss_clock; } -void -gst_oss_clock_set_update (GstOssClock *clock, gboolean update) -{ - GST_LOCK (clock); - - if (!update) { - - GST_UNLOCK (clock); - GST_CLOCK_CLASS (parent_class)->set_time (GST_CLOCK (clock), clock->current_time); - GST_LOCK (clock); - clock->is_updated = FALSE; - - /* FIXME, convert the entries to ones that wait for the system clock */ - if (clock->entries) { - GList *entries = g_list_copy (clock->entries); - while (entries) { - GstClockEntry *entry = (GstClockEntry *)entries->data; - - GST_CLOCK_ENTRY_LOCK (entry); - GST_CLOCK_ENTRY_SIGNAL (entry); - entry->status = GST_ENTRY_RESTART; - GST_CLOCK_ENTRY_UNLOCK (entry); - - clock->entries = g_list_remove (clock->entries, entry); - entries = g_list_next (entries); - } - } - } - else { - clock->is_updated = TRUE; - } - - GST_UNLOCK (clock); -} - -void -gst_oss_clock_set_base (GstOssClock *clock, guint64 base) -{ - GstOssClock *oss_clock = GST_OSS_CLOCK (clock); - - oss_clock->base_time = base; - - GST_CLOCK_CLASS (parent_class)->set_time (clock, base); -} - -static void -gst_oss_clock_reset (GstClock *clock) -{ - GstOssClock *oss_clock = GST_OSS_CLOCK (clock); - - oss_clock->next_time = 0; - oss_clock->current_time = 0; - oss_clock->base_time = 0; - - GST_CLOCK_CLASS (parent_class)->reset (clock); -} - -static void -gst_oss_clock_activate (GstClock *clock, gboolean activate) -{ - GstOssClock *oss_clock = GST_OSS_CLOCK (clock); - - if (!activate) { - oss_clock->base_time = oss_clock->current_time; - } - - GST_CLOCK_CLASS (parent_class)->activate (clock, activate); -} - -static void -gst_oss_clock_set_time (GstClock *clock, GstClockTime time) +static GstClockTime +gst_oss_clock_get_internal_time (GstClock *clock) { - GList *entries; + GTimeVal timeval; + GstClockTime time1; + GstClockTime time2; + GstClockTimeDiff diff1, diff2; GstOssClock *oss_clock = GST_OSS_CLOCK (clock); - - GST_LOCK (clock); - - time += oss_clock->base_time; - - /*g_print ("set time %llu\n", time); */ - - oss_clock->current_time = time; - - if (oss_clock->next_time > time) { - GST_UNLOCK (clock); - return; + + g_get_current_time (&timeval); + time1 = oss_clock->func (clock, oss_clock->user_data); + time2 = GST_TIMEVAL_TO_TIME (timeval); + if (!oss_clock->prev1) { + oss_clock->prev1 = time1; } + diff1 = time1 - oss_clock->prev1; + diff2 = time2 - oss_clock->prev2; - entries = g_list_copy (oss_clock->entries); - - while (entries) { - GstClockEntry *entry = (GstClockEntry *)entries->data; - - if (GST_CLOCK_ENTRY_TIME (entry) <= oss_clock->current_time) { - - GST_CLOCK_ENTRY_LOCK (entry); - GST_CLOCK_ENTRY_SIGNAL (entry); - entry->status = GST_ENTRY_OK; - GST_CLOCK_ENTRY_UNLOCK (entry); + oss_clock->prev1 = time1; + oss_clock->prev2 = time2; - oss_clock->entries = g_list_remove (oss_clock->entries, entry); - } - else { - break; - } - entries = g_list_next (entries); + if (diff1) { + oss_clock->adjust -= diff2 - diff1; } - if (oss_clock->entries) { - oss_clock->next_time = GST_CLOCK_ENTRY_TIME (oss_clock->entries->data); - } - else { - oss_clock->next_time = 0; - } - - GST_UNLOCK (oss_clock); -} - -static gint -clock_compare_func (gconstpointer a, - gconstpointer b) -{ - GstClockEntry *entry1 = (GstClockEntry *)a; - GstClockEntry *entry2 = (GstClockEntry *)b; + //g_print ("diff %lld %lld %lld %lld %lld %lld\n", diff1, diff2, time1, time2, diff2 - diff1, oss_clock->adjust); - return (entry1->time - entry2->time); + return time2 + oss_clock->adjust; } -static GstClockReturn -gst_oss_clock_wait (GstClock *clock, GstClockTime time) -{ - GstClockReturn ret; - GstOssClock *oss_clock = GST_OSS_CLOCK (clock); - - GST_LOCK (clock); -restart: - if (!oss_clock->is_updated) { - GST_UNLOCK (clock); - ret = GST_CLOCK_CLASS (parent_class)->wait (clock, time); - } - else if (time > oss_clock->current_time) { - GstClockEntry *entry = gst_clock_entry_new (time); - - oss_clock->entries = g_list_insert_sorted (oss_clock->entries, entry, clock_compare_func); - - oss_clock->next_time = GST_CLOCK_ENTRY_TIME (oss_clock->entries->data); - - GST_CLOCK_ENTRY_LOCK (entry); - GST_UNLOCK (clock); - GST_CLOCK_ENTRY_WAIT (entry); - if (entry->status == GST_ENTRY_RESTART) - goto restart; - GST_CLOCK_ENTRY_UNLOCK (entry); - - gst_clock_entry_free (entry); - - ret = GST_CLOCK_TIMEOUT; - } - else { - GST_UNLOCK (clock); - - ret = GST_CLOCK_EARLY; - } - - return ret; -} |