GNOME Bugzilla – Bug 437652
GStreamer network elements block in state change function
Last modified: 2007-09-08 21:06:18 UTC
The Playbin element blocks the GUI and MainLoop when changing its state to PAUSE or PLAY on some URIs. I attached a test code to reproduce the problem. The code has a good stream (self.__nice_stream) that works. And a bad stream (self.__bad_stream) that exposes the problem. You can change these streams in the self.__play_uri() method. To run the code, type python test.py File test.py ======================================================================== class MyPlayBin(object): def __init__(self): self.__init_attributes() self.__arrange_widgets() self.__window.connect("delete-event", self.__delete_event_cb) self.__play_button.connect("clicked", self.__clicked_play_button_cb) self.__stop_button.connect("clicked", self.__clicked_stop_button_cb) self.__window.show_all() def __init_attributes(self): self.__bad_stream = "http://66.250.45.118:7204" self.__nice_stream = "http://scfire-ntc0l-2.stream.aol.com:80/stream/1074" from gst import element_factory_make self.__element = element_factory_make("playbin", "MainPipeline") self.__bus = self.__element.get_bus() self.__bus.add_signal_watch() self.__bus.connect("message::buffering", self.__buffering_cb) from gtk import Window, Label, Button from gtk import STOCK_MEDIA_PLAY, STOCK_MEDIA_PAUSE self.__label = Label("READY") self.__play_button = Button(stock=STOCK_MEDIA_PLAY) self.__stop_button = Button(stock=STOCK_MEDIA_PAUSE) self.__window = Window() return def __play_uri(self): self.__stop() self.__label.set_text("Preparing to play") from gst import STATE_PAUSED self.__element.set_property("uri", self.__bad_stream) self.__element.set_state(STATE_PAUSED) return False def __stop(self): from gst import STATE_NULL, STATE_READY self.__element.set_state(STATE_READY) self.__element.set_state(STATE_NULL) self.__label.set_text("Paused") return def __buffering_cb(self, bus, data): from gst import STATE_PAUSED, STATE_PLAYING percentage = data.structure["buffer-percent"] if percentage == 100: self.__element.set_state(STATE_PLAYING) self.__label.set_text("Playing") else: self.__element.set_state(STATE_PAUSED) message = "%s buffering..." % percentage self.__label.set_text(message) return def __arrange_widgets(self): self.__window.set_title("MyPlayBin") self.__window.set_border_width(10) from gtk import VBox, HBox vbox = VBox(spacing=10) hbox = HBox(spacing=20) self.__window.add(vbox) vbox.pack_start(self.__label, True, True, 0) vbox.pack_start(hbox) hbox.pack_start(self.__play_button, True, True, 0) hbox.pack_start(self.__stop_button, True, True, 0) return def __clicked_play_button_cb(self, *args): self.__play_uri() return False def __clicked_stop_button_cb(self, *args): self.__stop() return False def __delete_event_cb(self, *args): raise SystemExit return True if __name__ == "__main__": from gobject import threads_init, MainLoop threads_init() MyPlayBin() MainLoop().run() ========================================================================
Created attachment 88000 [details] test file
This bug is probably a duplicate of bug #338827.
It's really a general problem with most of our networking elements I'm afraid (also those not using gnomevfssrc). There's unlikely to be a quick fix for this. Even if we didn't block on the upwards state change by putting the blocking stuff into the streaming thread, you'd still have the problem that shutting down the pipeline (e.g. when the user clicks 'next') will block until the blocking call in the streaming thread has finished. Also see bug #403122 for the mmssrc case. gnomevfssrc is unlikely to get fixed at this point, but there's going to be a new gvfssrc at some point when the new GVFS lands in GLib. Marking as duplicate of #338827 for now, since that's the most important networking element besides mmssrc and there's a different bug for mmsssrc *** This bug has been marked as a duplicate of 338827 ***