Package sparked :: Package hardware :: Module video
[hide private]
[frames] | no frames]

Source Code for Module sparked.hardware.video

  1  # Copyright (c) 2010 Arjan Scherpenisse 
  2  # See LICENSE for details. 
  3   
  4  import gst 
  5   
  6  from twisted.python import log 
  7   
  8  from sparked import events 
  9  from sparked.hardware import hal 
10 11 12 -class V4LDeviceMonitor (hal.HardwareMonitor):
13 """ 14 Video device monitor. 15 """ 16 subsystem = "video4linux" 17 uniquePath = "/dev/v4l/by-id/" 18
19 - def __init__(self):
20 self.events = videoEvents
21 22 videoEvents = events.EventDispatcher() 23 """ Event dispatcher for serial events """
24 25 26 27 -class V4LDevice (object):
28 """ 29 Represents a V4L video input device. 30 """ 31
32 - def __init__(self, device, v4l2version=2):
33 self.preferMimes = ["image/jpeg", "video/x-raw-yuv", "video/x-raw-rgb"] 34 self.setDevice(device, v4l2version)
35 36
37 - def _probe(self):
38 """ 39 Find out the resolutions of the device 40 """ 41 42 pipe = gst.parse_launch("%s name=source device=%s ! fakesink" % (self.gstSrc, self.device)) 43 pipe.set_state(gst.STATE_PAUSED) 44 caps = pipe.get_by_name("source").get_pad("src").get_caps() 45 46 self._resolutions = [] 47 48 for struct in caps: 49 if struct.get_name() not in self.preferMimes: 50 log.msg("mime \"%s\" currently not supported." % struct.get_name()) 51 continue 52 if not isinstance(struct["width"], int): 53 log.msg("\"range\" resolutions currently not supported.") 54 continue 55 if type(struct["framerate"]) == list: 56 fr = min(struct["framerate"]) 57 else: 58 fr = struct["framerate"] 59 r = {'mime': struct.get_name(), 60 'width': struct['width'], 61 'height': struct['height'], 62 'framerate': fr} 63 self.resolutions.append(r) 64 pipe.set_state(gst.STATE_NULL)
65 66 67 @property
68 - def resolutions(self):
69 if self._resolutions is None: 70 self._probe() 71 return self._resolutions
72 73
74 - def setDevice(self, device, v4l2version=2):
75 """ 76 Set the device 77 """ 78 self.device = device 79 80 self.v4l2version = v4l2version 81 if str(self.v4l2version) == '2': 82 self.gstSrc = "v4l2src" 83 else: 84 self.gstSrc = "v4lsrc" 85 self._resolutions = None
86 87
88 - def getHighestResolution(self, mime=None):
89 """ 90 Optionally given a mime, get the highest possible resolution, without 91 taking framerate into account. Returns a resolution dict. 92 """ 93 mxres = 0 94 mx = None 95 pref = self.preferMimes 96 for r in self.resolutions: 97 if mime and r['mime'] != mime: 98 continue 99 if not mx or r['width']*r['height']>mxres: 100 mx = r 101 mxres = r['width']*r['height'] 102 elif r['width']*r['height']==mxres and float(r['framerate'])>float(mx['framerate']): 103 mx = r 104 elif r['width']*r['height']==mxres and float(r['framerate'])==float(mx['framerate']) and pref.index(r['mime'])<pref.index(mx['mime']): 105 mx = r 106 return mx
107 108
109 - def getFastestResolution(self, mime=None):
110 """ 111 Optionally given a mime, get the fastest possible resolution, without 112 taking resolution into account. Returns a resolution dict. 113 """ 114 mxfr = None 115 mx = None 116 pref = self.preferMimes 117 for r in self.resolutions: 118 if mime and r['mime'] != mime: 119 continue 120 if not mx or float(r['framerate'])>float(mxfr): 121 mx = r 122 mxfr = r['framerate'] 123 elif float(r['framerate'])==float(mxfr) and r['width']*r['height']>mx['width']*mx['height']: 124 mx = r 125 elif float(r['framerate'])==float(mxfr) and r['width']*r['height']==mx['width']*mx['height'] and pref.index(r['mime'])<pref.index(mx['mime']): 126 mx = r 127 128 return mx
129 130
131 - def getBestMime(self):
132 """ 133 Return the best supported video mime type. 134 """ 135 mime = None 136 pref = self.preferMimes 137 for r in self.resolutions: 138 if not mime or pref.index(mime) > pref.index(r['mime']): 139 mime = r['mime'] 140 return mime
141 142
143 - def getResolution(self, resolution, mime=None):
144 if resolution == "auto" or resolution == "highest": 145 return self.getHighestResolution(mime) 146 if resolution == "fastest": 147 return self.getFastestResolution(mime) 148 149 w,h = parseResolution(resolution) 150 mx = None 151 pref = self.preferMimes 152 for r in self.resolutions: 153 if r['width'] != w or r['height'] != h: 154 continue 155 if mime and r['mime'] != mime: 156 continue 157 if not mx: 158 mx = r 159 elif pref.index(mx['mime']) > pref.index(r['mime']): 160 mx = r 161 return mx
162 163
164 - def getPipeline(self, outputMime=None, resolution="auto"):
165 """ 166 Construct a string which is parsable as the "input" part of the pipeline for a gstreamer camera. 167 """ 168 169 r = self.getResolution(resolution) 170 if r is None: 171 raise ValueError("Unsupported resolution: "+resolution) 172 w, h = r['width'], r['height'] 173 inputMime = r['mime'] 174 framerate = r['framerate'] 175 176 if outputMime is None: 177 outputMime = inputMime 178 179 pipe = "%s device=%s ! %s,width=%d,height=%d,framerate=%d/%d" % (self.gstSrc, self.device, inputMime, w, h, framerate.num, framerate.denom) 180 181 if inputMime == outputMime: 182 return pipe 183 if inputMime == "image/jpeg": 184 pipe += " ! jpegdec" 185 else: 186 pipe += " ! ffmpegcolorspace" 187 pipe += " ! " + outputMime 188 return pipe
189
190 191 -def parseResolution(res):
192 try: 193 return tuple(map(int, res.split("x"))) 194 except: 195 raise ValueError("Invalid resolution: " + res)
196