Here's the patch I worked out following the discussion on IRC
yesterday. It includes a single retry if the initial set_state(NULL)
fails in __load_song, and some streamlining of control flow. I also
have init() bump the GStreamer default debug level from NONE to ERROR,
so that future problems of this kind will be easier to diagnose.
Patch is versus top-of-trunk -- how far off is that from what's currently
packaged for Debian?
zw
* player.py (PlaylistPlayer#__load_song): Take third 'lock'
argument. Retry initial set_state once if it fails. Call
self.error here if initial set_state fails twice in a row,
or if final set_state fails at all.
(PlaylistPlayer#__get_song): Remove try/except wrapper
around call to __load_song.
(init): Set default GStreamer debug level to LEVEL_ERROR.
===================================================================
Index: player.py
--- player.py (revision 2406)
+++ player.py (working copy)
@@ -100,14 +100,32 @@
self.info.song_started(None)
config.set("memory", "song", "")
- def __load_song(self, song):
+ def __load_song(self, song, lock):
+ # Under as-yet-undetermined conditions, the initial set_state()
+ # can mysteriously fail -- if you turn GStreamer debugging on you
+ # get diagnostics like this:
+ # alsa( 1481) gstalsa.c(1632):gst_alsa_open_audio:<alsasink0>
+ # ALSA device "default" is already in use by another program.
+ #
+ # This is believed to be a GStreamer bug. If it happens, try again
+ # after pausing a little.
st = self.bin.set_state(gst.STATE_NULL)
- if st != gst.STATE_SUCCESS: raise Exception(st)
+ if st != gst.STATE_SUCCESS:
+ import time
+ time.sleep(0.01)
+ st = self.bin.set_state(gst.STATE_NULL)
+ if st != gst.STATE_SUCCESS:
+ # FIXME: feed self.error a useful error message
+ # (and do something sensible with it in SongWatcher#error)
+ self.error('', lock)
+ return
+
self.bin.set_property('uri', song("~uri"))
self.__length = song["~#length"] * 1000
if self.__paused: st = self.bin.set_state(gst.STATE_PAUSED)
else: st = self.bin.set_state(gst.STATE_PLAYING)
- if st != gst.STATE_SUCCESS: raise Exception(st)
+ if st != gst.STATE_SUCCESS:
+ self.error('', lock)
def quit(self):
self.bin.set_state(gst.STATE_NULL)
@@ -135,11 +153,7 @@
self.volume = self.__volume
if song is not None:
config.set("memory", "song", song["~filename"])
- try: self.__load_song(song)
- except Exception, err:
- import traceback; traceback.print_exc()
- self.error(err, lock)
- return
+ self.__load_song(song, lock)
else:
config.set("memory", "song", "")
self.paused = True
@@ -225,6 +239,7 @@
playlist = None
def init(pipeline):
+ gst.debug_set_default_threshold(gst.LEVEL_ERROR)
if gst.element_make_from_uri(gst.URI_SRC, "file://", ""):
global playlist
playlist = PlaylistPlayer(pipeline or "gconf")
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]