219 lines
5.2 KiB
Python
Executable File
219 lines
5.2 KiB
Python
Executable File
#! /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()
|