From 5c17d9401337f47d1a3149799e67f86367ca5074 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 11 Oct 2005 18:32:01 +0000 Subject: [PATCH] gst-libs/gst/audio/: Cleanups. Original commit message from CVS: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_create): * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_commit), (gst_ring_buffer_read): Cleanups. Commit and read from ringbuffer in samples rather than bytes. --- ChangeLog | 11 +++++++ gst-libs/gst/audio/gstbaseaudiosink.c | 57 ++++++++++++++++++++++++++-------- gst-libs/gst/audio/gstbaseaudiosrc.c | 8 +++-- gst-libs/gst/audio/gstringbuffer.c | 58 ++++++++++++++++++----------------- 4 files changed, 90 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 702f32d..3e513ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,17 @@ * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): + * gst-libs/gst/audio/gstbaseaudiosrc.c: + (gst_base_audio_src_create): + * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_commit), + (gst_ring_buffer_read): + Cleanups. + Commit and read from ringbuffer in samples rather than bytes. + +2005-10-11 Wim Taymans + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_render): Respect segment rate and accum when scheduling samples. 2005-10-11 Julien MOUTTE diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 1fc7957..69ecda2 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -340,21 +340,36 @@ static GstFlowReturn gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) { guint64 render_offset, in_offset; - GstClockTime time, render_time; + GstClockTime time, render_time, duration; GstClockTimeDiff render_diff; - GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (bsink); + GstBaseAudioSink *sink; + GstRingBuffer *ringbuf; gint64 diff; guint8 *data; guint size; + guint samples; + gint bps; + + sink = GST_BASE_AUDIO_SINK (bsink); + + ringbuf = sink->ringbuffer; /* can't do anything when we don't have the device */ - if (!gst_ring_buffer_is_acquired (sink->ringbuffer)) + if (!gst_ring_buffer_is_acquired (ringbuf)) goto wrong_state; + bps = ringbuf->spec.bytes_per_sample; + + size = GST_BUFFER_SIZE (buf); + if (size % bps != 0) + goto wrong_size; + + samples = size / bps; + in_offset = GST_BUFFER_OFFSET (buf); time = GST_BUFFER_TIMESTAMP (buf); + duration = GST_BUFFER_DURATION (buf); data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); GST_DEBUG ("time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT, GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment_start)); @@ -376,34 +391,42 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) /* add base time to get absolute clock time */ render_time += gst_element_get_base_time (GST_ELEMENT (bsink)); /* and bring the time to the offset in the buffer */ - render_offset = render_time * sink->ringbuffer->spec.rate / GST_SECOND; + render_offset = render_time * ringbuf->spec.rate / GST_SECOND; /* roundoff errors in timestamp conversion */ if (sink->next_sample != -1) diff = ABS ((gint64) render_offset - (gint64) sink->next_sample); else - diff = sink->ringbuffer->spec.rate; + diff = ringbuf->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); + ", render offset %llu, diff %lld, samples %lu", + GST_TIME_ARGS (render_time), render_offset, diff, samples); /* 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 / DIFF_TOLERANCE) { + if (diff < ringbuf->spec.rate / DIFF_TOLERANCE) { GST_DEBUG ("align with prev sample, %" G_GINT64_FORMAT " < %lu", diff, - sink->ringbuffer->spec.rate / DIFF_TOLERANCE); + ringbuf->spec.rate / DIFF_TOLERANCE); /* just align with previous sample then */ render_offset = sink->next_sample; } else { GST_DEBUG ("resync"); } - gst_ring_buffer_commit (sink->ringbuffer, render_offset, data, size); + + /* clip length based on rate */ + samples /= ABS (bsink->segment_rate); /* the next sample should be current sample and its length */ - sink->next_sample = - render_offset + size / sink->ringbuffer->spec.bytes_per_sample; + sink->next_sample = render_offset + samples; + + gst_ring_buffer_commit (ringbuf, render_offset, data, samples); + + if (time + duration >= bsink->segment_stop) { + GST_DEBUG ("start playback because we are at the end of segment"); + gst_ring_buffer_start (ringbuf); + } return GST_FLOW_OK; @@ -414,6 +437,14 @@ wrong_state: ("sink not negotiated."), ("sink not negotiated.")); return GST_FLOW_NOT_NEGOTIATED; } +wrong_size: + { + GST_DEBUG ("wrong size"); + GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, + ("sink received buffer of wrong size."), + ("sink received buffer of wrong size.")); + return GST_FLOW_ERROR; + } } GstRingBuffer * diff --git a/gst-libs/gst/audio/gstbaseaudiosrc.c b/gst-libs/gst/audio/gstbaseaudiosrc.c index 0dc25ad..a579eee 100644 --- a/gst-libs/gst/audio/gstbaseaudiosrc.c +++ b/gst-libs/gst/audio/gstbaseaudiosrc.c @@ -308,7 +308,7 @@ gst_base_audio_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (psrc); GstBuffer *buf; guchar *data; - guint len; + guint len, samples; guint res; guint64 sample; @@ -326,11 +326,13 @@ gst_base_audio_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) sample = 0; } - res = gst_ring_buffer_read (src->ringbuffer, sample, data, len); + samples = len / src->ringbuffer->spec.bytes_per_sample; + + res = gst_ring_buffer_read (src->ringbuffer, sample, data, samples); if (res == -1) goto stopped; - src->next_sample = sample + len / src->ringbuffer->spec.bytes_per_sample; + src->next_sample = sample + samples; gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc))); diff --git a/gst-libs/gst/audio/gstringbuffer.c b/gst-libs/gst/audio/gstringbuffer.c index daa1027..274d326 100644 --- a/gst-libs/gst/audio/gstringbuffer.c +++ b/gst-libs/gst/audio/gstringbuffer.c @@ -904,7 +904,7 @@ not_started: * @buf: the #GstRingBuffer to commit * @sample: the sample position of the data * @data: the data to commit - * @len: the length of the data to commit + * @len: the number of samples in the data to commit * * Commit @len samples pointed to by @data to the ringbuffer * @buf. The first sample should be written at position @sample in @@ -936,15 +936,15 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data, bps = buf->spec.bytes_per_sample; sps = buf->samples_per_seg; - /* write out all bytes */ + /* write out all samples */ while (len > 0) { - gint writelen; - gint writeseg, writeoff; + gint sampleslen; + gint writeseg, sampleoff; /* figure out the segment and the offset inside the segment where * the sample should be written. */ writeseg = sample / sps; - writeoff = (sample % sps) * bps; + sampleoff = (sample % sps); while (TRUE) { gint diff; @@ -957,13 +957,13 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data, GST_DEBUG ("pointer at %d, sample %llu, write to %d-%d, len %d, diff %d, segtotal %d, segsize %d", - segdone, sample, writeseg, writeoff, len, diff, segtotal, segsize); + segdone, sample, writeseg, sampleoff, len, diff, segtotal, sps); /* segment too far ahead, we need to drop */ if (diff < 0) { /* we need to drop one segment at a time, pretend we wrote a * segment. */ - writelen = MIN (segsize, len); + sampleslen = MIN (sps, len); goto next; } @@ -979,17 +979,18 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data, /* we can write now */ writeseg = writeseg % segtotal; - writelen = MIN (segsize - writeoff, len); + sampleslen = MIN (sps - sampleoff, len); GST_DEBUG ("write @%p seg %d, off %d, len %d", - dest + writeseg * segsize, writeseg, writeoff, writelen); + dest + writeseg * segsize, writeseg, sampleoff, sampleslen); - memcpy (dest + writeseg * segsize + writeoff, data, writelen); + memcpy (dest + (writeseg * segsize) + (sampleoff * bps), data, + (sampleslen * bps)); next: - len -= writelen; - data += writelen; - sample += writelen / bps; + len -= sampleslen; + sample += sampleslen; + data += sampleslen * bps; } return len; @@ -1007,9 +1008,9 @@ not_started: * @buf: the #GstRingBuffer to read from * @sample: the sample position of the data * @data: where the data should be read - * @len: the length of the data to read + * @len: the number of samples in data to read * - * Read @length samples from the ringbuffer into the memory pointed + * Read @len samples from the ringbuffer into the memory pointed * to by @data. * The first sample should be read from position @sample in * the ringbuffer. @@ -1040,15 +1041,15 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data, bps = buf->spec.bytes_per_sample; sps = buf->samples_per_seg; - /* read enough bytes */ + /* read enough samples */ while (len > 0) { - gint readlen; - gint readseg, readoff; + gint sampleslen; + gint readseg, sampleoff; /* figure out the segment and the offset inside the segment where * the sample should be written. */ readseg = sample / sps; - readoff = (sample % sps) * bps; + sampleoff = (sample % sps); while (TRUE) { gint diff; @@ -1061,14 +1062,14 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data, GST_DEBUG ("pointer at %d, sample %llu, read from %d-%d, len %d, diff %d, segtotal %d, segsize %d", - segdone, sample, readseg, readoff, len, diff, segtotal, segsize); + segdone, sample, readseg, sampleoff, len, diff, segtotal, segsize); /* segment too far ahead, we need to drop */ if (diff < 0) { /* we need to drop one segment at a time, pretend we read an * empty segment. */ - readlen = MIN (segsize, len); - memcpy (data, buf->empty_seg, readlen); + sampleslen = MIN (sps, len); + memcpy (data, buf->empty_seg, sampleslen * bps); goto next; } @@ -1084,17 +1085,18 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data, /* we can read now */ readseg = readseg % segtotal; - readlen = MIN (segsize - readoff, len); + sampleslen = MIN (sps - sampleoff, len); GST_DEBUG ("read @%p seg %d, off %d, len %d", - dest + readseg * segsize, readseg, readoff, readlen); + dest + readseg * segsize, readseg, sampleoff, sampleslen); - memcpy (data, dest + readseg * segsize + readoff, readlen); + memcpy (data, dest + (readseg * segsize) + (sampleoff * bps), + (sampleslen * bps)); next: - len -= readlen; - data += readlen; - sample += readlen / bps; + len -= sampleslen; + sample += sampleslen; + data += sampleslen * bps; } return len; -- 2.7.4