1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import sys
19
20 import gobject
21 import gst
22
23 from flumotion.common.i18n import gettexter
24 from flumotion.component import feedcomponent
25 from flumotion.common import gstreamer
26
27 __version__ = "$Rev$"
28 T_ = gettexter()
29
30 DEFAULT_TOLERANCE = 20000000
31
32
34 """
35 I am a GStreamer bin that can convert an an audio stream, changing its
36 samplerate and the number of channels
37 """
38 logCategory = "audiorate"
39 RATE_CAPS = ', rate=%d'
40 CHANNELS_CAPS = ', channels=%d'
41 CAPS_TEMPLATE = ("audio/x-raw-int %(extra_caps)s ;"
42 "audio/x-raw-float %(extra_caps)s")
43
44 __gproperties__ = {
45 'channels': (gobject.TYPE_UINT, 'channels',
46 'Audio channels', 1, 8, 2,
47 gobject.PARAM_READWRITE),
48 'samplerate': (gobject.TYPE_UINT, 'samplerate',
49 'Audio samplerate', 1, 200000, 44100,
50 gobject.PARAM_READWRITE),
51 'tolerance': (gobject.TYPE_UINT, 'tolerance',
52 'Correct imperfect timestamps when it exeeds the '
53 'tolerance', 0, sys.maxint, DEFAULT_TOLERANCE,
54 gobject.PARAM_READWRITE)}
55
58 gst.Bin.__init__(self)
59 self._samplerate = samplerate
60 self._samplerate_caps = ''
61 self._channels = channels
62 self._channels_caps = ''
63
64 if use_audiorate:
65 self._audiorate = gst.element_factory_make("audiorate")
66 else:
67 self._audiorate = gst.element_factory_make("identity")
68 self._audiorate.set_property("silent", True)
69
70 self._audioconv = gst.element_factory_make("audioconvert")
71
72 resampler = 'audioresample'
73 if gstreamer.element_factory_exists('legacyresample'):
74 resampler = 'legacyresample'
75 self._audioresample = gst.element_factory_make(resampler)
76
77 self._capsfilter = gst.element_factory_make("capsfilter")
78 self._identity = gst.parse_launch("identity silent=true")
79 self.add(self._audiorate)
80 self.add(self._audioconv)
81 self.add(self._audioresample)
82 self.add(self._capsfilter)
83 self.add(self._identity)
84
85 self._audiorate.link(self._audioconv)
86 self._audioconv.link(self._audioresample)
87 self._audioresample.link(self._capsfilter)
88 self._capsfilter.link(self._identity)
89
90
91 self._sinkPad = gst.GhostPad('sink', self._audiorate.get_pad('sink'))
92 self._srcPad = gst.GhostPad('src', self._identity.get_pad('src'))
93 self.add_pad(self._sinkPad)
94 self.add_pad(self._srcPad)
95
96 self._setSamplerate(samplerate)
97 self._setChannels(channels)
98 self._setTolerance(tolerance)
99
101 extra_caps = ' '.join([self._samplerate_caps, self._channels_caps])
102 return self.CAPS_TEMPLATE % dict(extra_caps=extra_caps)
103
105 self._channels = channels
106 self._channels_caps = ''
107 if self._channels is not None:
108 self._channels_caps = self.CHANNELS_CAPS % channels
109 self._capsfilter.set_property('caps', gst.Caps(self._getCapsString()))
110
112 self._samplerate = samplerate
113 self._samplerate_caps = ''
114 if self._samplerate is not None:
115 self._samplerate_caps = self.RATE_CAPS % samplerate
116 self._capsfilter.set_property('caps', gst.Caps(self._getCapsString()))
117
119 self._tolerance = tolerance
120 if gstreamer.element_has_property(self._audiorate, 'tolerance'):
121 self._audiorate.set_property('tolerance', self._tolerance)
122 else:
123 self.warning("The 'tolerance' property could not be set in the "
124 "audiorate element.")
125
135
137 if property.name == 'channels':
138 return self._channels
139 if property.name == 'samplerate':
140 return self._samplerate
141 if property.name == 'tolerance':
142 return self._tolerance
143 else:
144 raise AttributeError('unknown property %s' % property.name)
145
146
148 """
149 I am an effect that can be added to any component that changes the
150 samplerate of the audio output.
151 """
152 logCategory = "audioconvert-effect"
153
154 - def __init__(self, name, sourcePad, pipeline, channels=None,
155 samplerate=None, tolerance=DEFAULT_TOLERANCE,
156 use_audiorate=True):
157 """
158 @param element: the video source element on which the post
159 processing effect will be added
160 @param sourcePad: source pad used for linking the effect
161 @param pipeline: the pipeline of the element
162 @param channels: number of output channels
163 @param samplerate: output samplerate
164 @param tolerance: tolerance to correct imperfect timestamps
165 """
166 feedcomponent.PostProcEffect.__init__(self, name, sourcePad,
167 AudioconvertBin(channels, samplerate, tolerance, use_audiorate),
168 pipeline)
169
171 self.effectBin.set_property("tolerance", tolerance)
172 return tolerance
173
175 return self.effectBin.get_property('tolerance')
176
178 self.effectBin.set_property("samplerate", samplerate)
179 return samplerate
180
182 return self.effectBin.get_property('samplerate')
183
185 self.effectBin.set_property("channels", channels)
186 return channels
187
189 return self.effectBin.get_property('channels')
190