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