gstlal 1.13.0
Loading...
Searching...
No Matches
pipeutil.py
Go to the documentation of this file.
1# Copyright (C) 2010 Leo Singer
2#
3# This program is free software; you can redistribute it and/or modify it
4# under the terms of the GNU General Public License as published by the
5# Free Software Foundation; either version 2 of the License, or (at your
6# option) any later version.
7#
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11# Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along
14# with this program; if not, write to the Free Software Foundation, Inc.,
15# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
17
18
19
20"""
21
22Boilerplate code, shorthand, and utility functions for creating GStreamer
23elements and pipelines.
24
25"""
26__author__ = "Leo Singer <leo.singer@ligo.org>"
27__organization__ = ["LIGO", "California Institute of Technology"]
28__copyright__ = "Copyright 2010, Leo Singer"
29__all__ = ["gstlal_element_register", "mkelem", "mkelems_in_bin", "splice"]
30
31
32# The following snippet is taken from http://gstreamer.freedesktop.org/wiki/FAQ#Mypygstprogramismysteriouslycoredumping.2Chowtofixthis.3F
33import gi
34gi.require_version('Gst', '1.0')
35from gi.repository import GObject
36from gi.repository import Gst
37GObject.threads_init()
38Gst.init(None)
39
40
41def gstlal_element_register(clazz):
42 """Class decorator for registering a Python element. Note that decorator
43 syntax was extended from functions to classes in Python 2.6, so until 2.6
44 becomes the norm we have to invoke this as a function instead of by
45 saying::
46
47 @gstlal_element_register
48 class foo(Gst.Element):
49 ...
50
51 Until then, you have to do::
52
53 class foo(Gst.Element):
54 ...
55 gstlal_element_register(foo)
56 """
57 from inspect import getmodule
58 GObject.type_register(clazz) # MOD: Found type_register in line: [ gobject.type_register(clazz)]
59 getmodule(clazz).__gstelementfactory__ = (clazz.__name__, Gst.RANK_NONE, clazz)
60 return clazz
61
62
63def mkelem(elemname, props={}):
64 """Instantiate an element named elemname and optionally set some of its
65 properties from the dictionary props."""
66 elem = Gst.ElementFactory.make(elemname, None)
67 for (k, v) in props.iteritems():
68 elem.set_property(k, v)
69 return elem
70
71
72def mkelems_in_bin(bin, *pipedesc):
73 """Create an array of elements from a list of tuples, add them to a bin,
74 link them sequentially, and return the list. Example:
75
76 mkelem(bin, ('audiotestsrc', {'wave':9}), ('audioresample',))
77
78 is equivalent to
79
80 audiotestsrc wave=9 ! audioresample
81 """
82 elems = [mkelem(*elemdesc) for elemdesc in pipedesc]
83 for elem in elems:
84 bin.add(elem)
85 if len(elems) > 1:
86 Gst.element_link_many(*elems) # MOD: Error line [87]: element_link_many not yet implemented. See web page **
87 return elems
88
89
90
91def splice(bin, pad, element):
92 """Splice element into an existing bin by teeing off an existing pad.
93
94 If necessary, a tee is added to the pipeline in order to splice the new element.
95
96 bin is an instance of Gst.Bin or Gst.Pipeline. pad is a string that
97 describes any pad inside that bin. The syntax used in gst-launch is
98 understood. For example, the string 'foo.bar.bat' means the pad called 'bat'
99 on the element called 'bar' in the bin called 'foo' inside bin. 'foo.bar.'
100 refers to any pad on the element 'bar'. element_or_pad is either an element
101 or a pad.
102
103 FIXME: implicit pad names not yet understood.
104 """
105
106 padpath = pad.split('.')
107 padname = padpath.pop()
108
109 elem = bin
110 for name in padpath:
111 elem = elem.get_by_name(name)
112 if elem is None:
113 raise NameError("no such element: '%s'" % name)
114
115 pad = elem.get_static_pad(padname)
116 if pad is None:
117 raise NameError("no such pad: '%s'" % padname)
118
119 tee_type = Gst.element_factory_find('tee').get_element_type()
120
121 tee = pad.get_parent_element()
122 if tee.__gtype__ != tee_type:
123 peer_pad = pad.get_peer()
124 if peer_pad is None:
125 if hasattr(element, 'get_direction'):
126 elem.get_static_pad('src').link(element)
127 else:
128 elem.link(element)
129 return
130 else:
131 peer_element = peer_pad.get_parent_element()
132 if peer_element.__gtype__ == tee_type:
133 tee = peer_element
134 else:
135 if pad.get_direction() == Gst.PadDirection.SINK:
136 pad, peer_pad = peer_pad, pad
137 pad.unlink(peer_pad)
138 tee = Gst.ElementFactory.make("tee", None)
139 bin.add(tee)
140 pad.link(tee.get_static_pad('sink'))
141 tee.get_request_pad('src%d').link(peer_pad)
142 if hasattr(element, 'get_direction'):
143 tee.get_request_pad('src%d').link(element)
144 else:
145 tee.link(element)