Package flumotion :: Package worker :: Package checks :: Module video
[hide private]

Source Code for Module flumotion.worker.checks.video

  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 gst 
 19   
 20  from twisted.internet import defer 
 21   
 22  from flumotion.common import gstreamer, log, messages 
 23  from flumotion.worker.checks import check 
 24  from flumotion.worker.checks.gst010 import do_element_check 
 25   
 26  __version__ = "$Rev$" 
 27   
 28   
29 -def checkTVCard(device, mid='check-tvcard'):
30 """ 31 Probe the given device node as a TV card. 32 Return a deferred firing a human-readable device name, a list of channel 33 names (Tuner/Composite/...), and a list of norms (PAL/NTSC/SECAM/...). 34 35 @rtype: L{twisted.internet.defer.Deferred} 36 """ 37 result = messages.Result() 38 39 def get_name_channels_norms(element): 40 deviceName = element.get_property('device-name') 41 channels = [channel.label for channel in element.list_channels()] 42 norms = [norm.label for norm in element.list_norms()] 43 return (deviceName, channels, norms)
44 45 pipeline = 'v4lsrc name=source device=%s ! fakesink' % device 46 d = do_element_check(pipeline, 'source', get_name_channels_norms) 47 48 d.addCallback(check.callbackResult, result) 49 d.addErrback(check.errbackNotFoundResult, result, mid, device) 50 d.addErrback(check.errbackResult, result, mid, device) 51 52 return d 53 54
55 -def checkWebcam(device, mid):
56 """ 57 Probe the given device node as a webcam. 58 59 The result is either: 60 - succesful, with a None value: no device found 61 - succesful, with a tuple: 62 - device name 63 - dict of mime, format, width, height, fps pair 64 - failed 65 66 @rtype: L{flumotion.common.messages.Result} 67 """ 68 # FIXME: add code that checks permissions and ownership on errors, 69 # so that we can offer helpful hints on what to do. 70 71 def probeDevice(element): 72 caps = element.get_pad("src").get_caps() 73 log.debug('check', 'caps: %s' % caps.to_string()) 74 75 sizes = {} # (width, height) => [{'framerate': (framerate_num, 76 # framerate_denom), 77 # 'mime': str, 78 # 'fourcc': fourcc}] 79 80 def forAllStructValues(struct, key, proc): 81 vals = struct[key] 82 if isinstance(vals, list): 83 for val in vals: 84 proc(struct, val) 85 elif isinstance(vals, gst.IntRange): 86 val = vals.low 87 while val < vals.high: 88 proc(struct, val) 89 val *= 2 90 proc(struct, vals.high) 91 elif isinstance(vals, gst.DoubleRange): 92 # hack :) 93 proc(struct, vals.high) 94 elif isinstance(vals, gst.FractionRange): 95 # hack :) 96 val = vals.low 97 while float(val) < float(vals.high): 98 proc(struct, val) 99 val.num += 5 100 proc(struct, vals.high) 101 else: 102 # scalar 103 proc(struct, vals)
104 105 def addRatesForWidth(struct, width): 106 107 def addRatesForHeight(struct, height): 108 109 def addRate(struct, rate): 110 if not rate.num: 111 return 112 if (width, height) not in sizes: 113 sizes[(width, height)] = [] 114 d = {'framerate': (rate.num, rate.denom), 115 'mime': struct.get_name()} 116 if 'yuv' in d['mime']: 117 d['format'] = struct['format'].fourcc 118 sizes[(width, height)].append(d) 119 forAllStructValues(struct, 'framerate', addRate) 120 forAllStructValues(struct, 'height', addRatesForHeight) 121 for struct in caps: 122 if 'yuv' not in struct.get_name(): 123 continue 124 forAllStructValues(struct, 'width', addRatesForWidth) 125 126 return (element.get_factory().get_name(), sizes) 127 128 def tryV4L2(): 129 log.debug('webcam', 'trying v4l2') 130 version = gstreamer.get_plugin_version('video4linux2') 131 minVersion = (0, 10, 5, 1) 132 if not version or version < minVersion: 133 log.info('webcam', 'v4l2 version %r too old (need >=%r)', 134 version, minVersion) 135 return defer.fail(NotImplementedError()) 136 137 pipeline = 'v4l2src name=source device=%s ! fakesink' % (device, ) 138 d = do_element_check(pipeline, 'source', probeDevice, 139 state=gst.STATE_PAUSED, set_state_deferred=True) 140 return d 141 142 def tryV4L1(_): 143 log.debug('webcam', 'trying v4l1') 144 pipeline = 'v4lsrc name=source device=%s ! fakesink' % (device, ) 145 d = do_element_check(pipeline, 'source', probeDevice, 146 state=gst.STATE_PAUSED, set_state_deferred=True) 147 return d 148 149 result = messages.Result() 150 151 d = tryV4L2() 152 d.addErrback(tryV4L1) 153 d.addCallback(check.callbackResult, result) 154 d.addErrback(check.errbackNotFoundResult, result, mid, device) 155 d.addErrback(check.errbackResult, result, mid, device) 156 157 return d 158