Guido van Rossum | b7e3cc1 | 1993-05-06 16:06:44 +0000 | [diff] [blame^] | 1 | #! /ufs/guido/bin/sgi/python |
| 2 | |
| 3 | # Video bag-of-tricks |
| 4 | |
| 5 | import sys |
| 6 | import getopt |
| 7 | import string |
| 8 | import os |
| 9 | sts = os.system('makemap') # Must be before "import fl" |
| 10 | import sgi |
| 11 | import gl |
| 12 | import GL |
| 13 | import DEVICE |
| 14 | import fl |
| 15 | import FL |
| 16 | import flp |
| 17 | import watchcursor |
| 18 | import sv |
| 19 | import SV |
| 20 | import VFile |
| 21 | import VGrabber |
| 22 | import imageop |
| 23 | |
| 24 | ARROW = 0 |
| 25 | WATCH = 1 |
| 26 | watchcursor.defwatch(WATCH) |
| 27 | |
| 28 | def main(): |
| 29 | vb = VideoBagOfTricks().init() |
| 30 | while 1: |
| 31 | dummy = fl.do_forms() |
| 32 | [dummy] |
| 33 | |
| 34 | StopCapture = 'StopCapture' |
| 35 | |
| 36 | formats = ['rgb24', 'rgb8', 'grey8', 'grey4', 'grey2', \ |
| 37 | 'grey2_dith', 'mono_dith', 'mono_thresh'] |
| 38 | formatmap = {'rgb24': 'rgb', 'grey8': 'grey'} |
| 39 | |
| 40 | class VideoBagOfTricks: |
| 41 | |
| 42 | def init(self): |
| 43 | formdef = flp.parse_form('VbForm', 'form') |
| 44 | flp.create_full_form(self, formdef) |
| 45 | self.setdefaults() |
| 46 | self.openvideo() |
| 47 | self.makewindow() |
| 48 | self.bindvideo() |
| 49 | self.capturing = 0 |
| 50 | self.b_stop.hide_object() |
| 51 | self.form.show_form(FL.PLACE_SIZE, FL.TRUE, \ |
| 52 | 'Video Bag Of Tricks') |
| 53 | fl.set_event_call_back(self.do_event) |
| 54 | return self |
| 55 | |
| 56 | def setwatch(self): |
| 57 | gl.winset(self.form.window) |
| 58 | gl.setcursor(WATCH, 0, 0) |
| 59 | |
| 60 | def setarrow(self): |
| 61 | gl.winset(self.form.window) |
| 62 | gl.setcursor(ARROW, 0, 0) |
| 63 | |
| 64 | def setdefaults(self): |
| 65 | self.format = 'rgb8' |
| 66 | self.c_format.clear_choice() |
| 67 | for label in formats: |
| 68 | self.c_format.addto_choice(label) |
| 69 | self.c_format.set_choice(1 + formats.index(self.format)) |
| 70 | self.mono_thresh = 128 |
| 71 | self.mono_use_thresh = 0 |
| 72 | self.b_drop.set_button(1) |
| 73 | self.b_burst.set_button(0) |
| 74 | self.in_rate.set_input('2') |
| 75 | self.in_maxmem.set_input('1.0') |
| 76 | self.in_nframes.set_input('0') |
| 77 | self.in_file.set_input('film.video') |
| 78 | |
| 79 | def openvideo(self): |
| 80 | self.video = sv.OpenVideo() |
| 81 | param = [SV.BROADCAST, 0] |
| 82 | self.video.GetParam(param) |
| 83 | if param[1] == SV.PAL: |
| 84 | x = SV.PAL_XMAX |
| 85 | y = SV.PAL_YMAX |
| 86 | elif param[1] == SV.NTSC: |
| 87 | x = SV.NTSC_XMAX |
| 88 | y = SV.NTSC_YMAX |
| 89 | else: |
| 90 | print 'Unknown video standard:', param[1] |
| 91 | sys.exit(1) |
| 92 | self.maxx, self.maxy = x, y |
| 93 | |
| 94 | def makewindow(self): |
| 95 | x, y = self.maxx, self.maxy |
| 96 | gl.foreground() |
| 97 | gl.maxsize(x, y) |
| 98 | gl.keepaspect(x, y) |
| 99 | gl.stepunit(8, 6) |
| 100 | width = 256 # XXX |
| 101 | if width: |
| 102 | height = width*3/4 |
| 103 | x1 = 150 |
| 104 | x2 = x1 + width-1 |
| 105 | y2 = 768-150 |
| 106 | y1 = y2-height+1 |
| 107 | gl.prefposition(x1, x2, y1, y2) |
| 108 | self.window = gl.winopen('Vb: initializing') |
| 109 | self.settitle() |
| 110 | if width: |
| 111 | gl.maxsize(x, y) |
| 112 | gl.keepaspect(x, y) |
| 113 | gl.stepunit(8, 6) |
| 114 | gl.winconstraints() |
| 115 | gl.qdevice(DEVICE.LEFTMOUSE) |
| 116 | gl.qdevice(DEVICE.WINQUIT) |
| 117 | gl.qdevice(DEVICE.WINSHUT) |
| 118 | |
| 119 | def settitle(self): |
| 120 | gl.winset(self.window) |
| 121 | gl.wintitle(self.maketitle()) |
| 122 | |
| 123 | def bindvideo(self): |
| 124 | x, y = gl.getsize() |
| 125 | self.video.SetSize(x, y) |
| 126 | drop = self.b_drop.get_button() |
| 127 | if drop: |
| 128 | param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF] |
| 129 | else: |
| 130 | param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON] |
| 131 | if self.getformat()[:3] == 'rgb': |
| 132 | param = param+[SV.COLOR, SV.DEFAULT_COLOR, \ |
| 133 | SV.DITHER, 1, \ |
| 134 | SV.INPUT_BYPASS, 0] |
| 135 | else: |
| 136 | param = param+[SV.COLOR, SV.MONO, SV.DITHER, 0, \ |
| 137 | SV.INPUT_BYPASS, 1] |
| 138 | self.video.BindGLWindow(self.window, SV.IN_REPLACE) |
| 139 | self.video.SetParam(param) |
| 140 | |
| 141 | def rebindvideo(self): |
| 142 | gl.winset(self.window) |
| 143 | self.bindvideo() |
| 144 | |
| 145 | def do_event(self, dev, val): |
| 146 | #print 'Event:', dev, val |
| 147 | if dev in (DEVICE.WINSHUT, DEVICE.WINQUIT): |
| 148 | self.cb_quit() |
| 149 | if dev == DEVICE.REDRAW and val == self.window: |
| 150 | self.rebindvideo() |
| 151 | self.settitle() |
| 152 | |
| 153 | def cb_format(self, *args): |
| 154 | i = self.c_format.get_choice() |
| 155 | label = format = formats[i-1] |
| 156 | if '_' in format: |
| 157 | i = string.find(format, '_') |
| 158 | format = format[:i] |
| 159 | if formatmap.has_key(format): |
| 160 | format = formatmap[format] |
| 161 | self.format = format |
| 162 | # |
| 163 | if label == 'mono_thresh': |
| 164 | self.mono_use_thresh = 1 |
| 165 | s = `self.mono_thresh` |
| 166 | s = fl.show_input('Please enter mono threshold', s) |
| 167 | if s: |
| 168 | try: |
| 169 | self.mono_thresh = string.atoi(s) |
| 170 | except string.atoi_error: |
| 171 | fl.show_message( \ |
| 172 | 'Bad input, using ' + \ |
| 173 | `self.mono_thresh`) |
| 174 | else: |
| 175 | self.mono_use_thresh = 0 |
| 176 | # |
| 177 | self.rebindvideo() |
| 178 | |
| 179 | def getformat(self): |
| 180 | return self.format |
| 181 | |
| 182 | def cb_rate(self, *args): |
| 183 | pass |
| 184 | |
| 185 | def cb_drop(self, *args): |
| 186 | self.rebindvideo() |
| 187 | |
| 188 | def cb_burst(self, *args): |
| 189 | pass |
| 190 | |
| 191 | def cb_maxmem(self, *args): |
| 192 | pass |
| 193 | |
| 194 | def cb_nframes(self, *args): |
| 195 | pass |
| 196 | |
| 197 | def cb_file(self, *args): |
| 198 | filename = self.in_file.get_input() |
| 199 | if filename == '': |
| 200 | filename = 'film.video' |
| 201 | self.in_file.set_input(filename) |
| 202 | self.settitle() |
| 203 | |
| 204 | def cb_open(self, *args): |
| 205 | filename = self.in_file.get_input() |
| 206 | hd, tl = os.path.split(filename) |
| 207 | filename = fl.file_selector('Select file:', hd, '', tl) |
| 208 | if filename: |
| 209 | hd, tl = os.path.split(filename) |
| 210 | if hd == os.getcwd(): |
| 211 | filename = tl |
| 212 | self.in_file.set_input(filename) |
| 213 | self.cb_file() |
| 214 | |
| 215 | def cb_play(self, *args): |
| 216 | filename = self.in_file.get_input() |
| 217 | sts = os.system('Vplay -q ' + filename + ' &') |
| 218 | |
| 219 | def cb_stop(self, *args): |
| 220 | if self.capturing: |
| 221 | raise StopCapture |
| 222 | gl.ringbell() |
| 223 | |
| 224 | def cb_capture(self, *args): |
| 225 | self.setwatch() |
| 226 | self.cb_file() # Make sure filename is OK |
| 227 | filename = self.in_file.get_input() |
| 228 | format = self.getformat() |
| 229 | vout = VFile.VoutFile().init(filename) |
| 230 | vout.setformat(format) |
| 231 | gl.winset(self.window) |
| 232 | x, y = gl.getsize() |
| 233 | vout.setsize(x, y) |
| 234 | vout.writeheader() |
| 235 | convertor = None |
| 236 | if format[:4] == 'grey': |
| 237 | s = format[4:] |
| 238 | if s: |
| 239 | greybits = string.atoi(s) |
| 240 | else: |
| 241 | greybits = 8 |
| 242 | # XXX Should get this from somewhere else? |
| 243 | if greybits == 2: |
| 244 | convertor = imageop.grey2grey2 |
| 245 | elif greybits == 4: |
| 246 | convertor = imageop.grey2grey4 |
| 247 | elif greybits == -2: |
| 248 | convertor = imageop.dither2grey2 |
| 249 | vformat = SV.RGB8_FRAMES |
| 250 | qsize = 0 |
| 251 | rate = eval(self.in_rate.get_input()) |
| 252 | info = (vformat, x, y, qsize, rate) |
| 253 | ids = [] |
| 254 | tpf = 50 |
| 255 | self.video.InitContinuousCapture(info) |
| 256 | self.capturing = 1 |
| 257 | self.setarrow() |
| 258 | self.b_stop.show_object() |
| 259 | while 1: |
| 260 | try: |
| 261 | void = fl.check_forms() |
| 262 | except StopCapture: |
| 263 | self.capturing = 0 |
| 264 | break |
| 265 | try: |
| 266 | cd, id = self.video.GetCaptureData() |
| 267 | except sv.error: |
| 268 | sgi.nap(1) |
| 269 | continue |
| 270 | ids.append(id) |
| 271 | id = id + 2*rate |
| 272 | data = cd.InterleaveFields(1) |
| 273 | cd.UnlockCaptureData() |
| 274 | t = id*tpf |
| 275 | if convertor: |
| 276 | data = convertor(data, len(data), 1) |
| 277 | ## elif mono and monotreshold >= 0: |
| 278 | ## data = imageop.grey2mono(data, len(data), 1,\ |
| 279 | ## monotreshold) |
| 280 | ## elif mono: |
| 281 | ## data = imageop.dither2mono(data, len(data), 1) |
| 282 | vout.writeframe(t, data, None) |
| 283 | self.setwatch() |
| 284 | vout.close() |
| 285 | self.b_stop.hide_object() |
| 286 | self.video.EndContinuousCapture() |
| 287 | self.setarrow() |
| 288 | |
| 289 | def cb_quit(self, *args): |
| 290 | raise SystemExit, 0 |
| 291 | |
| 292 | def maketitle(self): |
| 293 | x, y = gl.getsize() |
| 294 | return 'Vb:' + self.in_file.get_input() + ' (%dx%d)' % (x, y) |
| 295 | |
| 296 | try: |
| 297 | main() |
| 298 | except KeyboardInterrupt: |
| 299 | print '[Interrupt]' |
| 300 | sys.exit(1) |