| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | # -q queuesize  : set the capture queue size (default 2) | 
					
						
							|  |  |  | # -r rate       : capture 1 out of every n frames (default and min 2) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | #  | 
					
						
							|  |  |  | # 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 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | # recording.  You can record as many times as you wish, but each time | 
					
						
							|  |  |  | # you overwrite the output file(s), so only the last recording is | 
					
						
							|  |  |  | # kept. | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # Press ESC or select the window manager Quit or Close window option | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | # to quit.  If you quit before recording anything, the output file(s) | 
					
						
							|  |  |  | # are not touched. | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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(): | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	format = SV.RGB8_FRAMES | 
					
						
							|  |  |  | 	qsize = 2 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	audio = 0 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	rate = 2 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	opts, args = getopt.getopt(sys.argv[1:], 'aq:r:') | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	for opt, arg in opts: | 
					
						
							|  |  |  | 		if opt == '-a': | 
					
						
							|  |  |  | 			audio = 1 | 
					
						
							|  |  |  | 		elif opt == '-q': | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 			qsize = string.atoi(arg) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 		elif opt == '-r': | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 			rate = string.atoi(arg) | 
					
						
							|  |  |  | 			if rate < 2: | 
					
						
							|  |  |  | 				sys.stderr.write('-r rate must be >= 2\n') | 
					
						
							|  |  |  | 				sys.exit(2) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	# XXX should remove PAL dependencies | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	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.SetSize(x, y) | 
					
						
							|  |  |  | 	v.BindGLWindow(win, SV.IN_REPLACE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while 1: | 
					
						
							|  |  |  | 		dev, val = gl.qread() | 
					
						
							|  |  |  | 		if dev == DEVICE.LEFTMOUSE: | 
					
						
							|  |  |  | 			if val == 1: | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 				info = format, x, y, qsize, rate | 
					
						
							|  |  |  | 				record(v, info, filename, audiofilename) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 		elif dev == DEVICE.REDRAW: | 
					
						
							|  |  |  | 			# Window resize (or move) | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 			x, y = gl.getsize() | 
					
						
							|  |  |  | 			print x, 'x', y | 
					
						
							|  |  |  | 			v.SetSize(x, y) | 
					
						
							|  |  |  | 			v.BindGLWindow(win, SV.IN_REPLACE) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 		elif dev in (DEVICE.ESCKEY, DEVICE.WINQUIT, DEVICE.WINSHUT): | 
					
						
							|  |  |  | 			# Quit | 
					
						
							|  |  |  | 			v.CloseVideo() | 
					
						
							|  |  |  | 			gl.winclose(win) | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Record until the mouse is released (or any other GL event) | 
					
						
							|  |  |  | # XXX audio not yet supported | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | def record(v, info, filename, audiofilename): | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	import thread | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	format, x, y, qsize, rate = info | 
					
						
							|  |  |  | 	fps = 59.64 # Fields per second | 
					
						
							|  |  |  | 	# XXX (Strange: need fps of Indigo monitor, not of PAL or NTSC!) | 
					
						
							|  |  |  | 	tpf = 1000.0 / fps # Time per field in msec | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	vout = VFile.VoutFile().init(filename) | 
					
						
							|  |  |  | 	vout.format = 'rgb8' | 
					
						
							|  |  |  | 	vout.width = x | 
					
						
							|  |  |  | 	vout.height = y | 
					
						
							|  |  |  | 	vout.writeheader() | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	MAXSIZE = 20 # XXX should be a user option | 
					
						
							|  |  |  | 	import Queue | 
					
						
							|  |  |  | 	queue = Queue.Queue().init(MAXSIZE) | 
					
						
							|  |  |  | 	done = thread.allocate_lock() | 
					
						
							|  |  |  | 	done.acquire_lock() | 
					
						
							|  |  |  | 	thread.start_new_thread(saveframes, (vout, queue, done)) | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 	if audiofilename: | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 		audiodone = thread.allocate_lock() | 
					
						
							|  |  |  | 		audiodone.acquire_lock() | 
					
						
							|  |  |  | 		audiostop = [] | 
					
						
							|  |  |  | 		initaudio(audiofilename, audiostop, audiodone) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	gl.wintitle('(rec) ' + filename) | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	lastid = 0 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	t0 = time.millitimer() | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	v.InitContinuousCapture(info) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	while not gl.qtest(): | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 		try: | 
					
						
							|  |  |  | 			cd, id = v.GetCaptureData() | 
					
						
							|  |  |  | 		except RuntimeError: | 
					
						
							|  |  |  | 			time.millisleep(10) # XXX is this necessary? | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		id = id + 2*rate | 
					
						
							|  |  |  | ##		if id <> lastid + 2*rate: | 
					
						
							|  |  |  | ##			print lastid, id | 
					
						
							|  |  |  | 		lastid = id | 
					
						
							|  |  |  | 		data = cd.InterleaveFields(1) | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 		cd.UnlockCaptureData() | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 		queue.put(data, int(id*tpf)) | 
					
						
							|  |  |  | 	t1 = time.millitimer() | 
					
						
							|  |  |  | 	gl.wintitle('(busy) ' + filename) | 
					
						
							|  |  |  | 	print lastid, 'fields in', t1-t0, 'msec', | 
					
						
							|  |  |  | 	print '--', 0.1 * int(lastid * 10000.0 / (t1-t0)), 'fields/sec' | 
					
						
							|  |  |  | 	if audiofilename: | 
					
						
							|  |  |  | 		audiostop.append(None) | 
					
						
							|  |  |  | 		audiodone.acquire_lock() | 
					
						
							|  |  |  | 	v.EndContinuousCapture() | 
					
						
							|  |  |  | 	queue.put(None) # Sentinel | 
					
						
							|  |  |  | 	done.acquire_lock() | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	gl.wintitle('(done) ' + filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Thread to save the frames to the file | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | def saveframes(vout, queue, done): | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	while 1: | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 		x = queue.get() | 
					
						
							|  |  |  | 		if not x: | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		data, t = x | 
					
						
							|  |  |  | 		vout.writeframe(t, data, None) | 
					
						
							|  |  |  | 		del data | 
					
						
							|  |  |  | 	sys.stderr.write('Done writing video\n') | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 	vout.close() | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	done.release_lock() | 
					
						
							| 
									
										
										
										
											1992-08-20 11:46:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | # Initialize audio recording | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | AQSIZE = 8000 # XXX should be a user option | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | def initaudio(filename, stop, done): | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	thread.start_new_thread(audiorecord, (afile, aport, stop, done)) | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | def audiorecord(afile, aport, stop, done): | 
					
						
							|  |  |  | 	while not stop: | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 		data = aport.readsamps(AQSIZE/2) | 
					
						
							|  |  |  | ##		afile.writesampsraw(data) | 
					
						
							|  |  |  | 		afile.writesamps(data) | 
					
						
							|  |  |  | 		del data | 
					
						
							|  |  |  | 	afile.destroy() | 
					
						
							|  |  |  | 	print 'Done writing audio' | 
					
						
							| 
									
										
										
										
											1992-09-03 16:56:04 +00:00
										 |  |  | 	done.release_lock() | 
					
						
							| 
									
										
										
										
											1992-08-20 14:46:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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]' |