3 # Play CMIF movie files
9 print 'Usage: Vplay [options] [file] ...'
12 print '-M magnify : magnify the image by the given factor'
13 print '-d : write some debug stuff on stderr'
14 print '-l : loop, playing the movie over and over again'
15 print '-m delta : drop frames closer than delta seconds (default 0.)'
16 print '-n : don\'t wait after each file'
17 print '-q : quiet, no informative messages'
18 print '-r delta : regenerate input time base delta seconds apart'
19 print '-s speed : speed change factor (default 1.0)'
20 print '-t : use a 2nd thread for read-ahead'
21 print '-x left : window offset from left of screen'
22 print '-y top : window offset from top of screen'
23 print '-w width : window width'
24 print '-h height : window height'
25 print '-b color : background color (white,black or (r,g,b))'
26 print 'file ... : file(s) to play; default film.video'
28 print 'User interface:'
29 print 'Press the left mouse button to stop or restart the movie.'
30 print 'Press ESC or use the window manager Close or Quit command'
31 print 'to close the window and play the next file (if any).'
37 sys
.path
.append('/ufs/guido/src/video') # Increase chance of finding VFile
41 from DEVICE
import REDRAW
, ESCKEY
, LEFTMOUSE
, WINSHUT
, WINQUIT
62 # Main program -- mostly command line parsing
65 global debug
, looping
, magnify
, mindelta
, nowait
, quiet
, regen
, speed
66 global threading
, xoff
, yoff
, xwsiz
, ywsiz
, bgcolor
70 opts
, args
= getopt
.getopt(sys
.argv
[1:], \
71 'M:dlm:nqr:s:tx:y:w:h:b:')
72 except getopt
.error
, msg
:
73 sys
.stdout
= sys
.stderr
74 print 'Error:', msg
, '\n'
81 if opt
== '-M': magnify
= float(eval(arg
))
82 if opt
== '-d': debug
= debug
+ 1
83 if opt
== '-l': looping
= 1
84 if opt
== '-m': mindelta
= float(eval(arg
))
85 if opt
== '-n': nowait
= 1
86 if opt
== '-q': quiet
= 1
87 if opt
== '-r': regen
= float(eval(arg
))
90 speed
= float(eval(arg
))
92 sys
.stdout
= sys
.stderr
93 print 'Option -s needs float argument'
100 print 'Sorry, this version of Python',
101 print 'does not support threads:',
103 if opt
== '-x': xoff
= string
.atoi(arg
)
104 if opt
== '-y': yoff
= string
.atoi(arg
)
105 if opt
== '-w': xwsiz
= string
.atoi(arg
)
106 if opt
== '-h': ywsiz
= string
.atoi(arg
)
111 bgcolor
= (255,255,255)
115 xxr
, xxg
, xxb
= bgcolor
117 print '-b needs (r,g,b) tuple'
119 except string
.atoi_error
:
120 sys
.stdout
= sys
.stderr
121 print 'Option', opt
, 'requires integer argument'
124 # Check validity of certain options combinations
125 if nowait
and looping
:
126 print 'Warning: -n and -l are mutually exclusive; -n ignored'
128 if xoff
<> None and yoff
== None:
129 print 'Warning: -x without -y ignored'
130 if xoff
== None and yoff
<> None:
131 print 'Warning: -y without -x ignored'
134 if not args
: args
= ['film.video']
136 for filename
in args
:
137 sts
= (process(filename
) or sts
)
139 # Exit with proper exit status
143 # Process one movie file
145 def process(filename
):
147 vin
= VFile
.VinFile(filename
)
149 sys
.stderr
.write(filename
+ ': I/O error: ' + `msg`
+ '\n')
151 except VFile
.Error
, msg
:
152 sys
.stderr
.write(msg
+ '\n')
155 sys
.stderr
.write(filename
+ ': EOF in video header\n')
163 width
, height
= int(vin
.width
* magnify
), int(vin
.height
* magnify
)
164 xborder
= yborder
= 0
166 vin
.xorigin
= (xwsiz
- width
)/2
169 vin
.yorigin
= (ywsiz
- height
)/2
171 if xoff
<> None and yoff
<> None:
172 scrheight
= gl
.getgdesc(GL
.GD_YPMAX
)
173 gl
.prefposition(xoff
, xoff
+width
-1, \
174 scrheight
-yoff
-height
, scrheight
-yoff
-1)
176 gl
.prefsize(width
, height
)
178 win
= gl
.winopen(filename
)
181 if quiet
: vin
.quiet
= 1
191 gl
.qdevice(LEFTMOUSE
)
196 gl
.wintitle(filename
)
197 stop
= (playonce(vin
) or nowait
)
198 gl
.wintitle('(done) ' + filename
)
201 dev
, val
= gl
.qread()
208 if dev
== LEFTMOUSE
and val
== 1:
209 break # Continue outer loop
210 if dev
== ESCKEY
and val
== 1 or \
211 dev
in (WINSHUT
, WINQUIT
):
214 # Set xoff, yoff for the next window from the current window
216 xoff
, yoff
= gl
.getorigin()
217 width
, height
= gl
.getsize()
218 scrheight
= gl
.getgdesc(GL
.GD_YPMAX
)
219 yoff
= scrheight
- yoff
- height
225 # Play a movie once; return 1 if user wants to stop, 0 if not
229 vin
.colormapinited
= 1
230 vin
.magnify
= magnify
233 MAXSIZE
= 20 # Don't read ahead too much
236 queue
= Queue
.Queue(MAXSIZE
)
238 thread
.start_new_thread(read_ahead
, (vin
, queue
, stop
))
239 # Get the read-ahead thread going
240 while queue
.qsize() < MAXSIZE
/2 and not stop
:
253 tlast
= t0
= time
.time()
257 dev
, val
= gl
.qread()
258 if dev
== ESCKEY
and val
== 1 or \
259 dev
in (WINSHUT
, WINQUIT
) or \
260 dev
== LEFTMOUSE
and val
== 1:
261 if debug
: sys
.stderr
.write('\n')
266 if item
== None: break
267 return (dev
!= LEFTMOUSE
)
270 if data
: vin
.showframe(data
, cdata
)
272 if debug
and queue
.empty(): sys
.stderr
.write('.')
274 if item
== None: break
275 tin
, data
, cdata
= item
278 tin
, size
, csize
= vin
.getnextframeheader()
283 if tin
+toffset
< oldtin
:
284 print 'Fix reversed time:', oldtin
, 'to', tin
285 toffset
= oldtin
- tin
288 if regen
: tout
= nin
* regen
291 if tout
- told
< mindelta
:
292 nskipped
= nskipped
+ 1
294 vin
.skipnextframedata(size
, csize
)
299 vin
.getnextframedata(size
, csize
)
302 print '[incomplete last frame]'
305 dt
= (tout
-told
) - (now
-tlast
)
307 if debug
: sys
.stderr
.write(`
round(dt
, 3)`
+ ' ')
308 if dt
< 0: nlate
= nlate
+ 1
313 vin
.showframe(data
, cdata
)
318 if debug
: sys
.stderr
.write('\n')
322 print 'Recorded:', nin
, 'frames in', round(tin
, 3), 'sec.',
323 if tin
: print '-- average', round(nin
/tin
, 1), 'frames/sec',
326 if nskipped
: print 'Skipped', nskipped
, 'frames'
329 print 'Played:', nout
,
330 print 'frames in', round(tout
, 3), 'sec.',
331 if tout
: print '-- average', round(nout
/tout
, 1), 'frames/sec',
334 if nlate
: print 'There were', nlate
, 'late frames'
341 def read_ahead(vin
, queue
, stop
):
343 while not stop
: queue
.put(vin
.getnextframe())
350 # Don't forget to call the main program
354 except KeyboardInterrupt: