python, appsrc, min-percent for need-data ignored

Jan Martinek honza at dp.fce.vutbr.cz
Mon Jun 5 10:58:30 UTC 2017


Hi everyone,

at first, I would like to thank Nicolas Dufresne for his help in my 
previous post - for some reason I am unable to reply to his post.

Anyway, I ported my waveform-playing script to gstreamer-1.0. It works - 
I can compute bytes and send them to the sound card. But the signal 
'need-data' is raised when only last 4096 bytes are present in the 
queue. Therefore, I need to take care of the data every 23 milliseconds:
4096/(44100*4) = 0.02322 s
In the meantime I want to plot a graph, which takes more time, the 
buffer runs out of data and ugly jittering results.

The default queue size of appsrc is 200000, which is fine, but never 
used. The signal 'need-data' could be called when the queue size is half 
full

min-percent=50

but the "min-percent" parameter is ignored and "current-level-bytes" is 
always zero (empty queue).

Is it a bug? The example script line 42 can safely be removed.

Thank you
Jan Martinek

--------
#!/usr/bin/python

import gi, signal, struct, time
gi.require_version('Gst', '1.0')
gi.require_version('Gtk', '3.0')
from gi.repository import GObject,Gtk
from gi.repository import Gst
from math import sin, pi

GObject.threads_init()
Gst.init(None)


class Sound:
     def __init__(self):
         self.samplecounter = 0
         signal.signal(signal.SIGINT, signal.SIG_DFL)
         self.player = Gst.parse_launch('''appsrc name=source 
min-percent=50 ! capsfilter 
caps=audio/x-raw,rate=44100,channels=2,format=S16LE ! pulsesink''')
         playersrc = self.player.get_by_name('source')
         playersrc.connect('need-data', self.needdata)
         self.player.set_state(Gst.State.PLAYING)
         Gtk.main()


     def sinuswave(self, nbytes):
         data = ''
         mul1 = 2*pi*440/44100
         mul2 = 2*pi*442/44100
         for i in range(nbytes//4):
             data += struct.pack('hh',
             32767*sin(self.samplecounter*mul1),
             32767*sin(self.samplecounter*mul2))
             self.samplecounter += 1
         return data

     def needdata(self, src, length):
         print "current-level-bytes", 
src.get_property("current-level-bytes")
         print "min-percent", src.get_property("min-percent")
         data = self.sinuswave(length)
         print len(data), length
         src.emit('push-buffer', Gst.Buffer.new_wrapped(data))
         time.sleep(0.02322) # REMOVE ME TO GET A NICE SOUND

sa = Sound()


More information about the gstreamer-devel mailing list