GNOME Bugzilla – Bug 510705
Core dump when calling add_singal_watch on a pipeline with gnonlin from within a function.
Last modified: 2008-01-21 12:49:53 UTC
# To run this program, first call this command in another window # gst-launch tcpserversrc host=127.0.0.1 port=3000 ! mad ! alsasink # You will likely need to copy a file into the current working directory # called file1.mp3. Next run this program with python. You should here # the first few seconds of that mp3 files played streamed to the gst-launch # command you ran earlier. # The body of playStream and the else branch at the bottom are identical. # Toggling the use_func flag will cause the program to use the function # or the else clause as its stream. Set the flag to True and rerun the # gst-launch command and also this program and you will see a core dump # and the following message: # play_stream.py:72: Warning: invalid unclassed pointer in cast to `GstBaseSrc' # It is odd to me that this should work from the else clause but not # from a function. Also I notice that if you comment out the call to # bus.add_signal_watch() in the function body it works as well. # I'm sorry the code is so long but I couldn't manage to reduce this anymore. # It's really a pretty quirky bug. import gobject import pygst pygst.require("0.10") import gst use_func = False def playStream (): pipeline = gst.Pipeline() adder = gst.element_factory_make("adder") lame = gst.element_factory_make("lame") tcpclientsink = gst.element_factory_make("tcpclientsink") tcpclientsink.set_property("host", "127.0.0.1") tcpclientsink.set_property("port", 3000) pipeline.add(adder, lame, tcpclientsink) gst.element_link_many(adder, lame, tcpclientsink) comp = gst.element_factory_make("gnlcomposition") compconvert = gst.element_factory_make("audioconvert") pipeline.add(comp, compconvert) def OnPad (comp, pad): convpad = compconvert.get_compatible_pad(pad, pad.get_caps()) pad.link(convpad) comp.connect("pad-added", OnPad) acsrcpad = compconvert.get_pad('src') addersinkpad = adder.get_request_pad('sink%d') acsrcpad.link(addersinkpad) audio = gst.element_factory_make("gnlfilesource") comp.add(audio) audio.set_property("location", "file1.mp3") audio.set_property("start", 0 * gst.SECOND) audio.set_property("duration", 3 * gst.SECOND) audio.set_property("media-start", 0 * gst.SECOND) audio.set_property("media-duration", 3 * gst.SECOND) pipeline.set_state(gst.STATE_PLAYING) bus = pipeline.get_bus() bus.add_signal_watch() if use_func: playStream() else: pipeline = gst.Pipeline() adder = gst.element_factory_make("adder") lame = gst.element_factory_make("lame") tcpclientsink = gst.element_factory_make("tcpclientsink") tcpclientsink.set_property("host", "127.0.0.1") tcpclientsink.set_property("port", 3000) pipeline.add(adder, lame, tcpclientsink) gst.element_link_many(adder, lame, tcpclientsink) comp = gst.element_factory_make("gnlcomposition") compconvert = gst.element_factory_make("audioconvert") pipeline.add(comp, compconvert) def OnPad (comp, pad): convpad = compconvert.get_compatible_pad(pad, pad.get_caps()) pad.link(convpad) comp.connect("pad-added", OnPad) acsrcpad = compconvert.get_pad('src') addersinkpad = adder.get_request_pad('sink%d') acsrcpad.link(addersinkpad) audio = gst.element_factory_make("gnlfilesource") comp.add(audio) audio.set_property("location", "file1.mp3") audio.set_property("start", 0 * gst.SECOND) audio.set_property("duration", 3 * gst.SECOND) audio.set_property("media-start", 0 * gst.SECOND) audio.set_property("media-duration", 3 * gst.SECOND) pipeline.set_state(gst.STATE_PLAYING) bus = pipeline.get_bus() bus.add_signal_watch() gobject.MainLoop().run()
the reference to the pipeline gets dropped when you exit that function, since only you have a reference to it. Once you exit the function, the only reference to the pipeline will be dropped, and it will be freed. Keep a reference to the pipeline, and everything will work correctly. for example do this at the beginning: pipeline = None def playStream (): global pipeline pipeline = gst.Pipeline() ...