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.
This commit is contained in:
Wim Taymans 2005-10-11 18:32:01 +00:00
parent 0c71c6348f
commit 5c17d94013
4 changed files with 90 additions and 44 deletions

View file

@ -1,3 +1,14 @@
2005-10-11 Wim Taymans <wim@fluendo.com>
* 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 <wim@fluendo.com> 2005-10-11 Wim Taymans <wim@fluendo.com>
* gst-libs/gst/audio/gstbaseaudiosink.c: * gst-libs/gst/audio/gstbaseaudiosink.c:

View file

@ -340,21 +340,36 @@ static GstFlowReturn
gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{ {
guint64 render_offset, in_offset; guint64 render_offset, in_offset;
GstClockTime time, render_time; GstClockTime time, render_time, duration;
GstClockTimeDiff render_diff; GstClockTimeDiff render_diff;
GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (bsink); GstBaseAudioSink *sink;
GstRingBuffer *ringbuf;
gint64 diff; gint64 diff;
guint8 *data; guint8 *data;
guint size; 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 */ /* 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; 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); in_offset = GST_BUFFER_OFFSET (buf);
time = GST_BUFFER_TIMESTAMP (buf); time = GST_BUFFER_TIMESTAMP (buf);
duration = GST_BUFFER_DURATION (buf);
data = GST_BUFFER_DATA (buf); data = GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf);
GST_DEBUG ("time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT, GST_DEBUG ("time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT,
GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment_start)); 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 */ /* add base time to get absolute clock time */
render_time += gst_element_get_base_time (GST_ELEMENT (bsink)); render_time += gst_element_get_base_time (GST_ELEMENT (bsink));
/* and bring the time to the offset in the buffer */ /* 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 */ /* roundoff errors in timestamp conversion */
if (sink->next_sample != -1) if (sink->next_sample != -1)
diff = ABS ((gint64) render_offset - (gint64) sink->next_sample); diff = ABS ((gint64) render_offset - (gint64) sink->next_sample);
else else
diff = sink->ringbuffer->spec.rate; diff = ringbuf->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, samples %lu",
render_offset, diff, size); GST_TIME_ARGS (render_time), render_offset, diff, samples);
/* 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 / DIFF_TOLERANCE) { if (diff < ringbuf->spec.rate / DIFF_TOLERANCE) {
GST_DEBUG ("align with prev sample, %" G_GINT64_FORMAT " < %lu", diff, 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 */ /* just align with previous sample then */
render_offset = sink->next_sample; render_offset = sink->next_sample;
} else { } else {
GST_DEBUG ("resync"); 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 */ /* the next sample should be current sample and its length */
sink->next_sample = sink->next_sample = render_offset + samples;
render_offset + size / sink->ringbuffer->spec.bytes_per_sample;
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; return GST_FLOW_OK;
@ -414,6 +437,14 @@ wrong_state:
("sink not negotiated."), ("sink not negotiated.")); ("sink not negotiated."), ("sink not negotiated."));
return GST_FLOW_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 * GstRingBuffer *

View file

@ -308,7 +308,7 @@ gst_base_audio_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (psrc); GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (psrc);
GstBuffer *buf; GstBuffer *buf;
guchar *data; guchar *data;
guint len; guint len, samples;
guint res; guint res;
guint64 sample; guint64 sample;
@ -326,11 +326,13 @@ gst_base_audio_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
sample = 0; 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) if (res == -1)
goto stopped; 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))); gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));

View file

@ -904,7 +904,7 @@ not_started:
* @buf: the #GstRingBuffer to commit * @buf: the #GstRingBuffer to commit
* @sample: the sample position of the data * @sample: the sample position of the data
* @data: the data to commit * @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 * Commit @len samples pointed to by @data to the ringbuffer
* @buf. The first sample should be written at position @sample in * @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; bps = buf->spec.bytes_per_sample;
sps = buf->samples_per_seg; sps = buf->samples_per_seg;
/* write out all bytes */ /* write out all samples */
while (len > 0) { while (len > 0) {
gint writelen; gint sampleslen;
gint writeseg, writeoff; gint writeseg, sampleoff;
/* figure out the segment and the offset inside the segment where /* figure out the segment and the offset inside the segment where
* the sample should be written. */ * the sample should be written. */
writeseg = sample / sps; writeseg = sample / sps;
writeoff = (sample % sps) * bps; sampleoff = (sample % sps);
while (TRUE) { while (TRUE) {
gint diff; gint diff;
@ -957,13 +957,13 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
GST_DEBUG GST_DEBUG
("pointer at %d, sample %llu, write to %d-%d, len %d, diff %d, segtotal %d, segsize %d", ("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 */ /* segment too far ahead, we need to drop */
if (diff < 0) { if (diff < 0) {
/* we need to drop one segment at a time, pretend we wrote a /* we need to drop one segment at a time, pretend we wrote a
* segment. */ * segment. */
writelen = MIN (segsize, len); sampleslen = MIN (sps, len);
goto next; goto next;
} }
@ -979,17 +979,18 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
/* we can write now */ /* we can write now */
writeseg = writeseg % segtotal; writeseg = writeseg % segtotal;
writelen = MIN (segsize - writeoff, len); sampleslen = MIN (sps - sampleoff, len);
GST_DEBUG ("write @%p seg %d, off %d, len %d", 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: next:
len -= writelen; len -= sampleslen;
data += writelen; sample += sampleslen;
sample += writelen / bps; data += sampleslen * bps;
} }
return len; return len;
@ -1007,9 +1008,9 @@ not_started:
* @buf: the #GstRingBuffer to read from * @buf: the #GstRingBuffer to read from
* @sample: the sample position of the data * @sample: the sample position of the data
* @data: where the data should be read * @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. * to by @data.
* The first sample should be read from position @sample in * The first sample should be read from position @sample in
* the ringbuffer. * the ringbuffer.
@ -1040,15 +1041,15 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
bps = buf->spec.bytes_per_sample; bps = buf->spec.bytes_per_sample;
sps = buf->samples_per_seg; sps = buf->samples_per_seg;
/* read enough bytes */ /* read enough samples */
while (len > 0) { while (len > 0) {
gint readlen; gint sampleslen;
gint readseg, readoff; gint readseg, sampleoff;
/* figure out the segment and the offset inside the segment where /* figure out the segment and the offset inside the segment where
* the sample should be written. */ * the sample should be written. */
readseg = sample / sps; readseg = sample / sps;
readoff = (sample % sps) * bps; sampleoff = (sample % sps);
while (TRUE) { while (TRUE) {
gint diff; gint diff;
@ -1061,14 +1062,14 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
GST_DEBUG GST_DEBUG
("pointer at %d, sample %llu, read from %d-%d, len %d, diff %d, segtotal %d, segsize %d", ("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 */ /* segment too far ahead, we need to drop */
if (diff < 0) { if (diff < 0) {
/* we need to drop one segment at a time, pretend we read an /* we need to drop one segment at a time, pretend we read an
* empty segment. */ * empty segment. */
readlen = MIN (segsize, len); sampleslen = MIN (sps, len);
memcpy (data, buf->empty_seg, readlen); memcpy (data, buf->empty_seg, sampleslen * bps);
goto next; goto next;
} }
@ -1084,17 +1085,18 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
/* we can read now */ /* we can read now */
readseg = readseg % segtotal; readseg = readseg % segtotal;
readlen = MIN (segsize - readoff, len); sampleslen = MIN (sps - sampleoff, len);
GST_DEBUG ("read @%p seg %d, off %d, len %d", 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: next:
len -= readlen; len -= sampleslen;
data += readlen; sample += sampleslen;
sample += readlen / bps; data += sampleslen * bps;
} }
return len; return len;