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.
This commit is contained in:
Wim Taymans 2005-09-24 13:06:03 +00:00
parent 272aad79bb
commit b17856db22
8 changed files with 49 additions and 46 deletions

View file

@ -1,3 +1,19 @@
2005-09-24 Wim Taymans <wim@fluendo.com>
* 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 <thomas at apestaart dot org>
* docs/plugins/Makefile.am:

2
common

@ -1 +1 @@
Subproject commit c7160d5b7c76f00609cf7b6e9b782e99f626686c
Subproject commit 7caeee4b949b4388927fec7fcf25f767429bde30

View file

@ -707,7 +707,6 @@ gst_alsasink_delay (GstAudioSink * asink)
static void
gst_alsasink_reset (GstAudioSink * asink)
{
#if 0
GstAlsaSink *alsa;
gint err;

View file

@ -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;
}

View file

@ -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;

View file

@ -80,6 +80,9 @@ struct _GstBaseAudioSink {
GstClockTime buffer_time;
GstClockTime latency_time;
/* the next sample to write */
guint64 next_sample;
/* clock */
GstClock *clock;

View file

@ -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;

View file

@ -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;