mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
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:
parent
0c71c6348f
commit
5c17d94013
4 changed files with 90 additions and 44 deletions
11
ChangeLog
11
ChangeLog
|
@ -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:
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue