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