From 5395c067dea68bd1e052b6c05ed9293bffb2a22d Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 4 Nov 1991 14:31:54 +0000 Subject: [PATCH] Made much faster, but for SHORT movies only, by saving lrectread data unprocessed in memory. As long as memory doesn't run out this gets us 19 frames/sec! Also many cosmetic changes. --- Demo/sgi/video/camcorder.py | 160 ++++++++++++++++++++++++++---------- 1 file changed, 115 insertions(+), 45 deletions(-) diff --git a/Demo/sgi/video/camcorder.py b/Demo/sgi/video/camcorder.py index a6b7f4a0408..63a4f743fa2 100755 --- a/Demo/sgi/video/camcorder.py +++ b/Demo/sgi/video/camcorder.py @@ -1,4 +1,3 @@ -#!/ufs/guido/bin/sgi/python3.3 from gl import * from GL import * from DEVICE import * @@ -9,15 +8,14 @@ import socket import posix import vtime +# Preallocation parameter +PREALLOC = 8 # Megabyte + +# Sync audio parameters SYNCPORT = 10000 CTLPORT = 10001 -VP_GBXORG = 0x1000001 -VP_GBYORG = 0x1000002 -VP_FBXORG = 0x1000003 -VP_FBYORG = 0x1000004 -VP_WIDTH = 0x1000005 -VP_HEIGHT = 0x1000006 +from vpregs import * class Struct(): pass epoch = Struct() @@ -25,17 +23,52 @@ epoch = Struct() def getvideosize(): w = getvideo(VP_WIDTH) h = getvideo(VP_HEIGHT) - print getvideo(VP_GBXORG), getvideo(VP_GBYORG) - print getvideo(VP_FBXORG), getvideo(VP_FBYORG) + print 'WIDTH,HEIGHT:', w, h + print 'GB{X,Y}ORG:', getvideo(VP_GBXORG), getvideo(VP_GBYORG) + print 'FB{X,Y}ORG:', getvideo(VP_FBXORG), getvideo(VP_FBYORG) x = 0 y = 0 return x,y,w,h + +framelist = [] + +def prealloc(w, h): + nbytes = w*h*4 + limit = PREALLOC*1024*1024 + total = 0 + list = [] + print 'Prealloc to', PREALLOC, 'Megabytes...' + while total+nbytes <= limit: + list.append('x'*nbytes) + total = total + nbytes + print 'Done.' + +def grabframe(f,x,y,w,h,pf): +#### saveframes(f, w, h, pf) + readsource(SRC_FRONT) + if pf: + w = w/pf*pf + h = h/pf*pf + data = lrectread(x,y,x+w-1,y+h-1) + t = time.millitimer()-epoch.epoch + framelist.append(data, t) + readsource(SRC_FRAMEGRABBER) + +def saveframes(f, w, h, pf): + for data, t in framelist: + if pf: + w = w/pf*pf + h = h/pf*pf + data = packrect(w,h,pf,data) + f.write(`t` + ',' + `len(data)` + '\n') + f.write(data) + framelist[:] = [] + def saveframe(f,x,y,w,h,pf, notime): readsource(SRC_FRONT) if pf: w = w/pf*pf h = h/pf*pf - data = None data = lrectread(x,y,x+w-1,y+h-1) if pf: data = packrect(w,h,pf,data) if notime: t = 0 @@ -43,6 +76,7 @@ def saveframe(f,x,y,w,h,pf, notime): f.write(`t` + ',' + `len(data)` + '\n') f.write(data) readsource(SRC_FRAMEGRABBER) + def drawframe(x,y,w,h,col): drawmode(OVERDRAW) color(col) @@ -50,12 +84,25 @@ def drawframe(x,y,w,h,col): v2i(x-1,y-1) ; v2i(x+w,y-1); v2i(x+w,y+h); v2i(x-1,y+h); v2i(x-1,y-1) endline() drawmode(NORMALDRAW) + +def usage(): + sys.stderr.write('Usage: camcorder ' + \ + '[-c] [-p packfactor] [-a audiomachine [-s]] [outputfile]\n') + sys.exit(2) + +def wrheader(f, w, h, pf): + f.write('CMIF video 1.0\n') + f.write(`w,h,pf` + '\n') + print 'width,height,pf:', w, h, pf, + if pf = 0: pf = 4 + print '(i.e.,', w*h*pf, 'bytes/frame)' + def main(): foreground() pf = 2 ausync = 0 austart = 0 - optlist, args = getopt.getopt(sys.argv[1:],'ca:s') + optlist, args = getopt.getopt(sys.argv[1:],'ca:sp:') for opt, arg in optlist: if opt = '-c': pf = 0 @@ -64,13 +111,21 @@ def main(): aumachine = arg elif opt = '-s': austart = 1 + elif opt = '-p': + pf = int(eval(arg)) else: - print 'Usage: camcorder [-c] [-a audiomachine [-s]]' - sys.exit(1) + usage() + if args: + if len(args) > 1: + print 'Too many arguments' + usage() + filename = args[0] + else: + filename = 'film.video' if austart: if not ausync: print 'Cannot use -s without -a' - sys.exit(1) + usage() print 'Starting audio recorder...' posix.system('rsh '+aumachine+' syncrecord '+socket.gethostname()+' &') if ausync: @@ -81,15 +136,14 @@ def main(): aua = (socket.gethostbyname(aumachine), CTLPORT) print 'Done.' vidx, vidy, w, h = getvideosize() - prefsize(w,h) - win = winopen('Camcorder') - if len(args) > 1: - f = open(args, 'w') - else: - f = open('film.video', 'w') + #prefsize(w,h) + winx, winy = 1280-w-10, 1024-h-30 + prefposition(winx,winx+w-1,winy,winy+h-1) + win = winopen(filename) + f = open(filename, 'w') w, h = getsize() realw, realh = w, h - doublebuffer() + #doublebuffer() RGBmode() gconfig() qdevice(LEFTMOUSE) @@ -98,6 +152,8 @@ def main(): qdevice(CKEY) qdevice(PKEY) qdevice(ESCKEY) + qdevice(WINQUIT) + qdevice(WINSHUT) inrunning = 1 outrunning = 0 stop = 'stop' @@ -108,9 +164,10 @@ def main(): sizewritten = 0 x, y = realw/4, realh/4 w, h = w/2, h/2 - drawframe(x,y,w,h,1) - nframe = 0 + prealloc(w, h) try: + drawframe(x,y,w,h,1) + nframe = 0 num = 0 while 1: insingle = 0 @@ -125,7 +182,8 @@ def main(): w = getvaluator(MOUSEX)-x-ox h = getvaluator(MOUSEY)-y-oy drawframe(x,y,w,h,1) - if qtest(): + if qtest() or \ + not (mousing or inrunning or insingle or outrunning or outsingle): ev, val = qread() if ev = LEFTMOUSE and val = 1: drawframe(x,y,w,h,0) @@ -134,12 +192,16 @@ def main(): x = getvaluator(MOUSEX)-ox y = getvaluator(MOUSEY)-oy elif ev = LEFTMOUSE and val = 0: + if h < 0: + y, h = y+h, -h + if w < 0: + x, w = x+w, -w mousing = 0 if not sizewritten: - f.write('CMIF video 1.0\n') - f.write(`w,h,pf` + '\n') + wrheader(f, w, h, pf) sizewritten = 1 - if ev = RKEY and val = 1: + prealloc(w, h) + elif ev = RKEY and val = 1: if not inrunning: ringbell() else: @@ -155,14 +217,12 @@ def main(): stoptime = time.millitimer() if ausync: ctl.sendto(`(0,stoptime)`, aua) - nf = nframe * 1000.0 / (time.millitimer()-starttime) - drawmode(OVERDRAW) - color(0) - clear() - color(1) - cmov2i(5,5) - charstr('Recorded ' + `nf` + ' frames/sec') - drawmode(NORMALDRAW) + fps = nframe * 1000.0 / (time.millitimer()-starttime) + print 'Recorded', nframe, + print 'frames at', 0.1*int(fps*10),'frames/sec' + print 'Saving...' + saveframes(f, w, h, pf) + print 'Done.' elif ev = PKEY and val = 1 and not outrunning: outsingle = 1 elif ev = CKEY and val = 1: @@ -174,24 +234,34 @@ def main(): inrunning = 0 else: insingle = 1 - elif ev = ESCKEY: + elif ev in (ESCKEY, WINQUIT, WINSHUT): if ausync: ctl.sendto(`(2,time.millitimer())`, aua) raise stop + elif ev = REDRAW: + drawframe(x,y,w,h,0) + reshapeviewport() + drawframe(x,y,w,h,1) if inrunning or insingle: - rectcopy(vidx,vidy,realw,realh,0,0) - swapbuffers() + if outrunning: + rectcopy(vidx+x,vidy+y,vidx+x+w-1,vidy+y+h-1,x,y) + else: + rectcopy(vidx,vidy,vidx+realw-1,vidx+realh-1,0,0) + #swapbuffers() if outrunning or outsingle: nframe = nframe + 1 if not sizewritten: - f.write('CMIF video 1.0\n') - f.write(`w,h,pf` + '\n') + wrheader(f, w, h, pf) sizewritten = 1 - saveframe(f, x, y, w, h, pf, outsingle) + if outrunning: + grabframe(f, x, y, w, h, pf) + else: + saveframe(f, x, y, w, h, pf, outsingle) except stop: pass - drawmode(OVERDRAW) - color(0) - clear() -# + finally: + drawmode(OVERDRAW) + color(0) + clear() + main()