From 356244e3be7940e9d5b07825c8ac7ce13bd6546a Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Sat, 30 Oct 2010 12:09:28 -0400 Subject: [PATCH] Gstreamer locking Locking for gstreamer operations may help prevent a double free error I was getting. --- libsaria/music/audio.py | 109 +++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 19 deletions(-) diff --git a/libsaria/music/audio.py b/libsaria/music/audio.py index 1e888426..9256a69e 100644 --- a/libsaria/music/audio.py +++ b/libsaria/music/audio.py @@ -1,7 +1,9 @@ # Bryan Schumaker (8/7/2010) import libsaria +from libsaria import threads +lock = threads.get_mutex("gstreamer") gst = None player = None time = None @@ -13,22 +15,30 @@ def init(): global gst global player global time + global lock import gst + lock.acquire() player = gst.element_factory_make("playbin2", "player") - set_volume(libsaria.prefs["volume"]) + set_volume_locked(libsaria.prefs["volume"]) time = gst.Format(gst.FORMAT_TIME) bus = player.get_bus() bus.add_signal_watch() bus.connect("message", on_message) + lock.release() - -def reset(): +def reset_locked(): global player global length player.set_state(gst.STATE_NULL) length = None +def reset(): + global lock + lock.acquire() + reset_locked() + lock.release() + def on_message(bus, message): if message.type == gst.MESSAGE_EOS: @@ -36,22 +46,31 @@ def on_message(bus, message): def on_quit(): - global player - player.set_state(gst.STATE_NULL) + global lock + lock.acquire() + reset_locked() + lock.release() libsaria.event.invite("PREQUIT", on_quit) -def get_state(): +def get_state_locked(): global player return player.get_state()[1] +def get_state(): + global lock + lock.acquire() + state = get_state_locked() + lock.release() + return state + # Returns the length of the song in ms -def duration(): +def duration_locked(): global length global player global time - if get_state() == gst.STATE_NULL: + if get_state_locked() == gst.STATE_NULL: return 0 if length == None: try: @@ -60,11 +79,18 @@ def duration(): length = 0 return float(length) +def duration(): + global lock + lock.acquire() + ret = duration_locked() + lock.release() + return ret -def position(): + +def position_locked(): global time global player - if get_state() == gst.STATE_NULL: + if get_state_locked() == gst.STATE_NULL: return float(0) try: pos = player.query_position(time)[0] @@ -72,46 +98,91 @@ def position(): pos = 0 return float(pos) +def position(): + global lock + lock.acquire() + ret = position_locked() + lock.release() + return ret -def load(file): + +def load_locked(file): global gst global player - reset() + reset_locked() #player.set_state(gst.STATE_NULL) player.set_property("uri", "file://%s"%file) player.set_state(gst.STATE_PAUSED) return file +def load(file): + global lock + lock.acquire() + ret = load_locked(file) + lock.release() + return ret -def play(): + +def play_locked(): global gst global player player.set_state(gst.STATE_PLAYING) +def play(): + global lock + lock.acquire() + play_locked() + lock.release() -def pause(): + +def pause_locked(): global gst global player player.set_state(gst.STATE_PAUSED) +def pause(): + global lock + lock.acquire() + pause_locked() + lock.release() + +def stop_locked(): + pause_locked() + seek_locked(0) + def stop(): - pause() - seek(0) + global lock + lock.acquire() + stop_locked() + lock.release() -def seek(prcnt): +def seek_locked(prcnt): global player global time global gst try: - spot = duration() * prcnt + spot = duration_locked() * prcnt player.seek_simple(time, gst.SEEK_FLAG_FLUSH, spot) except: pass +def seek(prcnt): + global lock + lock.acquire() + seek_locked(prcnt) + lock.release() -def set_volume(prcnt): + +def set_volume_locked(prcnt): global player player.set_property("volume", prcnt) libsaria.prefs["volume"] = prcnt return prcnt + +def set_volume(prcnt): + global lock + lock.acquire() + ret = set_volume_locked(prcnt) + lock.release() + return ret