From b17856db2218267bd71096b874b9ccb975b82919 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sat, 24 Sep 2005 13:06:03 +0000 Subject: [PATCH] Fix sync again. Moved sample alignment to basesink. Original commit message from CVS: * ext/alsa/gstalsasink.c: (gst_alsasink_reset): * gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_class_init), (audioringbuffer_thread_func), (gst_audioringbuffer_stop): * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event), (gst_base_audio_sink_render), (gst_base_audio_sink_change_state): * gst-libs/gst/audio/gstbaseaudiosink.h: * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_stop), (gst_ring_buffer_set_sample), (gst_ring_buffer_clear_all), (gst_ring_buffer_commit), (gst_ring_buffer_read): * gst-libs/gst/audio/gstringbuffer.h: Fix sync again. Moved sample alignment to basesink. --- ChangeLog | 16 ++++++++++++ common | 2 +- ext/alsa/gstalsasink.c | 1 - gst-libs/gst/audio/gstaudiosink.c | 7 +++--- gst-libs/gst/audio/gstbaseaudiosink.c | 30 +++++++++++++++++------ gst-libs/gst/audio/gstbaseaudiosink.h | 3 +++ gst-libs/gst/audio/gstringbuffer.c | 35 ++------------------------- gst-libs/gst/audio/gstringbuffer.h | 1 - 8 files changed, 49 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index c947851250..4754d261b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-09-24 Wim Taymans + + * ext/alsa/gstalsasink.c: (gst_alsasink_reset): + * gst-libs/gst/audio/gstaudiosink.c: + (gst_audioringbuffer_class_init), (audioringbuffer_thread_func), + (gst_audioringbuffer_stop): + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_event), (gst_base_audio_sink_render), + (gst_base_audio_sink_change_state): + * gst-libs/gst/audio/gstbaseaudiosink.h: + * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_stop), + (gst_ring_buffer_set_sample), (gst_ring_buffer_clear_all), + (gst_ring_buffer_commit), (gst_ring_buffer_read): + * gst-libs/gst/audio/gstringbuffer.h: + Fix sync again. Moved sample alignment to basesink. + 2005-09-23 Thomas Vander Stichele * docs/plugins/Makefile.am: diff --git a/common b/common index c7160d5b7c..7caeee4b94 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit c7160d5b7c76f00609cf7b6e9b782e99f626686c +Subproject commit 7caeee4b949b4388927fec7fcf25f767429bde30 diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c index 11c33ecd6a..6e5d5b49ed 100644 --- a/ext/alsa/gstalsasink.c +++ b/ext/alsa/gstalsasink.c @@ -707,7 +707,6 @@ gst_alsasink_delay (GstAudioSink * asink) static void gst_alsasink_reset (GstAudioSink * asink) { - #if 0 GstAlsaSink *alsa; gint err; diff --git a/gst-libs/gst/audio/gstaudiosink.c b/gst-libs/gst/audio/gstaudiosink.c index 74ae5652eb..0ead35c240 100644 --- a/gst-libs/gst/audio/gstaudiosink.c +++ b/gst-libs/gst/audio/gstaudiosink.c @@ -132,6 +132,7 @@ gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass) gstringbuffer_class->release = GST_DEBUG_FUNCPTR (gst_audioringbuffer_release); gstringbuffer_class->start = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start); + gstringbuffer_class->pause = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop); gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start); gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop); @@ -172,9 +173,9 @@ audioringbuffer_thread_func (GstRingBuffer * buf) left = len; do { - GST_DEBUG ("transfer %d bytes from segment %d", left, readseg); written = writefunc (sink, readptr + written, left); - GST_DEBUG ("transfered %d bytes", written); + GST_DEBUG ("transfered %d bytes of %d from segment %d", written, left, + readseg); if (written < 0 || written > left) { GST_WARNING ("error writing data (reason: %s), skipping segment\n", strerror (errno)); @@ -393,7 +394,7 @@ gst_audioringbuffer_stop (GstRingBuffer * buf) GST_DEBUG ("stop, waiting..."); GST_AUDIORING_BUFFER_WAIT (buf); - GST_DEBUG ("stoped"); + GST_DEBUG ("stopped"); return TRUE; } diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 28bc4c8d2f..88921fbd9b 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -34,6 +34,11 @@ enum LAST_SIGNAL }; +/* we tollerate a 10th of a second diff before we start resyncing. This + * should be enough to compensate for various rounding errors in the timestamp + * and sample offset position. */ +#define DIFF_TOLERANCE 10 + #define DEFAULT_BUFFER_TIME 500 * GST_USECOND #define DEFAULT_LATENCY_TIME 10 * GST_USECOND enum @@ -296,6 +301,9 @@ gst_base_audio_sink_event (GstBaseSink * bsink, GstEvent * event) gst_ring_buffer_clear_all (sink->ringbuffer); break; case GST_EVENT_FLUSH_STOP: + /* always resync on sample after a flush */ + sink->next_sample = -1; + gst_ring_buffer_clear_all (sink->ringbuffer); break; case GST_EVENT_EOS: break; @@ -366,24 +374,31 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) render_offset = render_time * sink->ringbuffer->spec.rate / GST_SECOND; /* roundoff errors in timestamp conversion */ - diff = ABS ((gint64) render_offset - (gint64) sink->ringbuffer->next_sample); + if (sink->next_sample != -1) + diff = ABS ((gint64) render_offset - (gint64) sink->next_sample); + else + diff = sink->ringbuffer->spec.rate; GST_DEBUG ("render time %" GST_TIME_FORMAT ", render offset %llu, diff %lld, size %lu", GST_TIME_ARGS (render_time), render_offset, diff, size); - GST_DEBUG ("ringgbuffer rate %lu", sink->ringbuffer->spec.rate); /* we tollerate a 10th of a second diff before we start resyncing. This * should be enough to compensate for various rounding errors in the timestamp * and sample offset position. */ - if (diff < sink->ringbuffer->spec.rate / 10) { + if (diff < sink->ringbuffer->spec.rate / DIFF_TOLERANCE) { + GST_DEBUG ("align with prev sample, %" G_GINT64_FORMAT " < %lu", diff, + sink->ringbuffer->spec.rate / DIFF_TOLERANCE); /* just align with previous sample then */ - render_offset = -1; - /* FIXME, can we use the OFFSET field to detect a gap? */ + render_offset = sink->next_sample; + } else { + GST_DEBUG ("resync"); } - //GST_DEBUG ("ringgbuffer next (before) %llu", sink->ringbuffer->next_sample); gst_ring_buffer_commit (sink->ringbuffer, render_offset, data, size); - //GST_DEBUG ("ringgbuffer next (after) %llu", sink->ringbuffer->next_sample); + + /* the next sample should be current sample and its length */ + sink->next_sample = + render_offset + size / sink->ringbuffer->spec.bytes_per_sample; return GST_FLOW_OK; @@ -435,6 +450,7 @@ gst_base_audio_sink_change_state (GstElement * element, } if (!gst_ring_buffer_open_device (sink->ringbuffer)) return GST_STATE_CHANGE_FAILURE; + sink->next_sample = 0; break; case GST_STATE_CHANGE_READY_TO_PAUSED: break; diff --git a/gst-libs/gst/audio/gstbaseaudiosink.h b/gst-libs/gst/audio/gstbaseaudiosink.h index edbd1a09d2..86d8fe3f9d 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.h +++ b/gst-libs/gst/audio/gstbaseaudiosink.h @@ -80,6 +80,9 @@ struct _GstBaseAudioSink { GstClockTime buffer_time; GstClockTime latency_time; + /* the next sample to write */ + guint64 next_sample; + /* clock */ GstClock *clock; diff --git a/gst-libs/gst/audio/gstringbuffer.c b/gst-libs/gst/audio/gstringbuffer.c index 029a4d1e9a..e5d149c114 100644 --- a/gst-libs/gst/audio/gstringbuffer.c +++ b/gst-libs/gst/audio/gstringbuffer.c @@ -727,8 +727,6 @@ gst_ring_buffer_stop (GstRingBuffer * buf) if (!res) { buf->state = GST_RING_BUFFER_STATE_STARTED; - } else { - gst_ring_buffer_set_sample (buf, 0); } done: GST_UNLOCK (buf); @@ -834,7 +832,6 @@ gst_ring_buffer_set_sample (GstRingBuffer * buf, guint64 sample) * position, round down to the beginning and keep track of * offset when calculating the processed samples. */ buf->segbase = buf->segdone - sample / buf->samples_per_seg; - buf->next_sample = sample; gst_ring_buffer_clear_all (buf); @@ -857,6 +854,8 @@ gst_ring_buffer_clear_all (GstRingBuffer * buf) g_return_if_fail (buf != NULL); g_return_if_fail (buf->spec.segtotal > 0); + GST_DEBUG ("clear all segments"); + for (i = 0; i < buf->spec.segtotal; i++) { gst_ring_buffer_clear (buf, i); } @@ -928,28 +927,12 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data, g_return_val_if_fail (buf->data != NULL, -1); g_return_val_if_fail (data != NULL, -1); - if (sample == -1) { - /* process aligned with last sample */ - sample = buf->next_sample; - } else { - if (sample != buf->next_sample) { - GST_WARNING ("discontinuity found got %" G_GUINT64_FORMAT - ", expected %" G_GUINT64_FORMAT, sample, buf->next_sample); - /* also sync here */ - sample = buf->next_sample; - } - } - dest = GST_BUFFER_DATA (buf->data); segsize = buf->spec.segsize; segtotal = buf->spec.segtotal; bps = buf->spec.bytes_per_sample; sps = buf->samples_per_seg; - /* we assume the complete buffer will be consumed and the next sample - * should be written after this */ - buf->next_sample = sample + len / bps; - /* write out all bytes */ while (len > 0) { gint writelen; @@ -1048,26 +1031,12 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data, g_return_val_if_fail (buf->data != NULL, -1); g_return_val_if_fail (data != NULL, -1); - if (sample == -1) { - /* process aligned with last sample */ - sample = buf->next_sample; - } else { - if (sample != buf->next_sample) { - GST_WARNING ("discontinuity found got %" G_GUINT64_FORMAT - ", expected %" G_GUINT64_FORMAT, sample, buf->next_sample); - } - } - dest = GST_BUFFER_DATA (buf->data); segsize = buf->spec.segsize; segtotal = buf->spec.segtotal; bps = buf->spec.bytes_per_sample; sps = buf->samples_per_seg; - /* we assume the complete buffer will be consumed and the next sample - * should be written after this */ - buf->next_sample = sample + len / bps; - /* read enough bytes */ while (len > 0) { gint readlen; diff --git a/gst-libs/gst/audio/gstringbuffer.h b/gst-libs/gst/audio/gstringbuffer.h index 13058d4ac3..955db07037 100644 --- a/gst-libs/gst/audio/gstringbuffer.h +++ b/gst-libs/gst/audio/gstringbuffer.h @@ -169,7 +169,6 @@ struct _GstRingBuffer { gint waiting; /* when waiting for a segment to be freed */ /*< private >*/ - guint64 next_sample; /* the next sample we need to process */ GstRingBufferCallback callback; gpointer cb_data;