| #! /ufs/guido/bin/sgi/python |
| #! /ufs/guido/src/video/py |
| |
| # Capture a CMIF movie using the Indigo video library and board |
| |
| |
| # Usage: |
| # |
| # makemovie [-q queuesize] [-t recordtime] [-a] [moviefile [audiofile]] |
| |
| |
| # Options: |
| # |
| # -q queuesize : set the capture queue size (default and max 16) |
| # -t recordtime : set the record time in seconds (default 5 seconds) |
| # -a : record audio as well |
| # 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. |
| # Click the left mouse button to start recording (recording starts |
| # when you release the mouse button). Recording time is specified by |
| # the -t option (XXX this should change). |
| # |
| # 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.) |
| # |
| # (It is possible to record more than once; but this doesn't set the |
| # time stamps correctly yet, and doesn't work at all with audio. So |
| # don't use.) |
| |
| |
| # XXX To do: |
| # |
| # fix timestamps for second and further recordings |
| # fix audio " " " " " |
| # flush audio buffer when recording starts |
| # make code more readable |
| |
| |
| 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 |
| |
| |
| def main(): |
| QSIZE = 16 |
| TIME = 5 |
| audio = 0 |
| |
| opts, args = getopt.getopt(sys.argv[1:], 'aq:t:') |
| for opt, arg in opts: |
| if opt == '-a': |
| audio = 1 |
| elif opt == '-q': |
| QSIZE = string.atoi(arg) |
| elif opt == '-t': |
| TIME = string.atoi(arg) |
| |
| if args: |
| filename = args[0] |
| else: |
| filename = 'film.video' |
| |
| if audio: |
| if args[1:]: |
| audiofilename = args[1] |
| else: |
| audiofilename = 'film.aiff' |
| |
| 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 |
| |
| gl.qdevice(DEVICE.LEFTMOUSE) |
| gl.qdevice(DEVICE.WINQUIT) |
| gl.qdevice(DEVICE.WINSHUT) |
| gl.qdevice(DEVICE.ESCKEY) |
| |
| print 'Click left mouse to start recording', TIME, 'seconds' |
| ofile = None |
| afile = None |
| # Mouse down opens the file & freezes window |
| # Mouse up starts recording frames |
| |
| while 1: |
| dev, val = gl.qread() |
| if dev == DEVICE.LEFTMOUSE: |
| # Start recording |
| if val == 1: |
| # Mouse down -- preparations |
| if ofile == None: |
| ofile = VFile.VoutFile().init(filename) |
| ofile.format = 'rgb8' |
| ofile.width = x |
| ofile.height = y |
| ofile.writeheader() |
| # XXX other format bits? |
| # The window can't be resized from now |
| gl.prefsize(x, y) |
| gl.winconstraints() |
| gl.wintitle('* ' + filename) |
| if audio: |
| afile = initaudio(audiofilename) |
| continue |
| # Mouse up -- start actual recording |
| global recording, stop_recording |
| if audio: |
| stop_recording = 0 |
| recording.release() |
| t0 = time.millitimer() |
| v.StartCapture() |
| while 1: |
| t = time.millitimer() - t0 |
| if t >= TIME*1000: |
| break |
| if v.GetCaptured() > 2: |
| doframe(v, ofile, x, y, t) |
| v.StopCapture() |
| stop_recording = 1 |
| while v.GetCaptured() > 0: |
| doframe(v, ofile, x, y, t) |
| t = time.millitimer() - t0 |
| gl.wintitle(filename) |
| elif dev == DEVICE.REDRAW: |
| # Window resize (or move) |
| 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 ofile: |
| ofile.close() |
| if afile: |
| afile.destroy() |
| posix._exit(0) |
| # EndCapture dumps core... |
| v.EndCapture() |
| v.CloseVideo() |
| gl.winclose(win) |
| |
| def doframe(v, ofile, x, y, t): |
| cd, start = v.GetCaptureData() |
| data = cd.interleave(x, y) |
| cd.UnlockCaptureData() |
| ofile.writeframe(t, data, None) |
| |
| AQSIZE = 16000 |
| |
| def initaudio(filename): |
| import thread, aiff |
| global recording, stop_recording |
| 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 '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) |
| recording = thread.allocate_lock() |
| recording.acquire() |
| stop_recording = 0 |
| thread.start_new_thread(recorder, (afile, aport)) |
| return afile |
| |
| def recorder(afile, aport): |
| # XXX recording more than one fragment doesn't work |
| # XXX (the thread never dies) |
| recording.acquire() |
| while not stop_recording: |
| data = aport.readsamps(AQSIZE/2) |
| afile.writesampsraw(data) |
| del data |
| |
| main() |