From 53b9f87436c583a9d33c9944511760da2065b5b8 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Thu, 16 Dec 2010 15:15:49 +0100 Subject: [PATCH] pulsesink: flush remaining buffered samples on EOS ... which can make a difference between all or nothing when dealing with short streams and relatively large ringbuffer segment. --- ext/pulse/pulsesink.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c index 2a9a108..796c7b7 100644 --- a/ext/pulse/pulsesink.c +++ b/ext/pulse/pulsesink.c @@ -1649,6 +1649,50 @@ write_failed: } } +/* write pending local samples, must be called with the mainloop lock */ +static void +gst_pulsering_flush (GstPulseRingBuffer * pbuf) +{ +#ifdef HAVE_PULSE_0_9_16 + GstPulseSink *psink; + + psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (pbuf)); + GST_DEBUG_OBJECT (psink, "entering flush"); + + /* flush the buffer if possible */ + if (pbuf->stream && (pbuf->m_data != NULL) && (pbuf->m_towrite > 0)) { +#ifndef GST_DISABLE_GST_DEBUG + gint bps; + + bps = (GST_RING_BUFFER_CAST (pbuf))->spec.bytes_per_sample; + GST_LOG_OBJECT (psink, + "flushing %u samples at offset %" G_GINT64_FORMAT, + (guint) pbuf->m_towrite / bps, pbuf->m_offset); +#endif + + if (pa_stream_write (pbuf->stream, (uint8_t *) pbuf->m_data, + pbuf->m_towrite, NULL, pbuf->m_offset, PA_SEEK_ABSOLUTE) < 0) { + goto write_failed; + } + + pbuf->m_towrite = 0; + pbuf->m_offset += pbuf->m_towrite; /* keep track of current offset */ + } + +done: + return; + + /* ERRORS */ +write_failed: + { + GST_ELEMENT_ERROR (psink, RESOURCE, FAILED, + ("pa_stream_write() failed: %s", + pa_strerror (pa_context_errno (pbuf->context))), (NULL)); + goto done; + } +#endif +} + static void gst_pulsesink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_pulsesink_get_property (GObject * object, guint prop_id, @@ -2579,6 +2623,34 @@ update_failed: } #endif +static void +gst_pulsesink_flush_ringbuffer (GstPulseSink * psink) +{ + GstPulseRingBuffer *pbuf; + + pa_threaded_mainloop_lock (mainloop); + + pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer); + + if (pbuf == NULL || pbuf->stream == NULL) + goto no_buffer; + + gst_pulsering_flush (pbuf); + + /* We're not interested if this operation failed or not */ +unlock: + pa_threaded_mainloop_unlock (mainloop); + + return; + + /* ERRORS */ +no_buffer: + { + GST_DEBUG_OBJECT (psink, "we have no ringbuffer"); + goto unlock; + } +} + static gboolean gst_pulsesink_event (GstBaseSink * sink, GstEvent * event) { @@ -2626,6 +2698,9 @@ gst_pulsesink_event (GstBaseSink * sink, GstEvent * event) break; } + case GST_EVENT_EOS: + gst_pulsesink_flush_ringbuffer (pulsesink); + break; default: ; } -- 2.7.4