Problem with EOS signal
Séb
sebastien.fenet at yahoo.fr
Sun Mar 8 15:42:21 PDT 2015
Hi all,
I've started using GStreamer (with Python) quite recently (I'm a newbie).
>From what I've seen, GST is a great tool! However, I'm having a little
issue. Maybe I'm doing something the wrong way (documentation on the Python
API is hard to find...).
My use-case is the following: I feed a pipeline in pull-mode with audio data
from my application (thanks to the appsrc element) and I output this on the
soundcard (thanks to autoaudiosink). When I'm done with the feeding, I emit
an "end-of-stream" to the appsrc. From what I understood, this EOS should be
serialized with the data, go through all elements and when it's done, the
pipeline should send an EOS message to the bus.
The problem I have is that I get the EOS signal on the bus a little "too
early". What I mean is that I get the signal when the soundcard is still
playing the end of the buffers I sent. I tried to measure the time shift and
it's about 250 ms.... The consequence, of course, is that if I shut down the
pipeline when getting the EOS signal, I'm missing the last bits of my audio
data. I have investigated this for quite a while but I can't figure out why
it's doing this. If anyone could enlighten me, I would be very grateful.
For more clarity, here is what I do to build the pipeline :
self._pipeline = gst.parse_launch('''
appsrc name=appsrc !
audio/x-raw-float, rate=%i, width=64,
depth=64, channels=%i, signed=true, endianness=BYTE_ORDER !
audioconvert !
autoaudiosink ''' % (self.sr,
self.data.shape[1]))
appsrc = self._pipeline.get_by_name('appsrc')
appsrc.connect('need-data', self._send_buf)
self.main_loop = gobject.MainLoop()
bus = self._pipeline.get_bus()
bus.add_watch(self._message)
gobject.threads_init()
Then I have a method that starts the pipeline:
def play():
self._pipeline.set_state(gst.STATE_PLAYING)
self.main_loop.run()
self._pipeline.set_state(gst.STATE_NULL)
And here is what I do when I feed the data, with the initial 'if' statement
happening when we're reaching the end:
def _send_buf(self, src, bufsize_bytes):
if self._cursor > self._cursor_end:
src.emit('end-of-stream')
return True
element_size = self.data.nbytes / self.data.size #in Bytes
length = bufsize_bytes / (element_size*self.data.shape[1])
buf = self.data[self._cursor: min(self._cursor+length,
self._cursor_end+1), :]
src.emit("push-buffer", gst.Buffer(buf.reshape(buf.size)))
self._cursor += length
return True
And finally, I catch the EOS signal on the pipeline's bus:
def _message(self, bus, msg):
if msg.type == gst.MESSAGE_EOS:
self.main_loop.quit()
return True
Since I'm a new user (of both Python and Gstreamer), I hope I didn't code
too many awful things. Still, this code ends the main loop a little too soon
and my audio data are cut at the end (around 250ms).
Thanks in advance.
Best,
Sébastien.
--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Problem-with-EOS-signal-tp4671057.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
More information about the gstreamer-devel
mailing list