summaryrefslogtreecommitdiffstats
path: root/sys/oss/gstossclock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/oss/gstossclock.c')
-rw-r--r--sys/oss/gstossclock.c261
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;
-}