gst-libs/gst/audio/gstaudiosink.c: Implement pause that does not wait for completion.

Original commit message from CVS:
* gst-libs/gst/audio/gstaudiosink.c:
(gst_audioringbuffer_class_init), (gst_audioringbuffer_release),
(gst_audioringbuffer_pause):
Implement pause that does not wait for completion.

* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
Don't drop buffers when going to PAUSED but perform preroll on
remaining samples now that core base class supports this.

* gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_release),
(gst_ring_buffer_pause_unlocked), (gst_ring_buffer_stop),
(gst_ring_buffer_commit):
Pause should not signal waiters.
Implement return value of _commit correctly.
This commit is contained in:
Wim Taymans 2006-01-30 16:19:33 +00:00
parent 0ad84fae5d
commit a169abc679
5 changed files with 86 additions and 17 deletions

View file

@ -1,3 +1,21 @@
2006-01-30 Wim Taymans <wim@fluendo.com>
* gst-libs/gst/audio/gstaudiosink.c:
(gst_audioringbuffer_class_init), (gst_audioringbuffer_release),
(gst_audioringbuffer_pause):
Implement pause that does not wait for completion.
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
Don't drop buffers when going to PAUSED but perform preroll on
remaining samples now that core base class supports this.
* gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_release),
(gst_ring_buffer_pause_unlocked), (gst_ring_buffer_stop),
(gst_ring_buffer_commit):
Pause should not signal waiters.
Implement return value of _commit correctly.
2006-01-30 Andy Wingo <wingo@pobox.com>
* tests/check/Makefile.am (check_vorbis): Add pipelines/vorbisenc.

2
common

@ -1 +1 @@
Subproject commit bc4325349e8d0ec90aa5c5e74566880cc2e82527
Subproject commit 0b93085188e83fe678ec5ded2823cd7c24dfa843

View file

@ -77,6 +77,7 @@ static gboolean gst_audioringbuffer_acquire (GstRingBuffer * buf,
GstRingBufferSpec * spec);
static gboolean gst_audioringbuffer_release (GstRingBuffer * buf);
static gboolean gst_audioringbuffer_start (GstRingBuffer * buf);
static gboolean gst_audioringbuffer_pause (GstRingBuffer * buf);
static gboolean gst_audioringbuffer_stop (GstRingBuffer * buf);
static guint gst_audioringbuffer_delay (GstRingBuffer * buf);
@ -132,7 +133,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->pause = GST_DEBUG_FUNCPTR (gst_audioringbuffer_pause);
gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop);
@ -348,6 +349,7 @@ gst_audioringbuffer_release (GstRingBuffer * buf)
abuf = GST_AUDIORING_BUFFER (buf);
abuf->running = FALSE;
GST_DEBUG ("signal wait");
GST_AUDIORING_BUFFER_SIGNAL (buf);
GST_OBJECT_UNLOCK (buf);
@ -388,6 +390,25 @@ gst_audioringbuffer_start (GstRingBuffer * buf)
return TRUE;
}
static gboolean
gst_audioringbuffer_pause (GstRingBuffer * buf)
{
GstAudioSink *sink;
GstAudioSinkClass *csink;
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
csink = GST_AUDIO_SINK_GET_CLASS (sink);
/* unblock any pending writes to the audio device */
if (csink->reset) {
GST_DEBUG ("reset...");
csink->reset (sink);
GST_DEBUG ("reset done");
}
return TRUE;
}
static gboolean
gst_audioringbuffer_stop (GstRingBuffer * buf)
{

View file

@ -406,7 +406,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
gint64 diff, ctime, cstop;
guint8 *data;
guint size;
guint samples;
guint samples, written;
gint bps;
gdouble crate = 1.0;
GstClockTime crate_num;
@ -458,6 +458,8 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
* arriving before the segment.start or after segment.stop are to be
* thrown away. All samples should also be clipped to the segment
* boundaries */
/* let's calc stop based on the number of samples in the buffer instead
* of trusting the DURATION */
stop =
time + gst_util_uint64_scale_int (samples, GST_SECOND,
ringbuf->spec.rate);
@ -536,7 +538,27 @@ no_sync:
/* the next sample should be current sample and its length */
sink->next_sample = render_offset + samples;
samples = gst_ring_buffer_commit (ringbuf, render_offset, data, samples);
do {
written = gst_ring_buffer_commit (ringbuf, render_offset, data, samples);
GST_DEBUG_OBJECT (sink, "wrote %u of %u", written, samples);
/* if we wrote all, we're done */
if (written == samples)
break;
/* else something interrupted us */
GST_DEBUG_OBJECT (sink, "wait for preroll...");
bsink->have_preroll = TRUE;
GST_PAD_PREROLL_WAIT (bsink->sinkpad);
bsink->have_preroll = FALSE;
GST_DEBUG_OBJECT (sink, "preroll done");
if (G_UNLIKELY (bsink->flushing))
goto stopping;
GST_DEBUG_OBJECT (sink, "continue after preroll");
render_offset += written;
samples -= written;
data += written * bps;
} while (TRUE);
if (GST_CLOCK_TIME_IS_VALID (stop) && stop >= bsink->segment.stop) {
GST_DEBUG_OBJECT (sink,
@ -569,6 +591,11 @@ wrong_size:
("sink received buffer of wrong size."));
return GST_FLOW_ERROR;
}
stopping:
{
GST_DEBUG_OBJECT (sink, "ringbuffer is stopping");
return GST_FLOW_WRONG_STATE;
}
}
GstRingBuffer *
@ -644,6 +671,9 @@ gst_base_audio_sink_change_state (GstElement * element,
GST_OBJECT_UNLOCK (sink);
break;
}
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
gst_ring_buffer_pause (sink->ringbuffer);
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
gst_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
break;
@ -655,7 +685,6 @@ gst_base_audio_sink_change_state (GstElement * element,
switch (transition) {
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
gst_ring_buffer_pause (sink->ringbuffer);
/* slop slaving ourselves to the master, if any */
gst_clock_set_master (sink->provided_clock, NULL);
break;

View file

@ -654,6 +654,7 @@ gst_ring_buffer_release (GstRingBuffer * buf)
res = rclass->release (buf);
/* signal any waiters */
GST_DEBUG_OBJECT (buf, "signal waiter");
GST_RING_BUFFER_SIGNAL (buf);
if (!res)
@ -820,9 +821,6 @@ gst_ring_buffer_pause_unlocked (GstRingBuffer * buf)
goto done;
}
/* signal any waiters */
GST_RING_BUFFER_SIGNAL (buf);
rclass = GST_RING_BUFFER_GET_CLASS (buf);
if (rclass->pause)
res = rclass->pause (buf);
@ -906,6 +904,7 @@ gst_ring_buffer_stop (GstRingBuffer * buf)
}
/* signal any waiters */
GST_DEBUG_OBJECT (buf, "signal waiter");
GST_RING_BUFFER_SIGNAL (buf);
rclass = GST_RING_BUFFER_GET_CLASS (buf);
@ -1127,6 +1126,7 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
gint segdone;
gint segsize, segtotal, bps, sps;
guint8 *dest;
guint to_write;
g_return_val_if_fail (buf != NULL, -1);
g_return_val_if_fail (buf->data != NULL, -1);
@ -1138,8 +1138,9 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
bps = buf->spec.bytes_per_sample;
sps = buf->samples_per_seg;
to_write = len;
/* write out all samples */
while (len > 0) {
while (to_write > 0) {
gint sampleslen;
gint writeseg, sampleoff;
@ -1158,14 +1159,14 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
diff = writeseg - segdone;
GST_DEBUG
("pointer at %d, sample %llu, write to %d-%d, len %d, diff %d, segtotal %d, segsize %d",
segdone, sample, writeseg, sampleoff, len, diff, segtotal, sps);
("pointer at %d, sample %llu, write to %d-%d, to_write %d, diff %d, segtotal %d, segsize %d",
segdone, sample, writeseg, sampleoff, to_write, 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. */
sampleslen = MIN (sps, len);
sampleslen = MIN (sps, to_write);
goto next;
}
@ -1181,27 +1182,27 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
/* we can write now */
writeseg = writeseg % segtotal;
sampleslen = MIN (sps - sampleoff, len);
sampleslen = MIN (sps - sampleoff, to_write);
GST_DEBUG_OBJECT (buf, "write @%p seg %d, off %d, len %d",
GST_DEBUG_OBJECT (buf, "write @%p seg %d, off %d, sampleslen %d",
dest + writeseg * segsize, writeseg, sampleoff, sampleslen);
memcpy (dest + (writeseg * segsize) + (sampleoff * bps), data,
(sampleslen * bps));
next:
len -= sampleslen;
to_write -= sampleslen;
sample += sampleslen;
data += sampleslen * bps;
}
return len;
return len - to_write;
/* ERRORS */
not_started:
{
GST_DEBUG_OBJECT (buf, "stopped processing");
return -1;
return len - to_write;
}
}