summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-03-30 17:06:26 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-03-30 17:06:26 +0000
commit13d9e8d35227337a04b0cd24a0dda7c0c3961289 (patch)
tree9a4e6fa918604e74a46251b50d2f26d7c0d2d024 /sys
parentc5e4b06ff518ca83a403c175e22a802ee73714f1 (diff)
Changed to the new props API
Original commit message from CVS: Changed to the new props API Other small tuff.
Diffstat (limited to 'sys')
-rw-r--r--sys/oss/gstossclock.c261
-rw-r--r--sys/oss/gstossclock.h25
-rw-r--r--sys/oss/gstosssink.c132
-rw-r--r--sys/oss/gstosssink.h1
4 files changed, 109 insertions, 310 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;
-}
diff --git a/sys/oss/gstossclock.h b/sys/oss/gstossclock.h
index 30659fea..e3f28325 100644
--- a/sys/oss/gstossclock.h
+++ b/sys/oss/gstossclock.h
@@ -45,18 +45,17 @@ extern "C" {
typedef struct _GstOssClock GstOssClock;
typedef struct _GstOssClockClass GstOssClockClass;
+typedef GstClockTime (*GstOssClockGetTimeFunc) (GstClock *clock, gpointer user_data);
+
+
struct _GstOssClock {
GstSystemClock clock;
-
- GList *entries;
- GstClockTime current_time;
- GstClockTime next_time;
- GstClockTime base_time;
- gboolean is_updated;
- GstClockTime start_time;
- GstClockTime origin;
-
- GstElement *owner;
+
+ GstOssClockGetTimeFunc func;
+ gpointer user_data;
+
+ GstClockTime prev1, prev2;
+ GstClockTimeDiff adjust;
};
struct _GstOssClockClass {
@@ -64,10 +63,8 @@ struct _GstOssClockClass {
};
GType gst_oss_clock_get_type (void);
-GstOssClock* gst_oss_clock_new (gchar *name, GstElement *owner);
-
-void gst_oss_clock_set_update (GstOssClock *clock, gboolean update);
-void gst_oss_clock_set_base (GstOssClock *clock, guint64 base);
+GstOssClock* gst_oss_clock_new (gchar *name, GstOssClockGetTimeFunc func,
+ gpointer user_data);
#ifdef __cplusplus
}
diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c
index 9c1f78ad..c96efee8 100644
--- a/sys/oss/gstosssink.c
+++ b/sys/oss/gstosssink.c
@@ -50,7 +50,8 @@ static void gst_osssink_close_audio (GstOssSink *sink);
static gboolean gst_osssink_sync_parms (GstOssSink *osssink);
static GstElementStateReturn gst_osssink_change_state (GstElement *element);
static void gst_osssink_set_clock (GstElement *element, GstClock *clock);
-static GstClock* gst_osssink_get_clock (GstElement *element);
+static GstClock* gst_osssink_get_clock (GstElement *element);
+
static GstPadConnectReturn gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps);
static void gst_osssink_set_property (GObject *object, guint prop_id, const GValue *value,
@@ -213,7 +214,21 @@ gst_osssink_class_init (GstOssSinkClass *klass)
gobject_class->get_property = gst_osssink_get_property;
gobject_class->finalize = gst_osssink_finalize;
- gstelement_class->change_state = gst_osssink_change_state;
+ gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_osssink_change_state);
+}
+
+static GstClockTime
+gst_osssink_get_time (GstClock *clock, gpointer data)
+{
+ GstOssSink *osssink = GST_OSSSINK (data);
+ gint delay;
+
+ if (!osssink->bps)
+ return 0;
+
+ ioctl (osssink->fd, SNDCTL_DSP_GETODELAY, &delay);
+
+ return osssink->offset + (osssink->handled - delay) * 1000000LL / osssink->bps;
}
static void
@@ -240,16 +255,19 @@ gst_osssink_init (GstOssSink *osssink)
#endif /* WORDS_BIGENDIAN */
/* gst_clock_register (osssink->clock, GST_OBJECT (osssink)); */
osssink->bufsize = 4096;
- osssink->offset = 0LL;
+ osssink->offset = -1LL;
+ osssink->handled = 0LL;
/* 6 buffers per chunk by default */
osssink->sinkpool = gst_buffer_pool_get_default (osssink->bufsize, 6);
- osssink->provided_clock = GST_CLOCK (gst_oss_clock_new ("OssClock", GST_ELEMENT (osssink)));
+ osssink->provided_clock = NULL;
+ osssink->provided_clock = GST_CLOCK (gst_oss_clock_new ("ossclock", gst_osssink_get_time, osssink));
GST_ELEMENT (osssink)->setclockfunc = gst_osssink_set_clock;
GST_ELEMENT (osssink)->getclockfunc = gst_osssink_get_clock;
GST_FLAG_SET (osssink, GST_ELEMENT_THREAD_SUGGESTED);
+ GST_FLAG_SET (osssink, GST_ELEMENT_EVENT_AWARE);
}
static GstPadConnectReturn
@@ -263,8 +281,8 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps)
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
- width = gst_caps_get_int (caps, "width");
- depth = gst_caps_get_int (caps, "depth");
+ gst_caps_get_int (caps, "width", &width);
+ gst_caps_get_int (caps, "depth", &depth);
if (width != depth)
return GST_PAD_CONNECT_REFUSED;
@@ -272,9 +290,9 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps)
/* laws 1 and 2 are 1 bps anyway */
osssink->bps = 1;
- law = gst_caps_get_int (caps, "law");
- endianness = gst_caps_get_int (caps, "endianness");
- sign = gst_caps_get_boolean (caps, "signed");
+ gst_caps_get_int (caps, "law", &law);
+ gst_caps_get_int (caps, "endianness", &endianness);
+ gst_caps_get_boolean (caps, "signed", &sign);
if (law == 0) {
if (width == 16) {
@@ -314,8 +332,8 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps)
return GST_PAD_CONNECT_REFUSED;
osssink->format = format;
- osssink->channels = gst_caps_get_int (caps, "channels");
- osssink->frequency = gst_caps_get_int (caps, "rate");
+ gst_caps_get_int (caps, "channels", &osssink->channels);
+ gst_caps_get_int (caps, "rate", &osssink->frequency);
osssink->bps *= osssink->channels;
osssink->bps *= osssink->frequency;
@@ -344,9 +362,9 @@ gst_osssink_sync_parms (GstOssSink *osssink)
return FALSE;
if (osssink->fragment >> 16)
- frag = osssink->fragment;
+ frag = osssink->fragment;
else
- frag = 0x7FFF0000 | osssink->fragment;
+ frag = 0x7FFF0000 | osssink->fragment;
GST_INFO (GST_CAT_PLUGIN_INFO, "osssink: trying to set sound card to %dHz %d bit %s (%08x fragment)",
osssink->frequency, osssink->format,
@@ -393,24 +411,24 @@ gst_osssink_sync_parms (GstOssSink *osssink)
return TRUE;
}
-static void
-gst_osssink_set_clock (GstElement *element, GstClock *clock)
+static GstClock*
+gst_osssink_get_clock (GstElement *element)
{
GstOssSink *osssink;
osssink = GST_OSSSINK (element);
- osssink->clock = clock;
+ return GST_CLOCK (osssink->provided_clock);
}
-static GstClock*
-gst_osssink_get_clock (GstElement *element)
+static void
+gst_osssink_set_clock (GstElement *element, GstClock *clock)
{
GstOssSink *osssink;
osssink = GST_OSSSINK (element);
- return osssink->provided_clock;
+ osssink->clock = clock;
}
static void
@@ -422,6 +440,17 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf)
/* this has to be an audio buffer */
osssink = GST_OSSSINK (gst_pad_get_parent (pad));
+ if (GST_IS_EVENT (buf)) {
+ switch (GST_EVENT_TYPE (buf)) {
+ case GST_EVENT_EOS:
+ ioctl (osssink->fd, SNDCTL_DSP_SYNC);
+ gst_pad_event_default (pad, GST_EVENT (buf));
+ return;
+ default:
+ return;
+ }
+ }
+
buftime = GST_BUFFER_TIMESTAMP (buf);
if (!osssink->bps) {
@@ -433,47 +462,26 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf)
if (!osssink->mute) {
guchar *data = GST_BUFFER_DATA (buf);
gint size = GST_BUFFER_SIZE (buf);
+ gint frag = osssink->fragment;
if (osssink->clock) {
- if (osssink->clock == osssink->provided_clock) {
- guint64 time;
- gint granularity, granularity_time;
- count_info optr;
- audio_buf_info ospace;
- gint queued;
-
- /* FIXME, NEW_MEDIA/DISCONT?. Try to get our start point */
- if (osssink->offset == 0LL && buftime != -1LL) {
- /* gst_oss_clock_set_base (GST_OSS_CLOCK (osssink->clock), buftime); */
- osssink->offset = buftime;
- }
-
- ioctl (osssink->fd, SNDCTL_DSP_GETOSPACE, &ospace);
- ioctl (osssink->fd, SNDCTL_DSP_GETOPTR, &optr);
-
- queued = (ospace.fragstotal * ospace.fragsize) - ospace.bytes;
- time = osssink->offset + (optr.bytes) * 1000000LL / osssink->bps;
-
- GST_DEBUG (GST_CAT_PLUGIN_INFO, "sync %llu %llu %d", buftime, time, queued);
-
- granularity = ospace.fragsize;
- /* granularity = size; */
- granularity_time = granularity * osssink->fragment_time / ospace.fragsize;
-
- while (size > 0) {
- write (osssink->fd, data, MIN (size, granularity));
- data += granularity;
- size -= granularity;
- time += granularity_time;
- gst_clock_set_time (osssink->provided_clock, time);
- }
- }
- else {
+ /* FIXME, NEW_MEDIA/DISCONT?. Try to get our start point */
+ if (osssink->offset == -1LL && buftime != -1LL) {
+ //g_print ("%lld %lld %lld\n", osssink->offset, buftime, gst_clock_get_time (osssink->clock));
+ osssink->offset = buftime;
+ osssink->handled = 0;
gst_element_clock_wait (GST_ELEMENT (osssink), osssink->clock, buftime);
-
- write (osssink->fd, data, size);
}
+
+ while (size) {
+ gint tosend = MIN (size, frag);
+ write (osssink->fd, data, tosend);
+ data += frag;
+ size -= frag;
+ osssink->handled += tosend;
+ }
}
+ /* no clock, try to be as fast as possible */
else {
audio_buf_info ospace;
@@ -482,6 +490,7 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf)
if (ospace.bytes >= size) {
write (osssink->fd, data, size);
}
+ osssink->handled += size;
}
}
}
@@ -675,9 +684,10 @@ gst_osssink_change_state (GstElement *element)
}
break;
case GST_STATE_READY_TO_PAUSED:
+ osssink->offset = -1LL;
break;
case GST_STATE_PAUSED_TO_PLAYING:
- gst_oss_clock_set_update (GST_OSS_CLOCK (osssink->provided_clock), TRUE);
+ //gst_clock_adjust (osssink->clock, osssink->offset - gst_clock_get_time (osssink->clock));
break;
case GST_STATE_PLAYING_TO_PAUSED:
{
@@ -685,22 +695,18 @@ gst_osssink_change_state (GstElement *element)
if (osssink->bps) {
GstClockTime time;
audio_buf_info ospace;
- count_info optr;
gint queued;
ioctl (osssink->fd, SNDCTL_DSP_GETOSPACE, &ospace);
- ioctl (osssink->fd, SNDCTL_DSP_GETOPTR, &optr);
+ ioctl (osssink->fd, SNDCTL_DSP_RESET, 0);
queued = (ospace.fragstotal * ospace.fragsize) - ospace.bytes;
- time = (optr.bytes + queued) * 1000000LL / osssink->bps;
- ioctl (osssink->fd, SNDCTL_DSP_RESET, 0);
+ time = osssink->offset + (osssink->handled - queued) * 1000000LL / osssink->bps;
- gst_oss_clock_set_update (GST_OSS_CLOCK (osssink->provided_clock), FALSE);
- gst_clock_set_time (osssink->provided_clock, time);
+ //gst_clock_adjust (osssink->clock, time - gst_clock_get_time (osssink->clock));
}
else {
ioctl (osssink->fd, SNDCTL_DSP_RESET, 0);
- gst_oss_clock_set_update (GST_OSS_CLOCK (osssink->provided_clock), FALSE);
}
}
diff --git a/sys/oss/gstosssink.h b/sys/oss/gstosssink.h
index c526cea5..9a22418f 100644
--- a/sys/oss/gstosssink.h
+++ b/sys/oss/gstosssink.h
@@ -78,6 +78,7 @@ struct _GstOssSink {
guint bufsize;
guint bps;
guint64 offset;
+ guint64 handled;
guint64 fragment_time;
};