Package flumotion :: Package component :: Package producers :: Package firewire :: Module firewire
[hide private]

Source Code for Module flumotion.component.producers.firewire.firewire

  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 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  import gst 
 23  from twisted.internet import defer 
 24   
 25  from flumotion.common import errors, messages 
 26  from flumotion.component import feedcomponent 
 27   
 28  from flumotion.common.messages import N_ 
 29  T_ = messages.gettexter('flumotion') 
 30   
 31  # See comments in gstdvdec.c for details on the dv format. 
 32   
33 -class Firewire(feedcomponent.ParseLaunchComponent):
34 - def do_check(self):
35 self.debug('running PyGTK/PyGST checks') 36 from flumotion.component.producers import checks 37 d1 = checks.checkTicket347() 38 d2 = checks.checkTicket348() 39 dl = defer.DeferredList([d1, d2]) 40 dl.addCallback(self._checkCallback) 41 return dl
42
43 - def _checkCallback(self, results):
44 for (state, result) in results: 45 for m in result.messages: 46 self.addMessage(m)
47
48 - def get_pipeline_string(self, props):
49 width = props.get('width', 240) 50 height = props.get('height', int(576 * width/720.)) # assuming PAL :-/ 51 52 # F0.6: remove backwards-compatible properties 53 self.fixRenamedProperties(props, [ 54 ('scaled_width', 'scaled-width'), 55 ('is_square', 'is-square'), 56 ]) 57 scaled_width = props.get('scaled-width', width) 58 is_square = props.get('is-square', False) 59 framerate = props.get('framerate', (30, 2)) 60 framerate_float = float(framerate[0]) / framerate[1] 61 62 scale_correction = width - scaled_width 63 64 if 12.5 < framerate_float <= 25: 65 drop_factor = 1 66 elif 6.3 < framerate_float <= 12.5: 67 drop_factor = 2 68 elif 3.2 < framerate_float <= 6.3: 69 drop_factor = 4 70 else: 71 drop_factor = 8 72 73 if is_square: 74 square_pipe = ',pixel-aspect-ratio=(fraction)1/1' 75 else: 76 square_pipe = '' 77 78 # the point of width correction is to get to a multiple of 8 for width 79 # so codecs are happy; it's unrelated to the aspect ratio correction 80 # to get to 4:3 or 16:9 81 if scale_correction > 0: 82 # videobox in 0.8.8 has a stride problem outputting AYUV with odd 83 # width I420 works fine, but is slower when overlay is used 84 85 pad_pipe = '! ffmpegcolorspace ! videobox right=-%d ! video/x-raw-yuv,format=(fourcc)I420 ' % scale_correction 86 else: 87 pad_pipe = '' 88 89 # Always scale down to half size to lose interlacing artifacts. 90 # FIXME: handle this better when GStreamer provides facilities for it. 91 interlaced_height = 288 92 93 # FIXME: might be nice to factor out dv1394src ! dvdec so we can 94 # replace it with videotestsrc of the same size and PAR, so we can 95 # unittest the pipeline 96 # need a queue in case tcpserversink blocks somehow 97 template = ('dv1394src' 98 ' ! queue leaky=2 max-size-time=1000000000' 99 ' ! dvdemux name=demux' 100 ' demux. ! queue ! dvdec drop-factor=%(df)d' 101 ' ! video/x-raw-yuv,format=(fourcc)YUY2' 102 ' ! videorate ! videoscale' 103 ' ! video/x-raw-yuv,width=%(sw)s,height=%(ih)s%(sq)s' 104 ' ! videoscale' 105 ' ! video/x-raw-yuv,width=%(sw)s,height=%(h)s,framerate=%(fr)s,format=(fourcc)YUY2' 106 ' %(pp)s' 107 ' ! @feeder::video@' 108 ' demux. ! queue ! audio/x-raw-int ! volume name=setvolume' 109 ' ! level name=volumelevel message=true ! audiorate' 110 ' ! @feeder::audio@' 111 % dict(df=drop_factor, ih=interlaced_height, 112 sq=square_pipe, pp=pad_pipe, 113 sw=scaled_width, h=height, 114 fr=('%d/%d' % (framerate[0], framerate[1])))) 115 116 return template
117
118 - def configure_pipeline(self, pipeline, properties):
119 self.volume = pipeline.get_by_name("setvolume") 120 from flumotion.component.effects.volume import volume 121 comp_level = pipeline.get_by_name('volumelevel') 122 vol = volume.Volume('inputVolume', comp_level, pipeline) 123 # catch bus message for when camera disappears 124 bus = pipeline.get_bus() 125 bus.add_signal_watch() 126 bus.connect('message::element', self._bus_message_received_cb) 127 128 self.addEffect(vol)
129
130 - def getVolume(self):
131 return self.volume.get_property('volume')
132
133 - def setVolume(self, value):
134 """ 135 @param value: float between 0.0 and 4.0 136 """ 137 self.debug("Setting volume to %f" % (value)) 138 139 self.volume.set_property('volume', value)
140 141 # detect camera unplugging or other cause of firewire bus reset
142 - def _bus_message_received_cb(self, bus, message):
143 """ 144 @param bus: the message bus sending the message 145 @param message: the message received 146 """ 147 if message.structure.get_name() == "ieee1394-bus-reset": 148 # we have a firewire bus reset 149 s = message.structure 150 # current-device-change is only in gst-plugins-good 0.10.3 151 # not yet released 152 if 'current-device-change' in s: 153 if s['current-device-change'] != 0: 154 # we actually have a connect or disconnect of the camera 155 # so first remove all the previous messages warning about a 156 # firewire-bus-reset 157 158 for m in self.state.get('messages'): 159 if m.id.startswith('firewire-bus-reset'): 160 self.state.remove('messages',m) 161 162 if s['current-device-change'] == 1: 163 # connected 164 m = messages.Info(T_(N_( 165 "The camera has now been reconnected.")), 166 id="firewire-bus-reset-%d" % s['nodecount'], 167 priority=40) 168 self.state.append('messages', m) 169 elif s['current-device-change'] == -1: 170 # disconnected 171 m = messages.Warning(T_(N_( 172 "The camera has been disconnected.")), 173 id="firewire-bus-reset-%d" % s['nodecount'], 174 priority=40) 175 self.state.append('messages', m)
176