blob: d79113ccdf9bcd00dabf302a95183801090c64cb [file] [log] [blame]
Guido van Rossumb7e3cc11993-05-06 16:06:44 +00001#! /ufs/guido/bin/sgi/python
2
3# Video bag-of-tricks
4
5import sys
6import getopt
7import string
8import os
9sts = os.system('makemap') # Must be before "import fl"
10import sgi
11import gl
12import GL
13import DEVICE
14import fl
15import FL
16import flp
17import watchcursor
18import sv
19import SV
20import VFile
21import VGrabber
22import imageop
23
24ARROW = 0
25WATCH = 1
26watchcursor.defwatch(WATCH)
27
28def main():
29 vb = VideoBagOfTricks().init()
30 while 1:
31 dummy = fl.do_forms()
32 [dummy]
33
34StopCapture = 'StopCapture'
35
36formats = ['rgb24', 'rgb8', 'grey8', 'grey4', 'grey2', \
37 'grey2_dith', 'mono_dith', 'mono_thresh']
38formatmap = {'rgb24': 'rgb', 'grey8': 'grey'}
39
40class 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
296try:
297 main()
298except KeyboardInterrupt:
299 print '[Interrupt]'
300 sys.exit(1)