1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 GStreamer helper functionality
24 """
25
26 from twisted.internet import defer
27
28 from flumotion.common import errors, log
29
30 import gobject
31 import gst
32
34 """
35 Represent L{gst.Caps} as a string.
36
37 @rtype: string
38 """
39 value = str(caps)
40 pos = value.find('streamheader')
41 if pos != -1:
42 return 'streamheader=<...>'
43 else:
44 return value
45
47 """
48 A default deep-notify signal handler for pipelines.
49 """
50 value = orig.get_property(pspec.name)
51 if pspec.value_type == gobject.TYPE_BOOLEAN:
52 if value:
53 value = 'TRUE'
54 else:
55 value = 'FALSE'
56 output = value
57 elif pspec.value_type == gst.Caps.__gtype__:
58 output = caps_repr(value)
59 else:
60 output = value
61
62
63 if pspec.name == 'active':
64 return
65 if pspec.name == 'caps' and output == 'None':
66 return
67
68 component.debug('%s: %s = %s' % (orig.get_path_string(), pspec.name, output))
69
71 """
72 Check if the given element factory has the given property.
73
74 @rtype: boolean
75 """
76
77 e = gst.element_factory_make(element_factory)
78 for pspec in gobject.list_properties(e):
79 if pspec.name == property_name:
80 return True
81 return False
82
84 """
85 Check if the given element factory allows the given value for the given property.
86
87 @rtype: boolean
88 """
89
90 e = gst.element_factory_make(element_factory)
91 try:
92 e.set_property(property_name, value)
93 except TypeError:
94 return False
95
96 return True
97
99 """
100 Check if the given element factory name exists.
101
102 @rtype: boolean
103 """
104 registry = gst.registry_get_default()
105 factory = registry.find_feature(name, gst.TYPE_ELEMENT_FACTORY)
106
107 if factory:
108 return True
109
110 return False
111
113 """
114 Find the version of the given plugin.
115
116 @rtype: tuple of (major, minor, micro, nano), or None if it could not be
117 found or determined
118 """
119 plugin = gst.registry_get_default().find_plugin(plugin_name)
120
121 if not plugin:
122 return None
123
124 versionTuple = tuple([int(x) for x in plugin.get_version().split('.')])
125 if len(versionTuple) < 4:
126 versionTuple = versionTuple + (0,)
127 return versionTuple
128
129
131 table = {(gst.STATE_NULL, gst.STATE_READY):
132 gst.STATE_CHANGE_NULL_TO_READY,
133 (gst.STATE_READY, gst.STATE_PAUSED):
134 gst.STATE_CHANGE_READY_TO_PAUSED,
135 (gst.STATE_PAUSED, gst.STATE_PLAYING):
136 gst.STATE_CHANGE_PAUSED_TO_PLAYING,
137 (gst.STATE_PLAYING, gst.STATE_PAUSED):
138 gst.STATE_CHANGE_PLAYING_TO_PAUSED,
139 (gst.STATE_PAUSED, gst.STATE_READY):
140 gst.STATE_CHANGE_PAUSED_TO_READY,
141 (gst.STATE_READY, gst.STATE_NULL):
142 gst.STATE_CHANGE_READY_TO_NULL}
143 return table.get((old, new), 0)
144
149
150 - def add(self, statechange):
151 if statechange not in self:
152 self[statechange] = []
153
154 d = defer.Deferred()
155 self[statechange].append(d)
156
157 return d
158
160 self.log('state change: pipeline %s->%s',
161 old.value_nick, new.value_nick)
162 change = get_state_change(old, new)
163 if change in self:
164 dlist = self[change]
165 for d in dlist:
166 d.callback(None)
167 del self[change]
168
170
171
172 changes = [gst.STATE_CHANGE_NULL_TO_READY,
173 gst.STATE_CHANGE_READY_TO_PAUSED,
174 gst.STATE_CHANGE_PAUSED_TO_PLAYING]
175
176 extras = ((gst.STATE_PAUSED, gst.STATE_CHANGE_PLAYING_TO_PAUSED),
177 (gst.STATE_READY, gst.STATE_CHANGE_PAUSED_TO_READY),
178 (gst.STATE_NULL, gst.STATE_CHANGE_READY_TO_NULL))
179 for state, change in extras:
180 if curstate <= state:
181 changes.append(change)
182
183 for change in changes:
184 if change in self:
185 self.log("We have an error, going to errback pending "
186 "state change defers")
187 gerror, debug = message.parse_error()
188 for d in self[change]:
189 d.errback(errors.GStreamerGstError(
190 message.src, gerror, debug))
191 del self[change]
192