diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2002-05-28 22:52:52 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2002-05-28 22:52:52 +0000 |
commit | 40b3b23ce1fef9a5bba0175f518d94107097c591 (patch) | |
tree | 920a8d329ac1f0fc06425134dee47950fa7e8f82 /sys | |
parent | dac1353696dca0f0fdc17cb76066b0f5da96b207 (diff) |
Resurect ossclock with a simple algorithm
Original commit message from CVS:
Resurect ossclock with a simple algorithm
Diffstat (limited to 'sys')
-rw-r--r-- | sys/oss/gstossclock.c | 58 | ||||
-rw-r--r-- | sys/oss/gstossclock.h | 3 | ||||
-rw-r--r-- | sys/oss/gstosssink.c | 80 | ||||
-rw-r--r-- | sys/oss/gstosssink.h | 1 |
4 files changed, 108 insertions, 34 deletions
diff --git a/sys/oss/gstossclock.c b/sys/oss/gstossclock.c index bd1bf8e7..5171c086 100644 --- a/sys/oss/gstossclock.c +++ b/sys/oss/gstossclock.c @@ -92,34 +92,48 @@ gst_oss_clock_new (gchar *name, GstOssClockGetTimeFunc func, gpointer user_data) return oss_clock; } -static GstClockTime -gst_oss_clock_get_internal_time (GstClock *clock) +void +gst_oss_clock_set_active (GstClock *clock, gboolean active) { - GTimeVal timeval; - GstClockTime time1; - GstClockTime time2; - GstClockTimeDiff diff1, diff2; GstOssClock *oss_clock = GST_OSS_CLOCK (clock); - + GTimeVal timeval; + GstClockTime time; + GstClockTime osstime; + 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; + time = GST_TIMEVAL_TO_TIME (timeval); + osstime = oss_clock->func (clock, oss_clock->user_data); + + if (active) { + oss_clock->adjust = time - osstime; + } + else { + oss_clock->adjust = osstime - time; } - diff1 = time1 - oss_clock->prev1; - diff2 = time2 - oss_clock->prev2; - oss_clock->prev1 = time1; - oss_clock->prev2 = time2; + oss_clock->active = active; +} + +static GstClockTime +gst_oss_clock_get_internal_time (GstClock *clock) +{ + GstOssClock *oss_clock = GST_OSS_CLOCK (clock); + + if (oss_clock->active) { + GstClockTime osstime; + + osstime = oss_clock->func (clock, oss_clock->user_data) + oss_clock->adjust; - if (diff1) { - oss_clock->adjust -= diff2 - diff1; + return osstime; + } + else { + GstClockTime time; + GTimeVal timeval; + + g_get_current_time (&timeval); + time = GST_TIMEVAL_TO_TIME (timeval); + + return time; } - /* - g_print ("diff %lld %lld %lld %lld %lld %lld\n", - diff1, diff2, time1, time2, diff2 - diff1, oss_clock->adjust); - */ - return time2 + oss_clock->adjust; } diff --git a/sys/oss/gstossclock.h b/sys/oss/gstossclock.h index e3f28325..00f2f763 100644 --- a/sys/oss/gstossclock.h +++ b/sys/oss/gstossclock.h @@ -56,6 +56,8 @@ struct _GstOssClock { GstClockTime prev1, prev2; GstClockTimeDiff adjust; + + gboolean active; }; struct _GstOssClockClass { @@ -65,6 +67,7 @@ struct _GstOssClockClass { GType gst_oss_clock_get_type (void); GstOssClock* gst_oss_clock_new (gchar *name, GstOssClockGetTimeFunc func, gpointer user_data); +void gst_oss_clock_set_active (GstClock *clock, gboolean active); #ifdef __cplusplus } diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c index 88d05616..e71bed73 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 GstClockTime gst_osssink_get_time (GstClock *clock, gpointer data); static GstPadConnectReturn gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps); @@ -249,13 +250,17 @@ gst_osssink_init (GstOssSink *osssink) osssink->sync = TRUE; /* 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_osssink_get_time, osssink)); + osssink->handled = 0; 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 gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps) { @@ -397,6 +402,59 @@ gst_osssink_sync_parms (GstOssSink *osssink) return TRUE; } +static inline gint64 +gst_osssink_get_delay (GstOssSink *osssink) +{ + gint delay = 0; + + if (ioctl (osssink->fd, SNDCTL_DSP_GETODELAY, &delay) < 0) { + audio_buf_info info; + if (ioctl (osssink->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { + delay = 0; + } + else { + delay = (info.fragstotal * info.fragsize) - info.bytes; + } + } + return delay; +} + +static GstClockTime +gst_osssink_get_time (GstClock *clock, gpointer data) +{ + GstOssSink *osssink = GST_OSSSINK (data); + gint delay; + GstClockTime res; + + if (!osssink->bps) + return 0; + + delay = gst_osssink_get_delay (osssink); + + /* sometimes delay is bigger than the number of bytes sent to the device, which screws + * up this calculation, we assume that everything is still in the device then */ + if (((guint64)delay) > osssink->handled) { + delay = osssink->handled; + } + res = (osssink->handled - delay) * GST_SECOND / osssink->bps; + + /* + g_print ("from osssink: %lld %d %lld %d\n", res, delay, osssink->handled, osssink->bps); + */ + + return res; +} + +static GstClock* +gst_osssink_get_clock (GstElement *element) +{ + GstOssSink *osssink; + + osssink = GST_OSSSINK (element); + + return GST_CLOCK (osssink->provided_clock); +} + static void gst_osssink_set_clock (GstElement *element, GstClock *clock) { @@ -418,11 +476,11 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf) if (GST_IS_EVENT (buf)) { GstEvent *event = GST_EVENT (buf); - //gint64 offset; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: ioctl (osssink->fd, SNDCTL_DSP_SYNC); + gst_oss_clock_set_active (osssink->clock, FALSE); gst_pad_event_default (pad, event); return; case GST_EVENT_NEW_MEDIA: @@ -434,7 +492,7 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf) ioctl (osssink->fd, SNDCTL_DSP_RESET); if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &value)) { - gst_clock_handle_discont (osssink->clock, value); + osssink->handled = 0; } osssink->resync = TRUE; return; @@ -464,15 +522,7 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf) gint64 queued; GstClockTimeDiff jitter; - if (ioctl (osssink->fd, SNDCTL_DSP_GETODELAY, &delay) < 0) { - audio_buf_info info; - if (ioctl (osssink->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { - delay = 0; - } - else { - delay = (info.fragstotal * info.fragsize) - info.bytes; - } - } + delay = gst_osssink_get_delay (osssink); queued = delay * GST_SECOND / osssink->bps; if (osssink->resync && osssink->sync) { @@ -480,12 +530,16 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf) buftime - queued, &jitter); if (jitter > 0) { + gst_clock_handle_discont (osssink->clock, buftime - queued + jitter); write (osssink->fd, data, size); + gst_oss_clock_set_active (osssink->provided_clock, TRUE); osssink->resync = FALSE; + osssink->handled += size; } } else { write (osssink->fd, data, size); + osssink->handled += size; } } /* no clock, try to be as fast as possible */ @@ -703,6 +757,8 @@ gst_osssink_change_state (GstElement *element) { if (GST_FLAG_IS_SET (element, GST_OSSSINK_OPEN)) ioctl (osssink->fd, SNDCTL_DSP_RESET, 0); + gst_oss_clock_set_active (osssink->provided_clock, FALSE); + osssink->resync = TRUE; break; } case GST_STATE_PAUSED_TO_READY: diff --git a/sys/oss/gstosssink.h b/sys/oss/gstosssink.h index 66bbfd78..ed5a3af3 100644 --- a/sys/oss/gstosssink.h +++ b/sys/oss/gstosssink.h @@ -65,6 +65,7 @@ struct _GstOssSink { GstClock *clock; gboolean resync; gboolean sync; + guint64 handled; /* device */ gchar *device; |