| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | #! /ufs/guido/bin/sgi/python-405 | 
					
						
							|  |  |  | #! /ufs/guido/bin/sgi/python | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Capture a CMIF movie using the Indigo video library and board | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Usage: | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # makemovie [-a] [-q queuesize] [-r n/d] [moviefile [audiofile]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Options: | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # -a            : record audio as well | 
					
						
							|  |  |  | # -q queuesize  : set the capture queue size (default and max 16) | 
					
						
							|  |  |  | # -r n/d        : capture n out of every d frames (default 1/1) | 
					
						
							|  |  |  | #                 XXX doesn't work yet | 
					
						
							|  |  |  | #  | 
					
						
							|  |  |  | # moviefile     : here goes the movie data (default film.video); | 
					
						
							|  |  |  | #                 the format is documented in cmif-film.ms | 
					
						
							|  |  |  | # audiofile     : with -a, here goes the audio data (default film.aiff); | 
					
						
							|  |  |  | #                 audio data is recorded in AIFF format, using the | 
					
						
							|  |  |  | #                 input sampling rate, source and volume set by the | 
					
						
							|  |  |  | #                 audio panel, in mono, 8 bits/sample | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # User interface: | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Start the application.  Resize the window to the desired movie size. | 
					
						
							|  |  |  | # Press the left mouse button to start recording, release it to end | 
					
						
							|  |  |  | # recording.  XXX For now, you must restart the program to record again. | 
					
						
							|  |  |  | # You can't resize the window once you have made a recording. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Press ESC or select the window manager Quit or Close window option | 
					
						
							|  |  |  | # to quit.  (You can do this without recording -- then the output | 
					
						
							|  |  |  | # files are untouched.)  XXX Don't press ESC before the program has | 
					
						
							|  |  |  | # finished writing the output file -- it prints "Done writing" when it | 
					
						
							|  |  |  | # is done. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # XXX To do: | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # add audio | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | sys.path.append('/ufs/guido/src/video') | 
					
						
							|  |  |  | import sv, SV | 
					
						
							|  |  |  | import VFile | 
					
						
							|  |  |  | import gl, GL, DEVICE | 
					
						
							|  |  |  | import al, AL | 
					
						
							|  |  |  | import time | 
					
						
							|  |  |  | import posix | 
					
						
							|  |  |  | import getopt | 
					
						
							|  |  |  | import string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Main program | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(): | 
					
						
							|  |  |  | 	QSIZE = 16 | 
					
						
							|  |  |  | 	TIME = 5 | 
					
						
							|  |  |  | 	audio = 0 | 
					
						
							|  |  |  | 	num, den = 1, 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opts, args = getopt.getopt(sys.argv[1:], 'aq:r:t:') | 
					
						
							|  |  |  | 	for opt, arg in opts: | 
					
						
							|  |  |  | 		if opt == '-a': | 
					
						
							|  |  |  | 			audio = 1 | 
					
						
							|  |  |  | 		elif opt == '-q': | 
					
						
							|  |  |  | 			QSIZE = string.atoi(arg) | 
					
						
							|  |  |  | 		elif opt == '-r': | 
					
						
							|  |  |  | 			[nstr, dstr] = string.splitfields(arg, '/') | 
					
						
							|  |  |  | 			num, den = string.atoi(nstr), string.atoi(dstr) | 
					
						
							|  |  |  | 		elif opt == '-t': | 
					
						
							|  |  |  | 			TIME = string.atoi(arg) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 	if args[2:]: | 
					
						
							|  |  |  | 		sys.stderr.write('usage: Vrec [options] [file [audiofile]]\n') | 
					
						
							|  |  |  | 		sys.exit(2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	if args: | 
					
						
							|  |  |  | 		filename = args[0] | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		filename = 'film.video' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 	if args[1:] and not audio: | 
					
						
							|  |  |  | 		sys.stderr.write('-a turned on by appearance of 2nd file\n') | 
					
						
							|  |  |  | 		audio = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	if audio: | 
					
						
							|  |  |  | 		if args[1:]: | 
					
						
							|  |  |  | 			audiofilename = args[1] | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			audiofilename = 'film.aiff' | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		audiofilename = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gl.foreground() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	x, y = SV.PAL_XMAX / 4, SV.PAL_YMAX / 4 | 
					
						
							|  |  |  | 	print x, 'x', y | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gl.minsize(40, 30) | 
					
						
							|  |  |  | 	gl.stepunit(8, 6) | 
					
						
							|  |  |  | 	gl.maxsize(SV.PAL_XMAX, SV.PAL_YMAX) | 
					
						
							|  |  |  | 	gl.keepaspect(SV.PAL_XMAX, SV.PAL_YMAX) | 
					
						
							|  |  |  | 	win = gl.winopen(filename) | 
					
						
							|  |  |  | 	x, y = gl.getsize() | 
					
						
							|  |  |  | 	print x, 'x', y | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v = sv.OpenVideo() | 
					
						
							|  |  |  | 	v.BindGLWindow(win, SV.IN_REPLACE) | 
					
						
							|  |  |  | 	v.SetSize(x, y) | 
					
						
							|  |  |  | 	v.BindGLWindow(win, SV.IN_REPLACE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v.SetCaptureFormat(SV.RGB_FRAMES) | 
					
						
							|  |  |  | 	v.SetCaptureMode(SV.BLOCKING_CAPTURE) | 
					
						
							|  |  |  | 	v.SetQueueSize(QSIZE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v.InitCapture() | 
					
						
							|  |  |  | 	if v.GetQueueSize() != QSIZE: | 
					
						
							|  |  |  | 		QSIZE = v.GetQueueSize() | 
					
						
							|  |  |  | 		print 'Warning: QSIZE reduced to', QSIZE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ###	v.SetSamplingRate(num, den) # XXX dumps core | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gl.qdevice(DEVICE.LEFTMOUSE) | 
					
						
							|  |  |  | 	gl.qdevice(DEVICE.WINQUIT) | 
					
						
							|  |  |  | 	gl.qdevice(DEVICE.WINSHUT) | 
					
						
							|  |  |  | 	gl.qdevice(DEVICE.ESCKEY) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	print 'Press left mouse to start recording, release it to stop' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	recorded = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while 1: | 
					
						
							|  |  |  | 		dev, val = gl.qread() | 
					
						
							|  |  |  | 		if dev == DEVICE.LEFTMOUSE: | 
					
						
							|  |  |  | 			if val == 1: | 
					
						
							|  |  |  | 				if recorded: | 
					
						
							|  |  |  | 					# XXX This would dump core | 
					
						
							|  |  |  | 					gl.ringbell() | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				# Fix the window's size now | 
					
						
							|  |  |  | 				gl.prefsize(x, y) | 
					
						
							|  |  |  | 				gl.winconstraints() | 
					
						
							|  |  |  | 				record(v, filename, audiofilename) | 
					
						
							|  |  |  | 				recorded = 1 | 
					
						
							|  |  |  | 				print 'Wait until "Done writing" is printed!' | 
					
						
							|  |  |  | 		elif dev == DEVICE.REDRAW: | 
					
						
							|  |  |  | 			# Window resize (or move) | 
					
						
							|  |  |  | 			if not recorded: | 
					
						
							|  |  |  | 				x, y = gl.getsize() | 
					
						
							|  |  |  | 				print x, 'x', y | 
					
						
							|  |  |  | 				v.SetSize(x, y) | 
					
						
							|  |  |  | 				v.BindGLWindow(win, SV.IN_REPLACE) | 
					
						
							|  |  |  | 		elif dev in (DEVICE.ESCKEY, DEVICE.WINQUIT, DEVICE.WINSHUT): | 
					
						
							|  |  |  | 			# Quit | 
					
						
							|  |  |  | 			if not recorded: | 
					
						
							|  |  |  | 				# XXX Avoid core dump in EndCapture | 
					
						
							|  |  |  | 				posix._exit(0) | 
					
						
							|  |  |  | 			v.EndCapture() | 
					
						
							|  |  |  | 			v.CloseVideo() | 
					
						
							|  |  |  | 			gl.winclose(win) | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Record until the mouse is released (or any other GL event) | 
					
						
							|  |  |  | # XXX audio not yet supported | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def record(v, filename, audiofilename): | 
					
						
							|  |  |  | 	import thread | 
					
						
							|  |  |  | 	x, y = gl.getsize() | 
					
						
							|  |  |  | 	vout = VFile.VoutFile().init(filename) | 
					
						
							|  |  |  | 	vout.format = 'rgb8' | 
					
						
							|  |  |  | 	vout.width = x | 
					
						
							|  |  |  | 	vout.height = y | 
					
						
							|  |  |  | 	vout.writeheader() | 
					
						
							|  |  |  | 	buffer = [] | 
					
						
							|  |  |  | 	thread.start_new_thread(saveframes, (vout, buffer)) | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 	if audiofilename: | 
					
						
							|  |  |  | 		initaudio(audiofilename, buffer) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	gl.wintitle('(rec) ' + filename) | 
					
						
							|  |  |  | 	v.StartCapture() | 
					
						
							|  |  |  | 	t0 = time.millitimer() | 
					
						
							|  |  |  | 	while not gl.qtest(): | 
					
						
							|  |  |  | 		if v.GetCaptured() > 2: | 
					
						
							|  |  |  | 			t = time.millitimer() - t0 | 
					
						
							|  |  |  | 			cd, st = v.GetCaptureData() | 
					
						
							|  |  |  | 			data = cd.interleave(x, y) | 
					
						
							|  |  |  | 			cd.UnlockCaptureData() | 
					
						
							|  |  |  | 			buffer.append(data, t) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			time.millisleep(10) | 
					
						
							|  |  |  | 	v.StopCapture() | 
					
						
							|  |  |  | 	while v.GetCaptured() > 0: | 
					
						
							|  |  |  | 		t = time.millitimer() - t0 | 
					
						
							|  |  |  | 		cd, st = v.GetCaptureData() | 
					
						
							|  |  |  | 		data = cd.interleave(x, y) | 
					
						
							|  |  |  | 		cd.UnlockCaptureData() | 
					
						
							|  |  |  | 		buffer.append(data, t) | 
					
						
							|  |  |  | 	buffer.append(None) # Sentinel | 
					
						
							|  |  |  | 	gl.wintitle('(done) ' + filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Thread to save the frames to the file | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def saveframes(vout, buffer): | 
					
						
							|  |  |  | 	while 1: | 
					
						
							|  |  |  | 		if not buffer: | 
					
						
							|  |  |  | 			time.millisleep(10) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			x = buffer[0] | 
					
						
							|  |  |  | 			if not x: | 
					
						
							|  |  |  | 				break | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 			del buffer[0] | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 			data, t = x | 
					
						
							|  |  |  | 			vout.writeframe(t, data, None) | 
					
						
							|  |  |  | 			del data | 
					
						
							|  |  |  | 	sys.stderr.write('Done writing\n') | 
					
						
							|  |  |  | 	vout.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | # Initialize audio recording | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AQSIZE = 8000 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def initaudio(filename, buffer): | 
					
						
							|  |  |  | 	import thread, aiff | 
					
						
							|  |  |  | 	afile = aiff.Aiff().init(filename, 'w') | 
					
						
							|  |  |  | 	afile.nchannels = AL.MONO | 
					
						
							|  |  |  | 	afile.sampwidth = AL.SAMPLE_8 | 
					
						
							|  |  |  | 	params = [AL.INPUT_RATE, 0] | 
					
						
							|  |  |  | 	al.getparams(AL.DEFAULT_DEVICE, params) | 
					
						
							|  |  |  | 	print 'audio sampling rate =', params[1] | 
					
						
							|  |  |  | 	afile.samprate = params[1] | 
					
						
							|  |  |  | 	c = al.newconfig() | 
					
						
							|  |  |  | 	c.setchannels(AL.MONO) | 
					
						
							|  |  |  | 	c.setqueuesize(AQSIZE) | 
					
						
							|  |  |  | 	c.setwidth(AL.SAMPLE_8) | 
					
						
							|  |  |  | 	aport = al.openport(filename, 'r', c) | 
					
						
							|  |  |  | 	thread.start_new_thread(audiorecord, (afile, aport, buffer)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Thread to record audio samples | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # XXX should use writesampsraw for efficiency, but then destroy doesn't | 
					
						
							|  |  |  | # XXX seem to set the #samples in the header correctly | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def audiorecord(afile, aport, buffer): | 
					
						
							|  |  |  | 	while buffer[-1:] <> [None]: | 
					
						
							|  |  |  | 		data = aport.readsamps(AQSIZE/2) | 
					
						
							|  |  |  | ##		afile.writesampsraw(data) | 
					
						
							|  |  |  | 		afile.writesamps(data) | 
					
						
							|  |  |  | 		del data | 
					
						
							|  |  |  | 	afile.destroy() | 
					
						
							|  |  |  | 	print 'Done writing audio' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | # Don't forget to call the main program | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-01 14:45:57 +00:00
										 |  |  | try: | 
					
						
							|  |  |  | 	main() | 
					
						
							|  |  |  | except KeyboardInterrupt: | 
					
						
							|  |  |  | 	print '[Interrupt]' |