mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-04 09:42:19 +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
8 changed files with 49 additions and 46 deletions
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>
|
||||
|
||||
* 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
|
||||
gst_alsasink_reset (GstAudioSink * asink)
|
||||
{
|
||||
|
||||
#if 0
|
||||
GstAlsaSink *alsa;
|
||||
gint err;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -80,6 +80,9 @@ struct _GstBaseAudioSink {
|
|||
GstClockTime buffer_time;
|
||||
GstClockTime latency_time;
|
||||
|
||||
/* the next sample to write */
|
||||
guint64 next_sample;
|
||||
|
||||
/* clock */
|
||||
GstClock *clock;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue