Package flumotion :: Package common :: Module gstreamer
[hide private]

Source Code for Module flumotion.common.gstreamer

  1  # -*- Mode: Python; test-case-name: flumotion.test.test_common_gstreamer -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  """gstreamer helpers 
 23  """ 
 24   
 25  from twisted.internet import defer 
 26  # moving this down causes havoc when running this file directly for some reason 
 27  from flumotion.common import errors, log 
 28   
 29  import gobject 
 30  import gst 
 31   
 32  __version__ = "$Rev$" 
 33   
 34   
35 -def caps_repr(caps):
36 """ 37 Represent L{gst.Caps} as a string. 38 39 @rtype: string 40 """ 41 value = str(caps) 42 pos = value.find('streamheader') 43 if pos != -1: 44 return 'streamheader=<...>' 45 else: 46 return value
47 48
49 -def verbose_deep_notify_cb(object, orig, pspec, component):
50 """ 51 A default deep-notify signal handler for pipelines. 52 """ 53 value = orig.get_property(pspec.name) 54 if pspec.value_type == gobject.TYPE_BOOLEAN: 55 if value: 56 value = 'TRUE' 57 else: 58 value = 'FALSE' 59 output = value 60 elif pspec.value_type == gst.Caps.__gtype__: 61 output = caps_repr(value) 62 else: 63 output = value 64 65 # Filters 66 if pspec.name == 'active': 67 return 68 if pspec.name == 'caps' and output == 'None': 69 return 70 71 component.debug('%s: %s = %r', orig.get_path_string(), pspec.name, output)
72 73
74 -def element_has_property(element, property_name):
75 """ 76 Check if the given element has the given property. 77 78 @rtype: boolean 79 """ 80 try: 81 element.get_property(property_name) 82 return True 83 except TypeError: 84 return False
85 86
87 -def element_factory_has_property(element_factory, property_name):
88 """ 89 Check if the given element factory has the given property. 90 91 @rtype: boolean 92 """ 93 # FIXME: find a better way than instantiating one 94 e = gst.element_factory_make(element_factory) 95 for pspec in gobject.list_properties(e): 96 if pspec.name == property_name: 97 return True 98 return False
99 100
101 -def element_factory_has_property_value(element_factory, property_name, value):
102 """ 103 Check if the given element factory allows the given value 104 for the given property. 105 106 @rtype: boolean 107 """ 108 # FIXME: find a better way than instantiating one 109 e = gst.element_factory_make(element_factory) 110 try: 111 e.set_property(property_name, value) 112 except TypeError: 113 return False 114 115 return True
116 117
118 -def element_factory_exists(name):
119 """ 120 Check if the given element factory name exists. 121 122 @rtype: boolean 123 """ 124 registry = gst.registry_get_default() 125 factory = registry.find_feature(name, gst.TYPE_ELEMENT_FACTORY) 126 127 if factory: 128 return True 129 130 return False
131 132
133 -def get_plugin_version(plugin_name):
134 """ 135 Find the version of the given plugin. 136 137 @rtype: tuple of (major, minor, micro, nano), or None if it could not be 138 found or determined 139 """ 140 plugin = gst.registry_get_default().find_plugin(plugin_name) 141 142 if not plugin: 143 return None 144 145 versionTuple = tuple([int(x) for x in plugin.get_version().split('.')]) 146 if len(versionTuple) < 4: 147 versionTuple = versionTuple + (0, ) 148 return versionTuple
149 150 # GstPython should have something for this, but doesn't. 151 152
153 -def get_state_change(old, new):
154 table = {(gst.STATE_NULL, gst.STATE_READY): 155 gst.STATE_CHANGE_NULL_TO_READY, 156 (gst.STATE_READY, gst.STATE_PAUSED): 157 gst.STATE_CHANGE_READY_TO_PAUSED, 158 (gst.STATE_PAUSED, gst.STATE_PLAYING): 159 gst.STATE_CHANGE_PAUSED_TO_PLAYING, 160 (gst.STATE_PLAYING, gst.STATE_PAUSED): 161 gst.STATE_CHANGE_PLAYING_TO_PAUSED, 162 (gst.STATE_PAUSED, gst.STATE_READY): 163 gst.STATE_CHANGE_PAUSED_TO_READY, 164 (gst.STATE_READY, gst.STATE_NULL): 165 gst.STATE_CHANGE_READY_TO_NULL} 166 return table.get((old, new), 0)
167 168
169 -class StateChangeMonitor(dict, log.Loggable):
170
171 - def __init__(self):
172 # statechange -> [ deferred ] 173 dict.__init__(self)
174
175 - def add(self, statechange):
176 if statechange not in self: 177 self[statechange] = [] 178 179 d = defer.Deferred() 180 self[statechange].append(d) 181 182 return d
183
184 - def state_changed(self, old, new):
185 self.log('state change: pipeline %s->%s', 186 old.value_nick, new.value_nick) 187 change = get_state_change(old, new) 188 if change in self: 189 dlist = self[change] 190 for d in dlist: 191 d.callback(None) 192 del self[change]
193
194 - def have_error(self, curstate, message):
195 # if we have a state change defer that has not yet 196 # fired, we should errback it 197 changes = [gst.STATE_CHANGE_NULL_TO_READY, 198 gst.STATE_CHANGE_READY_TO_PAUSED, 199 gst.STATE_CHANGE_PAUSED_TO_PLAYING] 200 201 extras = ((gst.STATE_PAUSED, gst.STATE_CHANGE_PLAYING_TO_PAUSED), 202 (gst.STATE_READY, gst.STATE_CHANGE_PAUSED_TO_READY), 203 (gst.STATE_NULL, gst.STATE_CHANGE_READY_TO_NULL)) 204 for state, change in extras: 205 if curstate <= state: 206 changes.append(change) 207 208 for change in changes: 209 if change in self: 210 self.log("We have an error, going to errback pending " 211 "state change defers") 212 gerror, debug = message.parse_error() 213 for d in self[change]: 214 d.errback(errors.GStreamerGstError( 215 message.src, gerror, debug)) 216 del self[change]
217