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