blob: 84cd5cceee52392f122e9f97f6bf539a8a5dc875 [file] [log] [blame]
Guido van Rossum6e0e6681992-12-23 15:41:38 +00001#! /ufs/guido/bin/sgi/python-405
2#! /ufs/guido/bin/sgi/python
3
Guido van Rossum3f2ef091993-02-05 15:34:22 +00004# Capture a CMIF movie using the Indigo video library and board in burst mode
Guido van Rossum6e0e6681992-12-23 15:41:38 +00005
6
7# User interface:
8#
9# Start the application. Resize the window to the desired movie size.
10# Press the left mouse button to start recording, release it to end
11# recording. You can record as many times as you wish, but each time
12# you overwrite the output file(s), so only the last recording is
13# kept.
14#
15# Press ESC or select the window manager Quit or Close window option
16# to quit. If you quit before recording anything, the output file(s)
17# are not touched.
18
19
20import sys
21sys.path.append('/ufs/guido/src/video')
22import sv, SV
23import VFile
24import gl, GL, DEVICE
25import al, AL
26import time
27import posix
28import getopt
29import string
30import imageop
31import sgi
32
Guido van Rossum3f2ef091993-02-05 15:34:22 +000033
34# Usage and help functions (keep this up-to-date if you change the program!)
35
36def usage():
37 print 'Usage: Vrecb [options] [moviefile]'
38 print
39 print 'Options:'
40 print '-r rate : capture 1 out of every "rate" frames', \
41 '(default and min 1)'
42 print '-w width : initial window width', \
43 '(default interactive placement)'
44 print '-d : drop fields if needed'
45 print '-g bits : greyscale (2, 4 or 8 bits)'
46 print '-G : 2-bit greyscale dithered'
47 print '-m : monochrome dithered'
48 print '-M value : monochrome tresholded with value'
49 print '-f : Capture fields (instead of frames)'
50 print '-n number : Capture this many frames (default 60)'
51 print 'moviefile : here goes the movie data (default film.video)'
52
53def help():
54 print 'Press the left mouse button to start recording.'
55 print 'Recording time is determined by the -n option.'
56 print 'You can record as many times as you wish, but each'
57 print 'recording overwrites the output file(s) -- only the'
58 print 'last recording is kept.'
59 print
60 print 'Press ESC or use the window manager Quit or Close window option'
61 print 'to quit. If you quit before recording anything, the output'
62 print 'file(s) are not touched.'
63
64
Guido van Rossum6e0e6681992-12-23 15:41:38 +000065# Main program
66
67def main():
68 format = SV.RGB8_FRAMES
69 rate = 1
70 width = 0
71 drop = 0
72 mono = 0
73 grey = 0
74 greybits = 0
75 monotreshold = -1
76 fields = 0
77 number = 60
78
Guido van Rossum3f2ef091993-02-05 15:34:22 +000079 try:
80 opts, args = getopt.getopt(sys.argv[1:], 'r:w:dg:mM:Gfn:')
81 except getopt.error, msg:
82 sys.stdout = sys.stderr
83 print 'Error:', msg, '\n'
84 usage()
85 sys.exit(2)
86
87 try:
88 for opt, arg in opts:
89 if opt == '-r':
90 rate = string.atoi(arg)
91 if rate < 1:
92 sys.stderr.write('-r rate must be >= 1\n')
93 sys.exit(2)
94 elif opt == '-w':
95 width = string.atoi(arg)
96 elif opt == '-d':
97 drop = 1
98 elif opt == '-g':
99 grey = 1
100 greybits = string.atoi(arg)
101 if not greybits in (2,4,8):
102 sys.stderr.write( \
103 'Only 2, 4 or 8 bit greyscale supported\n')
104 sys.exit(2)
105 elif opt == '-G':
106 grey = 1
107 greybits = -2
108 elif opt == '-m':
109 mono = 1
110 elif opt == '-M':
111 mono = 1
112 monotreshold = string.atoi(arg)
113 elif opt == '-f':
114 fields = 1
115 elif opt == '-n':
116 number = string.atoi(arg)
117 except string.atoi_error:
118 sys.stdout = sys.stderr
119 print 'Option', opt, 'requires integer argument'
120 sys.exit(2)
121
122 if not fields:
123 print '-f option assumed until Jack fixes it'
124 fields = 1
Guido van Rossum6e0e6681992-12-23 15:41:38 +0000125
126 if args[2:]:
Guido van Rossum3f2ef091993-02-05 15:34:22 +0000127 sys.stderr.write('usage: Vrecb [options] [file]\n')
Guido van Rossum6e0e6681992-12-23 15:41:38 +0000128 sys.exit(2)
129
130 if args:
131 filename = args[0]
132 else:
133 filename = 'film.video'
134
135 v = sv.OpenVideo()
136 # Determine maximum window size based on signal standard
137 param = [SV.BROADCAST, 0]
138 v.GetParam(param)
139 if param[1] == SV.PAL:
140 x = SV.PAL_XMAX
141 y = SV.PAL_YMAX
142 elif param[1] == SV.NTSC:
143 x = SV.NTSC_XMAX
144 y = SV.NTSC_YMAX
145 else:
146 print 'Unknown video standard', param[1]
147 sys.exit(1)
148
149 gl.foreground()
150 gl.maxsize(x, y)
151 gl.keepaspect(x, y)
152 gl.stepunit(8, 6)
153 if width:
154 gl.prefsize(width, width*3/4)
155 win = gl.winopen(filename)
156 if width:
157 gl.maxsize(x, y)
158 gl.keepaspect(x, y)
159 gl.stepunit(8, 6)
160 gl.winconstraints()
161 x, y = gl.getsize()
162 print x, 'x', y
163
164 v.SetSize(x, y)
165
166 if drop:
167 param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF]
168 else:
169 param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON]
170 if mono or grey:
171 param = param+[SV.COLOR, SV.MONO, SV.INPUT_BYPASS, 1]
172 else:
173 param = param+[SV.COLOR, SV.DEFAULT_COLOR, SV.INPUT_BYPASS, 0]
174 v.SetParam(param)
175
176 v.BindGLWindow(win, SV.IN_REPLACE)
177
178 gl.qdevice(DEVICE.LEFTMOUSE)
179 gl.qdevice(DEVICE.WINQUIT)
180 gl.qdevice(DEVICE.WINSHUT)
181 gl.qdevice(DEVICE.ESCKEY)
182
Guido van Rossum3f2ef091993-02-05 15:34:22 +0000183 help()
Guido van Rossum6e0e6681992-12-23 15:41:38 +0000184
185 while 1:
186 dev, val = gl.qread()
187 if dev == DEVICE.LEFTMOUSE:
188 if val == 1:
189 info = format, x, y, number, rate
190 record(v, info, filename, mono, grey, \
191 greybits, monotreshold, fields)
192 elif dev == DEVICE.REDRAW:
193 # Window resize (or move)
194 x, y = gl.getsize()
195 print x, 'x', y
196 v.SetSize(x, y)
197 v.BindGLWindow(win, SV.IN_REPLACE)
198 elif dev in (DEVICE.ESCKEY, DEVICE.WINQUIT, DEVICE.WINSHUT):
199 # Quit
200 v.CloseVideo()
201 gl.winclose(win)
202 break
203
204
205# Record until the mouse is released (or any other GL event)
206# XXX audio not yet supported
207
208def record(v, info, filename, mono, grey, greybits, monotreshold, fields):
209 import thread
210 format, x, y, number, rate = info
211 fps = 59.64 # Fields per second
212 # XXX (Strange: need fps of Indigo monitor, not of PAL or NTSC!)
213 tpf = 1000.0 / fps # Time per field in msec
214 #
215 # Go grab
216 #
217 gl.wintitle('(rec) ' + filename)
218 try:
219 ninfo, data, bitvec = v.CaptureBurst(info)
220 except sv.error, arg:
221 print 'CaptureBurst failed:', arg
222 print 'info:', info
223 gl.wintitle(filename)
224 return
225 gl.wintitle('(save) '+ filename)
226 #
227 # Check results
228 #
229 if info <> ninfo:
230 print 'Sorry, format changed.'
231 print 'Wanted:',info
232 print 'Got :',ninfo
233 gl.wintitle(filename)
234 return
235 # print bitvec
236 if x*y*number <> len(data):
237 print 'Funny data length: wanted',x,'*',y,'*', number,'=',\
238 x*y*number,'got',len(data)
239 gl.wintitle(filename)
240 return
241 #
242 # Save
243 #
244 if filename:
245 #
246 # Construct header and write it
247 #
248 vout = VFile.VoutFile().init(filename)
249 if mono:
250 vout.format = 'mono'
251 elif grey and greybits == 8:
252 vout.format = 'grey'
253 elif grey:
254 vout.format = 'grey'+`abs(greybits)`
255 else:
256 vout.format = 'rgb8'
257 vout.width = x
258 vout.height = y
259 if fields:
260 vout.packfactor = (1,-2)
261 else:
262 print 'Sorry, can only save fields at the moment'
Guido van Rossum3f2ef091993-02-05 15:34:22 +0000263 print '(i.e. you *must* use the -f option)'
Guido van Rossum6e0e6681992-12-23 15:41:38 +0000264 gl.wintitle(filename)
265 return
266 vout.writeheader()
267 #
268 # Compute convertor, if needed
269 #
270 convertor = None
271 if grey:
272 if greybits == 2:
273 convertor = imageop.grey2grey2
274 elif greybits == 4:
275 convertor = imageop.grey2grey4
276 elif greybits == -2:
277 convertor = imageop.dither2grey2
278 fieldsize = x*y/2
279 nskipped = 0
280 realframeno = 0
281 tpf = 1000 / 50.0 #XXXX
282 for frameno in range(0, number*2):
283 if frameno <> 0 and \
284 bitvec[frameno] == bitvec[frameno-1]:
285 nskipped = nskipped + 1
286 continue
287 #
288 # Save field.
289 # XXXX Works only for fields and top-to-bottom
290 #
291 start = frameno*fieldsize
292 field = data[start:start+fieldsize]
293 if convertor:
294 field = convertor(field, x, y)
295 elif mono and monotreshold >= 0:
296 field = imageop.grey2mono(field, x, y, \
297 1, monotreshold)
298 elif mono:
299 field = imageop.dither2mono(field, x, y)
300 vout.writeframe(int(realframeno*tpf), field, None)
301 print 'Skipped',nskipped,'duplicate frames'
302 vout.close()
303
304 gl.wintitle('(done) ' + filename)
305
306# Don't forget to call the main program
307
308try:
309 main()
310except KeyboardInterrupt:
311 print '[Interrupt]'