mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-20 13:28:21 +00:00
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:
parent
272aad79bb
commit
b17856db22
16
ChangeLog
16
ChangeLog
|
@ -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>
|
2005-09-23 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
* docs/plugins/Makefile.am:
|
* docs/plugins/Makefile.am:
|
||||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit c7160d5b7c76f00609cf7b6e9b782e99f626686c
|
Subproject commit 7caeee4b949b4388927fec7fcf25f767429bde30
|
|
@ -707,7 +707,6 @@ gst_alsasink_delay (GstAudioSink * asink)
|
||||||
static void
|
static void
|
||||||
gst_alsasink_reset (GstAudioSink * asink)
|
gst_alsasink_reset (GstAudioSink * asink)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
GstAlsaSink *alsa;
|
GstAlsaSink *alsa;
|
||||||
gint err;
|
gint err;
|
||||||
|
|
|
@ -132,6 +132,7 @@ gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass)
|
||||||
gstringbuffer_class->release =
|
gstringbuffer_class->release =
|
||||||
GST_DEBUG_FUNCPTR (gst_audioringbuffer_release);
|
GST_DEBUG_FUNCPTR (gst_audioringbuffer_release);
|
||||||
gstringbuffer_class->start = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
|
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->resume = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
|
||||||
gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop);
|
gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop);
|
||||||
|
|
||||||
|
@ -172,9 +173,9 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
|
||||||
|
|
||||||
left = len;
|
left = len;
|
||||||
do {
|
do {
|
||||||
GST_DEBUG ("transfer %d bytes from segment %d", left, readseg);
|
|
||||||
written = writefunc (sink, readptr + written, left);
|
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) {
|
if (written < 0 || written > left) {
|
||||||
GST_WARNING ("error writing data (reason: %s), skipping segment\n",
|
GST_WARNING ("error writing data (reason: %s), skipping segment\n",
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
|
@ -393,7 +394,7 @@ gst_audioringbuffer_stop (GstRingBuffer * buf)
|
||||||
|
|
||||||
GST_DEBUG ("stop, waiting...");
|
GST_DEBUG ("stop, waiting...");
|
||||||
GST_AUDIORING_BUFFER_WAIT (buf);
|
GST_AUDIORING_BUFFER_WAIT (buf);
|
||||||
GST_DEBUG ("stoped");
|
GST_DEBUG ("stopped");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,11 @@ enum
|
||||||
LAST_SIGNAL
|
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_BUFFER_TIME 500 * GST_USECOND
|
||||||
#define DEFAULT_LATENCY_TIME 10 * GST_USECOND
|
#define DEFAULT_LATENCY_TIME 10 * GST_USECOND
|
||||||
enum
|
enum
|
||||||
|
@ -296,6 +301,9 @@ gst_base_audio_sink_event (GstBaseSink * bsink, GstEvent * event)
|
||||||
gst_ring_buffer_clear_all (sink->ringbuffer);
|
gst_ring_buffer_clear_all (sink->ringbuffer);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
|
/* always resync on sample after a flush */
|
||||||
|
sink->next_sample = -1;
|
||||||
|
gst_ring_buffer_clear_all (sink->ringbuffer);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
break;
|
break;
|
||||||
|
@ -366,24 +374,31 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
render_offset = render_time * sink->ringbuffer->spec.rate / GST_SECOND;
|
render_offset = render_time * sink->ringbuffer->spec.rate / GST_SECOND;
|
||||||
|
|
||||||
/* roundoff errors in timestamp conversion */
|
/* 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
|
GST_DEBUG ("render time %" GST_TIME_FORMAT
|
||||||
", render offset %llu, diff %lld, size %lu", GST_TIME_ARGS (render_time),
|
", render offset %llu, diff %lld, size %lu", GST_TIME_ARGS (render_time),
|
||||||
render_offset, diff, size);
|
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
|
/* 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
|
* should be enough to compensate for various rounding errors in the timestamp
|
||||||
* and sample offset position. */
|
* 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 */
|
/* just align with previous sample then */
|
||||||
render_offset = -1;
|
render_offset = sink->next_sample;
|
||||||
/* FIXME, can we use the OFFSET field to detect a gap? */
|
} 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_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;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
@ -435,6 +450,7 @@ gst_base_audio_sink_change_state (GstElement * element,
|
||||||
}
|
}
|
||||||
if (!gst_ring_buffer_open_device (sink->ringbuffer))
|
if (!gst_ring_buffer_open_device (sink->ringbuffer))
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
|
sink->next_sample = 0;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -80,6 +80,9 @@ struct _GstBaseAudioSink {
|
||||||
GstClockTime buffer_time;
|
GstClockTime buffer_time;
|
||||||
GstClockTime latency_time;
|
GstClockTime latency_time;
|
||||||
|
|
||||||
|
/* the next sample to write */
|
||||||
|
guint64 next_sample;
|
||||||
|
|
||||||
/* clock */
|
/* clock */
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
|
|
||||||
|
|
|
@ -727,8 +727,6 @@ gst_ring_buffer_stop (GstRingBuffer * buf)
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
buf->state = GST_RING_BUFFER_STATE_STARTED;
|
buf->state = GST_RING_BUFFER_STATE_STARTED;
|
||||||
} else {
|
|
||||||
gst_ring_buffer_set_sample (buf, 0);
|
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
GST_UNLOCK (buf);
|
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
|
* position, round down to the beginning and keep track of
|
||||||
* offset when calculating the processed samples. */
|
* offset when calculating the processed samples. */
|
||||||
buf->segbase = buf->segdone - sample / buf->samples_per_seg;
|
buf->segbase = buf->segdone - sample / buf->samples_per_seg;
|
||||||
buf->next_sample = sample;
|
|
||||||
|
|
||||||
gst_ring_buffer_clear_all (buf);
|
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 != NULL);
|
||||||
g_return_if_fail (buf->spec.segtotal > 0);
|
g_return_if_fail (buf->spec.segtotal > 0);
|
||||||
|
|
||||||
|
GST_DEBUG ("clear all segments");
|
||||||
|
|
||||||
for (i = 0; i < buf->spec.segtotal; i++) {
|
for (i = 0; i < buf->spec.segtotal; i++) {
|
||||||
gst_ring_buffer_clear (buf, 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 (buf->data != NULL, -1);
|
||||||
g_return_val_if_fail (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);
|
dest = GST_BUFFER_DATA (buf->data);
|
||||||
segsize = buf->spec.segsize;
|
segsize = buf->spec.segsize;
|
||||||
segtotal = buf->spec.segtotal;
|
segtotal = buf->spec.segtotal;
|
||||||
bps = buf->spec.bytes_per_sample;
|
bps = buf->spec.bytes_per_sample;
|
||||||
sps = buf->samples_per_seg;
|
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 */
|
/* write out all bytes */
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
gint writelen;
|
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 (buf->data != NULL, -1);
|
||||||
g_return_val_if_fail (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);
|
dest = GST_BUFFER_DATA (buf->data);
|
||||||
segsize = buf->spec.segsize;
|
segsize = buf->spec.segsize;
|
||||||
segtotal = buf->spec.segtotal;
|
segtotal = buf->spec.segtotal;
|
||||||
bps = buf->spec.bytes_per_sample;
|
bps = buf->spec.bytes_per_sample;
|
||||||
sps = buf->samples_per_seg;
|
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 */
|
/* read enough bytes */
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
gint readlen;
|
gint readlen;
|
||||||
|
|
|
@ -169,7 +169,6 @@ struct _GstRingBuffer {
|
||||||
gint waiting; /* when waiting for a segment to be freed */
|
gint waiting; /* when waiting for a segment to be freed */
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
guint64 next_sample; /* the next sample we need to process */
|
|
||||||
GstRingBufferCallback callback;
|
GstRingBufferCallback callback;
|
||||||
gpointer cb_data;
|
gpointer cb_data;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue