home *** CD-ROM | disk | FTP | other *** search
- #! /usr/bin/env python
-
- # Play CMIF movie files
-
-
- # Help function
-
- def help():
- print 'Usage: Vplay [options] [file] ...'
- print
- print 'Options:'
- print '-M magnify : magnify the image by the given factor'
- print '-d : write some debug stuff on stderr'
- print '-l : loop, playing the movie over and over again'
- print '-m delta : drop frames closer than delta seconds (default 0.)'
- print '-n : don\'t wait after each file'
- print '-q : quiet, no informative messages'
- print '-r delta : regenerate input time base delta seconds apart'
- print '-s speed : speed change factor (default 1.0)'
- print '-t : use a 2nd thread for read-ahead'
- print '-x left : window offset from left of screen'
- print '-y top : window offset from top of screen'
- print '-w width : window width'
- print '-h height : window height'
- print '-b color : background color (white,black or (r,g,b))'
- print 'file ... : file(s) to play; default film.video'
- print
- print 'User interface:'
- print 'Press the left mouse button to stop or restart the movie.'
- print 'Press ESC or use the window manager Close or Quit command'
- print 'to close the window and play the next file (if any).'
-
-
- # Imported modules
-
- import sys
- sys.path.append('/ufs/guido/src/video') # Increase chance of finding VFile
- import VFile
- import time
- import gl, GL
- from DEVICE import REDRAW, ESCKEY, LEFTMOUSE, WINSHUT, WINQUIT
- import getopt
- import string
-
-
- # Global options
-
- debug = 0
- looping = 0
- magnify = 1
- mindelta = 0
- nowait = 0
- quiet = 0
- regen = None
- speed = 1.0
- threading = 0
- xoff = yoff = None
- xwsiz = ywsiz = None
- bgcolor = None
-
-
- # Main program -- mostly command line parsing
-
- def main():
- global debug, looping, magnify, mindelta, nowait, quiet, regen, speed
- global threading, xoff, yoff, xwsiz, ywsiz, bgcolor
-
- # Parse command line
- try:
- opts, args = getopt.getopt(sys.argv[1:], \
- 'M:dlm:nqr:s:tx:y:w:h:b:')
- except getopt.error, msg:
- sys.stdout = sys.stderr
- print 'Error:', msg, '\n'
- help()
- sys.exit(2)
-
- # Interpret options
- try:
- for opt, arg in opts:
- if opt == '-M': magnify = float(eval(arg))
- if opt == '-d': debug = debug + 1
- if opt == '-l': looping = 1
- if opt == '-m': mindelta = float(eval(arg))
- if opt == '-n': nowait = 1
- if opt == '-q': quiet = 1
- if opt == '-r': regen = float(eval(arg))
- if opt == '-s':
- try:
- speed = float(eval(arg))
- except:
- sys.stdout = sys.stderr
- print 'Option -s needs float argument'
- sys.exit(2)
- if opt == '-t':
- try:
- import thread
- threading = 1
- except ImportError:
- print 'Sorry, this version of Python',
- print 'does not support threads:',
- print '-t ignored'
- if opt == '-x': xoff = string.atoi(arg)
- if opt == '-y': yoff = string.atoi(arg)
- if opt == '-w': xwsiz = string.atoi(arg)
- if opt == '-h': ywsiz = string.atoi(arg)
- if opt == '-b':
- if arg == 'black':
- bgcolor = (0,0,0)
- elif arg == 'white':
- bgcolor = (255,255,255)
- else:
- try:
- bgcolor = eval(arg)
- xxr, xxg, xxb = bgcolor
- except:
- print '-b needs (r,g,b) tuple'
- sys.exit(2)
- except string.atoi_error:
- sys.stdout = sys.stderr
- print 'Option', opt, 'requires integer argument'
- sys.exit(2)
-
- # Check validity of certain options combinations
- if nowait and looping:
- print 'Warning: -n and -l are mutually exclusive; -n ignored'
- nowait = 0
- if xoff <> None and yoff == None:
- print 'Warning: -x without -y ignored'
- if xoff == None and yoff <> None:
- print 'Warning: -y without -x ignored'
-
- # Process all files
- if not args: args = ['film.video']
- sts = 0
- for filename in args:
- sts = (process(filename) or sts)
-
- # Exit with proper exit status
- sys.exit(sts)
-
-
- # Process one movie file
-
- def process(filename):
- try:
- vin = VFile.VinFile(filename)
- except IOError, msg:
- sys.stderr.write(filename + ': I/O error: ' + `msg` + '\n')
- return 1
- except VFile.Error, msg:
- sys.stderr.write(msg + '\n')
- return 1
- except EOFError:
- sys.stderr.write(filename + ': EOF in video header\n')
- return 1
-
- if not quiet:
- vin.printinfo()
-
- gl.foreground()
-
- width, height = int(vin.width * magnify), int(vin.height * magnify)
- xborder = yborder = 0
- if xwsiz:
- vin.xorigin = (xwsiz - width)/2
- width = xwsiz
- if ywsiz:
- vin.yorigin = (ywsiz - height)/2
- height = ywsiz
- if xoff <> None and yoff <> None:
- scrheight = gl.getgdesc(GL.GD_YPMAX)
- gl.prefposition(xoff, xoff+width-1, \
- scrheight-yoff-height, scrheight-yoff-1)
- else:
- gl.prefsize(width, height)
-
- win = gl.winopen(filename)
- gl.clear()
-
- if quiet: vin.quiet = 1
- vin.initcolormap()
-
- if bgcolor:
- r, g, b = bgcolor
- vin.clearto(r,g,b)
-
- gl.qdevice(ESCKEY)
- gl.qdevice(WINSHUT)
- gl.qdevice(WINQUIT)
- gl.qdevice(LEFTMOUSE)
-
- stop = 0
-
- while not stop:
- gl.wintitle(filename)
- stop = (playonce(vin) or nowait)
- gl.wintitle('(done) ' + filename)
- if not looping:
- while not stop:
- dev, val = gl.qread()
- if dev == REDRAW:
- if bgcolor:
- r,g,b = bgcolor
- vin.clearto(r,g,b)
- else:
- vin.clear()
- if dev == LEFTMOUSE and val == 1:
- break # Continue outer loop
- if dev == ESCKEY and val == 1 or \
- dev in (WINSHUT, WINQUIT):
- stop = 1
-
- # Set xoff, yoff for the next window from the current window
- global xoff, yoff
- xoff, yoff = gl.getorigin()
- width, height = gl.getsize()
- scrheight = gl.getgdesc(GL.GD_YPMAX)
- yoff = scrheight - yoff - height
- gl.winclose(win)
-
- return 0
-
-
- # Play a movie once; return 1 if user wants to stop, 0 if not
-
- def playonce(vin):
- vin.rewind()
- vin.colormapinited = 1
- vin.magnify = magnify
-
- if threading:
- MAXSIZE = 20 # Don't read ahead too much
- import thread
- import Queue
- queue = Queue.Queue(MAXSIZE)
- stop = []
- thread.start_new_thread(read_ahead, (vin, queue, stop))
- # Get the read-ahead thread going
- while queue.qsize() < MAXSIZE/2 and not stop:
- time.sleep(0.100)
-
- tin = 0
- toffset = 0
- oldtin = 0
- told = 0
- nin = 0
- nout = 0
- nlate = 0
- nskipped = 0
- data = None
-
- tlast = t0 = time.time()
-
- while 1:
- if gl.qtest():
- dev, val = gl.qread()
- if dev == ESCKEY and val == 1 or \
- dev in (WINSHUT, WINQUIT) or \
- dev == LEFTMOUSE and val == 1:
- if debug: sys.stderr.write('\n')
- if threading:
- stop.append(None)
- while 1:
- item = queue.get()
- if item == None: break
- return (dev != LEFTMOUSE)
- if dev == REDRAW:
- gl.reshapeviewport()
- if data: vin.showframe(data, cdata)
- if threading:
- if debug and queue.empty(): sys.stderr.write('.')
- item = queue.get()
- if item == None: break
- tin, data, cdata = item
- else:
- try:
- tin, size, csize = vin.getnextframeheader()
- except EOFError:
- break
- tin = tin*0.001
- nin = nin+1
- if tin+toffset < oldtin:
- print 'Fix reversed time:', oldtin, 'to', tin
- toffset = oldtin - tin
- tin = tin + toffset
- oldtin = tin
- if regen: tout = nin * regen
- else: tout = tin
- tout = tout / speed
- if tout - told < mindelta:
- nskipped = nskipped + 1
- if not threading:
- vin.skipnextframedata(size, csize)
- else:
- if not threading:
- try:
- data, cdata = \
- vin.getnextframedata(size, csize)
- except EOFError:
- if not quiet:
- print '[incomplete last frame]'
- break
- now = time.time()
- dt = (tout-told) - (now-tlast)
- told = tout
- if debug: sys.stderr.write(`round(dt, 3)` + ' ')
- if dt < 0: nlate = nlate + 1
- if dt > 0:
- time.sleep(dt)
- now = time.time()
- tlast = now
- vin.showframe(data, cdata)
- nout = nout + 1
-
- t1 = time.time()
-
- if debug: sys.stderr.write('\n')
-
- if quiet: return 0
-
- print 'Recorded:', nin, 'frames in', round(tin, 3), 'sec.',
- if tin: print '-- average', round(nin/tin, 1), 'frames/sec',
- print
-
- if nskipped: print 'Skipped', nskipped, 'frames'
-
- tout = t1-t0
- print 'Played:', nout,
- print 'frames in', round(tout, 3), 'sec.',
- if tout: print '-- average', round(nout/tout, 1), 'frames/sec',
- print
-
- if nlate: print 'There were', nlate, 'late frames'
-
- return 0
-
-
- # Read-ahead thread
-
- def read_ahead(vin, queue, stop):
- try:
- while not stop: queue.put(vin.getnextframe())
- except EOFError:
- pass
- queue.put(None)
- stop.append(None)
-
-
- # Don't forget to call the main program
-
- try:
- main()
- except KeyboardInterrupt:
- print '[Interrupt]'
-