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: 7162 $" 
 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 proc(struct, vals.high) 102 else: 103 # scalar 104 proc(struct, vals)
105 106 def addRatesForWidth(struct, width): 107 108 def addRatesForHeight(struct, height): 109 110 def addRate(struct, rate): 111 if (width, height) not in sizes: 112 sizes[(width, height)] = [] 113 d = {'framerate': (rate.num, rate.denom), 114 'mime': struct.get_name()} 115 if 'yuv' in d['mime']: 116 d['format'] = struct['format'].fourcc 117 sizes[(width, height)].append(d) 118 forAllStructValues(struct, 'framerate', addRate) 119 forAllStructValues(struct, 'height', addRatesForHeight) 120 for struct in caps: 121 if 'yuv' not in struct.get_name(): 122 continue 123 forAllStructValues(struct, 'width', addRatesForWidth) 124 125 return (name, element.get_factory().get_name(), sizes) 126 127 def tryV4L2(): 128 log.debug('webcam', 'trying v4l2') 129 version = gstreamer.get_plugin_version('video4linux2') 130 minVersion = (0, 10, 5, 1) 131 if not version or version < minVersion: 132 log.info('webcam', 'v4l2 version %r too old (need >=%r)', 133 version, minVersion) 134 return defer.fail(NotImplementedError()) 135 136 pipeline = 'v4l2src name=source device=%s ! fakesink' % (device, ) 137 d = do_element_check(pipeline, 'source', probeDevice, 138 state=gst.STATE_PAUSED, set_state_deferred=True) 139 return d 140 141 def tryV4L1(_): 142 log.debug('webcam', 'trying v4l1') 143 pipeline = 'v4lsrc name=source device=%s ! fakesink' % (device, ) 144 d = do_element_check(pipeline, 'source', probeDevice, 145 state=gst.STATE_PAUSED, set_state_deferred=True) 146 return d 147 148 result = messages.Result() 149 150 d = tryV4L2() 151 d.addErrback(tryV4L1) 152 d.addCallback(check.callbackResult, result) 153 d.addErrback(check.errbackNotFoundResult, result, mid, device) 154 d.addErrback(check.errbackResult, result, mid, device) 155 156 return d 157