Package flumotion :: Package component :: Package effects :: Package audioconvert :: Module audioconvert
[hide private]

Source Code for Module flumotion.component.effects.audioconvert.audioconvert

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 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 # 20ms 
 31   
 32   
33 -class AudioconvertBin(gst.Bin):
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
56 - def __init__(self, channels=None, samplerate=None, 57 tolerance=DEFAULT_TOLERANCE, use_audiorate=True):
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 # Create source and sink pads 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
100 - def _getCapsString(self):
101 extra_caps = ' '.join([self._samplerate_caps, self._channels_caps]) 102 return self.CAPS_TEMPLATE % dict(extra_caps=extra_caps)
103
104 - def _setChannels(self, channels):
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
111 - def _setSamplerate(self, samplerate):
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
118 - def _setTolerance(self, tolerance):
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
126 - def do_set_property(self, property, value):
127 if property.name == 'channels': 128 self._setChannels(value) 129 if property.name == 'samplerate': 130 self._setSamplerate(value) 131 if property.name == 'tolerance': 132 self._setTolerance(value) 133 else: 134 raise AttributeError('unknown property %s' % property.name)
135
136 - def do_get_property(self, property):
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
147 -class Audioconvert(feedcomponent.PostProcEffect):
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
170 - def effect_setTolerance(self, tolerance):
171 self.effectBin.set_property("tolerance", tolerance) 172 return tolerance
173
174 - def effect_getTolerance(self):
175 return self.effectBin.get_property('tolerance')
176
177 - def effect_setSamplerate(self, samplerate):
178 self.effectBin.set_property("samplerate", samplerate) 179 return samplerate
180
181 - def effect_getSamplerate(self):
182 return self.effectBin.get_property('samplerate')
183
184 - def effect_setChannels(self, channels):
185 self.effectBin.set_property("channels", channels) 186 return channels
187
188 - def effect_getChannels(self):
189 return self.effectBin.get_property('channels')
190