Switch to event probe based solution to removing outputs.

Based on http://lists.freedesktop.org/archives/gstreamer-devel/2009-August/023708.html
This commit is contained in:
Thomas Adamcik 2011-05-17 01:21:50 +02:00
parent 82bd77e24b
commit 801b3d1155

View File

@ -285,18 +285,38 @@ class GStreamer(ThreadingActor):
def remove_output(self, output):
if output not in self._outputs:
return # FIXME raise mopidy exception of some sort?
src = output.get_pad('sink').get_peer()
src.set_blocked_async(True, self._blocked_callback, output)
teesrc = output.get_pad('sink').get_peer()
handler = teesrc.add_event_probe(self._handle_event_probe)
def _blocked_callback(self, pad, blocked, output):
gst.element_unlink_many(self._tee, output)
pad.set_blocked_async(False, self._unblocked_callback, output)
struct = gst.Structure('mopidy-unlink-tee')
struct.set_value('handler', handler)
def _unblocked_callback(self, pad, blocked, output):
output.set_state(gst.STATE_NULL)
self._pipeline.remove(output)
self._outputs.remove(output)
logger.warning(u'Removed %s', output.get_name())
event = gst.event_new_custom(gst.EVENT_CUSTOM_DOWNSTREAM, struct)
self._tee.send_event(event)
def _handle_event_probe(self, teesrc, event):
if event.type == gst.EVENT_CUSTOM_DOWNSTREAM and event.has_name('mopidy-unlink-tee'):
data = self._get_structure_data(event.get_structure())
output = teesrc.get_peer().get_parent()
teesrc.unlink(teesrc.get_peer())
teesrc.remove_event_probe(data['handler'])
output.set_state(gst.STATE_NULL)
self._pipeline.remove(output)
logger.warning('Removed %s', output.get_name())
return False
return True
def _get_structure_data(self, struct):
# Ugly hack to get around missing get_value in pygst bindings :/
data = {}
def get_data(key, value):
data[key] = value
struct.foreach(get_data)
return data
def connect_message_handler(self, element, handler):
self._handlers[element] = handler