1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """gstreamer helpers
23 """
24
25 from twisted.internet import defer
26
27 from flumotion.common import errors, log
28
29 import gobject
30 import gst
31
32 __version__ = "$Rev: 7162 $"
33
34
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
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
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
75 """
76 Check if the given element factory has the given property.
77
78 @rtype: boolean
79 """
80
81 e = gst.element_factory_make(element_factory)
82 for pspec in gobject.list_properties(e):
83 if pspec.name == property_name:
84 return True
85 return False
86
87
89 """
90 Check if the given element factory allows the given value
91 for the given property.
92
93 @rtype: boolean
94 """
95
96 e = gst.element_factory_make(element_factory)
97 try:
98 e.set_property(property_name, value)
99 except TypeError:
100 return False
101
102 return True
103
104
106 """
107 Check if the given element factory name exists.
108
109 @rtype: boolean
110 """
111 registry = gst.registry_get_default()
112 factory = registry.find_feature(name, gst.TYPE_ELEMENT_FACTORY)
113
114 if factory:
115 return True
116
117 return False
118
119
121 """
122 Find the version of the given plugin.
123
124 @rtype: tuple of (major, minor, micro, nano), or None if it could not be
125 found or determined
126 """
127 plugin = gst.registry_get_default().find_plugin(plugin_name)
128
129 if not plugin:
130 return None
131
132 versionTuple = tuple([int(x) for x in plugin.get_version().split('.')])
133 if len(versionTuple) < 4:
134 versionTuple = versionTuple + (0, )
135 return versionTuple
136
137
138
139
141 table = {(gst.STATE_NULL, gst.STATE_READY):
142 gst.STATE_CHANGE_NULL_TO_READY,
143 (gst.STATE_READY, gst.STATE_PAUSED):
144 gst.STATE_CHANGE_READY_TO_PAUSED,
145 (gst.STATE_PAUSED, gst.STATE_PLAYING):
146 gst.STATE_CHANGE_PAUSED_TO_PLAYING,
147 (gst.STATE_PLAYING, gst.STATE_PAUSED):
148 gst.STATE_CHANGE_PLAYING_TO_PAUSED,
149 (gst.STATE_PAUSED, gst.STATE_READY):
150 gst.STATE_CHANGE_PAUSED_TO_READY,
151 (gst.STATE_READY, gst.STATE_NULL):
152 gst.STATE_CHANGE_READY_TO_NULL}
153 return table.get((old, new), 0)
154
155
157
161
162 - def add(self, statechange):
163 if statechange not in self:
164 self[statechange] = []
165
166 d = defer.Deferred()
167 self[statechange].append(d)
168
169 return d
170
172 self.log('state change: pipeline %s->%s',
173 old.value_nick, new.value_nick)
174 change = get_state_change(old, new)
175 if change in self:
176 dlist = self[change]
177 for d in dlist:
178 d.callback(None)
179 del self[change]
180
182
183
184 changes = [gst.STATE_CHANGE_NULL_TO_READY,
185 gst.STATE_CHANGE_READY_TO_PAUSED,
186 gst.STATE_CHANGE_PAUSED_TO_PLAYING]
187
188 extras = ((gst.STATE_PAUSED, gst.STATE_CHANGE_PLAYING_TO_PAUSED),
189 (gst.STATE_READY, gst.STATE_CHANGE_PAUSED_TO_READY),
190 (gst.STATE_NULL, gst.STATE_CHANGE_READY_TO_NULL))
191 for state, change in extras:
192 if curstate <= state:
193 changes.append(change)
194
195 for change in changes:
196 if change in self:
197 self.log("We have an error, going to errback pending "
198 "state change defers")
199 gerror, debug = message.parse_error()
200 for d in self[change]:
201 d.errback(errors.GStreamerGstError(
202 message.src, gerror, debug))
203 del self[change]
204