Apparently the code to forestall Tk eating events was too aggressive (Tk user input...
[python/dscho.git] / Demo / sgi / video / makemovie.py
blob5cb41cde2ec2d63fb4480c619e9df1bf34d0fc78
1 #! /ufs/guido/bin/sgi/python
2 #! /ufs/guido/src/video/py
4 # Capture a CMIF movie using the Indigo video library and board
7 # Usage:
9 # makemovie [-q queuesize] [-t recordtime] [-a] [moviefile [audiofile]]
12 # Options:
14 # -q queuesize : set the capture queue size (default and max 16)
15 # -t recordtime : set the record time in seconds (default 5 seconds)
16 # -a : record audio as well
17 # moviefile : here goes the movie data (default film.video);
18 # the format is documented in cmif-film.ms
19 # audiofile : with -a, here goes the audio data (default film.aiff);
20 # audio data is recorded in AIFF format, using the
21 # input sampling rate, source and volume set by the
22 # audio panel, in mono, 8 bits/sample
25 # User interface:
27 # Start the application. Resize the window to the desired movie size.
28 # Click the left mouse button to start recording (recording starts
29 # when you release the mouse button). Recording time is specified by
30 # the -t option (XXX this should change).
32 # Press ESC or select the window manager Quit or Close window option
33 # to quit. (You can do this without recording -- then the output
34 # files are untouched.)
36 # (It is possible to record more than once; but this doesn't set the
37 # time stamps correctly yet, and doesn't work at all with audio. So
38 # don't use.)
41 # XXX To do:
43 # fix timestamps for second and further recordings
44 # fix audio " " " " "
45 # flush audio buffer when recording starts
46 # make code more readable
49 import sys
50 sys.path.append('/ufs/guido/src/video')
51 import sv, SV
52 import VFile
53 import gl, GL, DEVICE
54 import al, AL
55 import time
56 import posix
57 import getopt
58 import string
61 def main():
62 QSIZE = 16
63 TIME = 5
64 audio = 0
66 opts, args = getopt.getopt(sys.argv[1:], 'aq:t:')
67 for opt, arg in opts:
68 if opt == '-a':
69 audio = 1
70 elif opt == '-q':
71 QSIZE = string.atoi(arg)
72 elif opt == '-t':
73 TIME = string.atoi(arg)
75 if args:
76 filename = args[0]
77 else:
78 filename = 'film.video'
80 if audio:
81 if args[1:]:
82 audiofilename = args[1]
83 else:
84 audiofilename = 'film.aiff'
86 gl.foreground()
88 x, y = SV.PAL_XMAX / 4, SV.PAL_YMAX / 4
89 print x, 'x', y
91 gl.minsize(40, 30)
92 gl.stepunit(8, 6)
93 gl.maxsize(SV.PAL_XMAX, SV.PAL_YMAX)
94 gl.keepaspect(SV.PAL_XMAX, SV.PAL_YMAX)
95 win = gl.winopen(filename)
96 x, y = gl.getsize()
97 print x, 'x', y
99 v = sv.OpenVideo()
100 v.BindGLWindow(win, SV.IN_REPLACE)
101 v.SetSize(x, y)
102 v.BindGLWindow(win, SV.IN_REPLACE)
104 v.SetCaptureFormat(SV.RGB_FRAMES)
105 v.SetCaptureMode(SV.BLOCKING_CAPTURE)
106 v.SetQueueSize(QSIZE)
107 v.InitCapture()
108 if v.GetQueueSize() != QSIZE:
109 QSIZE = v.GetQueueSize()
110 print 'Warning: QSIZE reduced to', QSIZE
112 gl.qdevice(DEVICE.LEFTMOUSE)
113 gl.qdevice(DEVICE.WINQUIT)
114 gl.qdevice(DEVICE.WINSHUT)
115 gl.qdevice(DEVICE.ESCKEY)
117 print 'Click left mouse to start recording', TIME, 'seconds'
118 ofile = None
119 afile = None
120 # Mouse down opens the file & freezes window
121 # Mouse up starts recording frames
123 while 1:
124 dev, val = gl.qread()
125 if dev == DEVICE.LEFTMOUSE:
126 # Start recording
127 if val == 1:
128 # Mouse down -- preparations
129 if ofile == None:
130 ofile = VFile.VoutFile().init(filename)
131 ofile.format = 'rgb8'
132 ofile.width = x
133 ofile.height = y
134 ofile.writeheader()
135 # XXX other format bits?
136 # The window can't be resized from now
137 gl.prefsize(x, y)
138 gl.winconstraints()
139 gl.wintitle('* ' + filename)
140 if audio:
141 afile = initaudio(audiofilename)
142 continue
143 # Mouse up -- start actual recording
144 global recording, stop_recording
145 if audio:
146 stop_recording = 0
147 recording.release()
148 t0 = time.millitimer()
149 v.StartCapture()
150 while 1:
151 t = time.millitimer() - t0
152 if t >= TIME*1000:
153 break
154 if v.GetCaptured() > 2:
155 doframe(v, ofile, x, y, t)
156 v.StopCapture()
157 stop_recording = 1
158 while v.GetCaptured() > 0:
159 doframe(v, ofile, x, y, t)
160 t = time.millitimer() - t0
161 gl.wintitle(filename)
162 elif dev == DEVICE.REDRAW:
163 # Window resize (or move)
164 x, y = gl.getsize()
165 print x, 'x', y
166 v.SetSize(x, y)
167 v.BindGLWindow(win, SV.IN_REPLACE)
168 elif dev in (DEVICE.ESCKEY, DEVICE.WINQUIT, DEVICE.WINSHUT):
169 # Quit
170 if ofile:
171 ofile.close()
172 if afile:
173 afile.destroy()
174 posix._exit(0)
175 # EndCapture dumps core...
176 v.EndCapture()
177 v.CloseVideo()
178 gl.winclose(win)
180 def doframe(v, ofile, x, y, t):
181 cd, start = v.GetCaptureData()
182 data = cd.interleave(x, y)
183 cd.UnlockCaptureData()
184 ofile.writeframe(t, data, None)
186 AQSIZE = 16000
188 def initaudio(filename):
189 import thread, aiff
190 global recording, stop_recording
191 afile = aiff.Aiff().init(filename, 'w')
192 afile.nchannels = AL.MONO
193 afile.sampwidth = AL.SAMPLE_8
194 params = [AL.INPUT_RATE, 0]
195 al.getparams(AL.DEFAULT_DEVICE, params)
196 print 'rate =', params[1]
197 afile.samprate = params[1]
198 c = al.newconfig()
199 c.setchannels(AL.MONO)
200 c.setqueuesize(AQSIZE)
201 c.setwidth(AL.SAMPLE_8)
202 aport = al.openport(filename, 'r', c)
203 recording = thread.allocate_lock()
204 recording.acquire()
205 stop_recording = 0
206 thread.start_new_thread(recorder, (afile, aport))
207 return afile
209 def recorder(afile, aport):
210 # XXX recording more than one fragment doesn't work
211 # XXX (the thread never dies)
212 recording.acquire()
213 while not stop_recording:
214 data = aport.readsamps(AQSIZE/2)
215 afile.writesampsraw(data)
216 del data
218 main()