summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1992-08-25 12:29:30 (GMT)
committerGuido van Rossum <guido@python.org>1992-08-25 12:29:30 (GMT)
commit9ee7e159663ff81b3651a556dfde73574724ac26 (patch)
tree28988ccd34af9a321471b02e0b348ff4eb0945b9
parente1b4d7ce14c3463c14a188cb86eb1e267e66c254 (diff)
downloadcpython-9ee7e159663ff81b3651a556dfde73574724ac26.zip
cpython-9ee7e159663ff81b3651a556dfde73574724ac26.tar.gz
cpython-9ee7e159663ff81b3651a556dfde73574724ac26.tar.bz2
Created Vedit.py, the video editor. This uses the classes in Viewer.py.
Viewer.py in turn requires changes to VFile.py (unfortunately that file is now a complete mess...).
-rw-r--r--Demo/sgi/video/README4
-rwxr-xr-xDemo/sgi/video/VFile.py267
-rwxr-xr-xDemo/sgi/video/Vedit.py247
-rw-r--r--Demo/sgi/video/VeditForm.fd360
-rwxr-xr-xDemo/sgi/video/Viewer.py242
-rwxr-xr-xDemo/sgi/video/Vplay.py31
6 files changed, 1007 insertions, 144 deletions
diff --git a/Demo/sgi/video/README b/Demo/sgi/video/README
index eedb85f..85855a9 100644
--- a/Demo/sgi/video/README
+++ b/Demo/sgi/video/README
@@ -100,6 +100,10 @@ Vtime.py (unrelated to vtime!!!) Copy a video file,
manipulating the time codes (e.g. faster/slower, or
regenerate time codes, or drop frames too close apart)
+Vedit.py interactive video editing program
+
+Viewer.py two viewer classes used by Vedit
+
The following are C programs, either for efficiency or because they
need to link with a C library:
diff --git a/Demo/sgi/video/VFile.py b/Demo/sgi/video/VFile.py
index 17f677f..b16b2ab 100755
--- a/Demo/sgi/video/VFile.py
+++ b/Demo/sgi/video/VFile.py
@@ -52,7 +52,138 @@ def conv_rgb8(rgb,d1,d2):
# xorigin, yorigin
# fallback
-class VinFile:
+
+
+# XXX it's a total mess now -- VFile is a new base class
+# XXX to support common functionality (e.g. showframe)
+
+class VFile:
+
+ #
+ # getinfo returns all info pertaining to a film. The returned tuple
+ # can be passed to VoutFile.setinfo()
+ #
+ def getinfo(self):
+ return (self.format, self.width, self.height, self.packfactor,\
+ self.c0bits, self.c1bits, self.c2bits, self.offset, \
+ self.chrompack)
+
+ # reopen() raises Error if the header is bad (which can only
+ # happen if the file was written to since opened).
+
+ def reopen(self):
+ self.fp.seek(0)
+ x = self.initfp(self.fp, self.filename)
+
+ def setconvcolor(self):
+ try:
+ self.convcolor = eval('conv_'+self.format)
+ except:
+ raise Error, \
+ self.filename + ': unknown colorsys ' + self.format
+
+ def showframe(self, data, chromdata):
+ w, h, pf = self.width, self.height, self.packfactor
+ if not self.colormapinited:
+ self.initcolormap()
+ factor = self.magnify
+ if pf: factor = factor * pf
+ if chromdata and not self.skipchrom:
+ cp = self.chrompack
+ cw = (w+cp-1)/cp
+ ch = (h+cp-1)/cp
+ gl.rectzoom(factor*cp, factor*cp)
+ gl.pixmode(GL.PM_SIZE, 16)
+ gl.writemask(self.mask - ((1 << self.c0bits) - 1))
+ gl.lrectwrite(self.xorigin, self.yorigin, \
+ self.xorigin + cw - 1, self.yorigin + ch - 1, \
+ chromdata)
+ #
+ if pf:
+ gl.writemask((1 << self.c0bits) - 1)
+ gl.pixmode(GL.PM_SIZE, 8)
+ gl.rectzoom(factor, factor)
+ w = w/pf
+ h = h/pf
+ gl.lrectwrite(self.xorigin, self.yorigin, \
+ self.xorigin + w - 1, self.yorigin + h - 1, data)
+
+ def initcolormap(self):
+ self.colormapinited = 1
+ if self.format == 'rgb':
+ gl.RGBmode()
+ gl.gconfig()
+ gl.RGBcolor(200, 200, 200)
+ gl.clear()
+ return
+ gl.cmode()
+ gl.gconfig()
+ self.skipchrom = 0
+ if not self.quiet:
+ sys.stderr.write('Initializing color map...')
+ self.initcmap()
+ if not self.quiet:
+ sys.stderr.write(' Done.\n')
+ if self.offset == 0:
+ gl.color(0x800)
+ gl.clear()
+ self.mask = 0x7ff
+ else:
+ self.mask = 0xfff
+ gl.clear()
+
+
+ def initcmap(self):
+ maxbits = gl.getgdesc(GL.GD_BITS_NORM_SNG_CMODE)
+ if maxbits > 11:
+ maxbits = 11
+ c0bits, c1bits, c2bits = self.c0bits, self.c1bits, self.c2bits
+ if c0bits+c1bits+c2bits > maxbits:
+ if self.fallback and c0bits < maxbits:
+ # Cannot display film in this mode, use mono
+ self.skipchrom = 1
+ c1bits = c2bits = 0
+ self.convcolor = conv_grey
+ else:
+ raise Error, 'Sorry, '+`maxbits`+ \
+ ' bits max on this machine'
+ maxc0 = 1 << c0bits
+ maxc1 = 1 << c1bits
+ maxc2 = 1 << c2bits
+ if self.offset == 0 and maxbits == 11:
+ offset = 2048
+ else:
+ offset = self.offset
+ if maxbits <> 11:
+ offset = offset & ((1<<maxbits)-1)
+ #for i in range(512, MAXMAP):
+ # gl.mapcolor(i, 0, 0, 0)
+ #void = gl.qtest() # Should be gl.gflush()
+ for c0 in range(maxc0):
+ c0v = c0/float(maxc0-1)
+ for c1 in range(maxc1):
+ if maxc1 == 1:
+ c1v = 0
+ else:
+ c1v = c1/float(maxc1-1)
+ for c2 in range(maxc2):
+ if maxc2 == 1:
+ c2v = 0
+ else:
+ c2v = c2/float(maxc2-1)
+ index = offset + c0 + (c1<<c0bits) + \
+ (c2 << (c0bits+c1bits))
+ rv, gv, bv = self.convcolor( \
+ c0v, c1v, c2v)
+ r, g, b = int(rv*255.0), \
+ int(gv*255.0), int(bv*255.0)
+ if index < MAXMAP:
+ gl.mapcolor(index, r, g, b)
+ void = gl.gflush()
+
+
+
+class VinFile(VFile):
# init() and initfp() raise Error if the header is bad.
# init() raises whatever open() raises if the file can't be opened.
@@ -122,11 +253,7 @@ class VinFile:
raise Error, \
self.filename + ': bad 3.0 color info'
- try:
- self.convcolor = eval('conv_'+self.format)
- except:
- raise Error, \
- self.filename + ': unknown colorsys ' + self.format
+ self.setconvcolor()
#
line = self.fp.readline()
try:
@@ -162,23 +289,6 @@ class VinFile:
self.fp.close()
self.fp = None
-
- #
- # getinfo returns all info pertaining to a film. The returned tuple
- # can be passed to VoutFile.setinfo()
- #
- def getinfo(self):
- return (self.format, self.width, self.height, self.packfactor,\
- self.c0bits, self.c1bits, self.c2bits, self.offset, \
- self.chrompack)
-
- # reopen() raises Error if the header is bad (which can only
- # happen if the file was written to since opened).
-
- def reopen(self):
- self.fp.seek(0)
- x = self.initfp(self.fp, self.filename)
-
def rewind(self):
if self.hascache:
self.frameno = 0
@@ -270,105 +380,6 @@ class VinFile:
self.showframe(data, chromdata)
return time
- def showframe(self, data, chromdata):
- w, h, pf = self.width, self.height, self.packfactor
- if not self.colormapinited:
- self.initcolormap()
- factor = self.magnify
- if pf: factor = factor * pf
- if chromdata and not self.skipchrom:
- cp = self.chrompack
- cw = (w+cp-1)/cp
- ch = (h+cp-1)/cp
- gl.rectzoom(factor*cp, factor*cp)
- gl.pixmode(GL.PM_SIZE, 16)
- gl.writemask(self.mask - ((1 << self.c0bits) - 1))
- gl.lrectwrite(self.xorigin, self.yorigin, \
- self.xorigin + cw - 1, self.yorigin + ch - 1, \
- chromdata)
- #
- if pf:
- gl.writemask((1 << self.c0bits) - 1)
- gl.pixmode(GL.PM_SIZE, 8)
- gl.rectzoom(factor, factor)
- w = w/pf
- h = h/pf
- gl.lrectwrite(self.xorigin, self.yorigin, \
- self.xorigin + w - 1, self.yorigin + h - 1, data)
-
- def initcolormap(self):
- self.colormapinited = 1
- if self.format == 'rgb':
- gl.RGBmode()
- gl.gconfig()
- gl.RGBcolor(200, 200, 200)
- gl.clear()
- return
- gl.cmode()
- gl.gconfig()
- self.skipchrom = 0
- if not self.quiet:
- sys.stderr.write('Initializing color map...')
- self.initcmap()
- if not self.quiet:
- sys.stderr.write(' Done.\n')
- if self.offset == 0:
- gl.color(0x800)
- gl.clear()
- self.mask = 0x7ff
- else:
- self.mask = 0xfff
- gl.clear()
-
-
- def initcmap(self):
- maxbits = gl.getgdesc(GL.GD_BITS_NORM_SNG_CMODE)
- if maxbits > 11:
- maxbits = 11
- c0bits, c1bits, c2bits = self.c0bits, self.c1bits, self.c2bits
- if c0bits+c1bits+c2bits > maxbits:
- if self.fallback and c0bits < maxbits:
- # Cannot display film in this mode, use mono
- self.skipchrom = 1
- c1bits = c2bits = 0
- self.convcolor = conv_grey
- else:
- raise Error, 'Sorry, '+`maxbits`+ \
- ' bits max on this machine'
- maxc0 = 1 << c0bits
- maxc1 = 1 << c1bits
- maxc2 = 1 << c2bits
- if self.offset == 0 and maxbits == 11:
- offset = 2048
- else:
- offset = self.offset
- if maxbits <> 11:
- offset = offset & ((1<<maxbits)-1)
- #for i in range(512, MAXMAP):
- # gl.mapcolor(i, 0, 0, 0)
- #void = gl.qtest() # Should be gl.gflush()
- for c0 in range(maxc0):
- c0v = c0/float(maxc0-1)
- for c1 in range(maxc1):
- if maxc1 == 1:
- c1v = 0
- else:
- c1v = c1/float(maxc1-1)
- for c2 in range(maxc2):
- if maxc2 == 1:
- c2v = 0
- else:
- c2v = c2/float(maxc2-1)
- index = offset + c0 + (c1<<c0bits) + \
- (c2 << (c0bits+c1bits))
- rv, gv, bv = self.convcolor( \
- c0v, c1v, c2v)
- r, g, b = int(rv*255.0), \
- int(gv*255.0), int(bv*255.0)
- if index < MAXMAP:
- gl.mapcolor(index, r, g, b)
- void = gl.gflush()
-
#
# A set of routines to grab images from windows
#
@@ -417,7 +428,7 @@ def grab_hsv(w, h, pf):
# Notably it will accept almost any garbage and write it to the video
# output file
#
-class VoutFile:
+class VoutFile(VFile):
def init(self, filename):
if filename == '-':
return self.initfp(sys.stdout, filename)
@@ -434,21 +445,21 @@ class VoutFile:
self.offset = 0
self.chrompack = 0
self.headerwritten = 0
+ self.quiet = 0
+ self.magnify = 1
+ self.setconvcolor()
+ self.xorigin = self.yorigin = 0
return self
def close(self):
self.fp.close()
x = self.initfp(None, None)
- def getinfo(self):
- return (self.format, self.width, self.height, self.packfactor,\
- self.c0bits, self.c1bits, self.c2bits, self.offset, \
- self.chrompack)
-
def setinfo(self, values):
self.format, self.width, self.height, self.packfactor,\
self.c0bits, self.c1bits, self.c2bits, self.offset, \
self.chrompack = values
+ self.setconvcolor()
def writeheader(self):
self.headerwritten = 1
diff --git a/Demo/sgi/video/Vedit.py b/Demo/sgi/video/Vedit.py
new file mode 100755
index 0000000..fa8631a
--- /dev/null
+++ b/Demo/sgi/video/Vedit.py
@@ -0,0 +1,247 @@
+#! /ufs/guido/bin/sgi/python
+
+# Edit CMIF movies interactively -- copy one or more files to an output file
+
+
+# Possibilities:
+#
+# - convert between formats (grey, rgb, rgb8, ...)
+# - change size
+# - cut out a given area of the image
+# - change time base (a la Vtime)
+# - skip stretches of frames
+
+
+import sys
+import os
+import gl, GL, DEVICE
+import fl, FL
+import flp
+import Viewer
+import getopt
+import string
+
+
+def main():
+ qsize = 20
+ opts, args = getopt.getopt(sys.argv[1:], 'q:')
+ for o, a in opts:
+ if o == '-q':
+ qsize = string.atoi(a)
+ ed = Editor().init(qsize)
+ if args[0:]:
+ ed.open_input(args[0])
+ if args[1:]:
+ ed.open_output(args[1])
+ while 1:
+ dummy = fl.do_forms()
+
+
+class Editor:
+
+ def init(self, qsize):
+ self.qsize = qsize
+ self.vin = None
+ self.vout = None
+ self.ifile = ''
+ self.ofile = ''
+ formdef = flp.parse_form('VeditForm', 'form')
+ flp.create_full_form(self, formdef)
+ self.form.show_form(FL.PLACE_SIZE, FL.TRUE, 'Vedit')
+ fl.set_event_call_back(self.do_event)
+ return self
+
+ def do_event(self, (dev, val)):
+ if dev == DEVICE.REDRAW:
+ if self.vin:
+ self.vin.redraw(val)
+ if self.vout:
+ self.vout.redraw(val)
+
+
+ def iocheck(self):
+ self.msg('')
+ if self.vin == None and self.vout == None:
+ self.err('Please open input and output files first')
+ return 0
+ return self.icheck() and self.ocheck()
+
+ def icheck(self):
+ self.msg('')
+ if self.vin == None:
+ self.err('Please open an input file first')
+ return 0
+ return 1
+
+ def ocheck(self):
+ self.msg('')
+ if self.vout == None:
+ self.err('Please open an output file first')
+ return 0
+ return 1
+
+
+ def cb_in_new(self, args):
+ self.msg('')
+ hd, tl = os.path.split(self.ifile)
+ filename = fl.file_selector('Input video file', hd, '', tl)
+ if not filename: return
+ self.open_input(filename)
+
+ def cb_in_close(self, args):
+ self.msg('')
+ self.close_input()
+
+ def cb_in_skip(self, args):
+ if not self.icheck(): return
+ if not self.vin.get(): self.err('End of input file')
+ self.ishow()
+
+ def cb_in_back(self, args):
+ if not self.icheck(): return
+ if not self.vin.backup(): self.err('Input buffer exhausted')
+ self.ishow()
+
+ def cb_in_rewind(self, args):
+ if not self.icheck(): return
+ self.vin.rewind()
+ self.ishow()
+
+
+ def cb_copy(self, args):
+ if not self.iocheck(): return
+ data = self.vin.get()
+ if data:
+ if self.vout.getinfo() <> self.vin.getinfo():
+ print 'Copying info...'
+ self.vout.setinfo(self.vin.getinfo())
+ self.vout.put(data)
+ self.oshow()
+ self.ishow()
+
+ def cb_uncopy(self, args):
+ if not self.iocheck(): return
+ if not self.vout.backup():
+ self.err('Output buffer exhausted')
+ return
+ self.oshow()
+ if not self.vin.backup():
+ self.err('Input buffer exhausted')
+ return
+ self.ishow()
+
+
+ def cb_out_new(self, args):
+ self.msg('')
+ hd, tl = os.path.split(self.ofile)
+ filename = fl.file_selector('Output video file', hd, '', tl)
+ if not filename: return
+ self.open_output(filename)
+
+ def cb_out_close(self, args):
+ self.msg('')
+ self.close_output()
+
+ def cb_out_skip(self, arg):
+ if not self.ocheck(): return
+ if not self.vout.forward(): self.err('Output buffer exhausted')
+ self.oshow()
+
+ def cb_out_back(self, args):
+ if not self.ocheck(): return
+ if not self.vout.backup(): self.err('Output buffer exhausted')
+ self.oshow()
+
+ def cb_out_rewind(self, args):
+ if not self.ocheck(): return
+ self.vout.rewind()
+ self.oshow()
+
+
+ def cb_quit(self, args):
+ self.close_input()
+ self.close_output()
+ sys.exit(0)
+
+
+ def open_input(self, filename):
+ self.ifile = filename
+ basename = os.path.split(filename)[1]
+ title = 'in: ' + basename
+ try:
+ vin = Viewer.InputViewer().init(filename, \
+ title, self.qsize)
+ except:
+ self.err('Can\'t open input file', filename)
+ return
+ self.close_input()
+ self.vin = vin
+ self.in_file.label = basename
+ self.ishow()
+
+ def close_input(self):
+ if self.vin:
+ self.msg('Closing input file...')
+ self.vin.close()
+ self.msg('')
+ self.vin = None
+ self.in_file.label = '(none)'
+ self.format('in')
+
+ def ishow(self):
+ self.vin.show()
+ self.format('in')
+
+ def open_output(self, filename):
+ self.ofile = filename
+ basename = os.path.split(filename)[1]
+ title = 'out: ' + basename
+ try:
+ vout = Viewer.OutputViewer().init(filename, \
+ title, self.qsize)
+ except:
+ self.err('Can\'t open output file', filename)
+ return
+ self.close_output()
+ self.vout = vout
+ self.out_file.label = basename
+ if self.vin:
+ self.vout.setinfo(self.vin.getinfo())
+ self.oshow()
+
+ def close_output(self):
+ if self.vout:
+ self.msg('Closing output file...')
+ self.vout.close()
+ self.msg('')
+ self.vout = None
+ self.out_file.label = '(none)'
+ self.format('out')
+
+ def oshow(self):
+ self.vout.show()
+ self.format('out')
+
+
+ def msg(self, *args):
+ str = string.strip(string.join(args))
+ self.msg_area.label = str
+
+ def err(self, *args):
+ gl.ringbell()
+ apply(self.msg, args)
+
+ def format(self, io):
+ v = getattr(self, 'v' + io)
+ if v == None:
+ left = right = pos = 0
+ else:
+ left, right = v.qsizes()
+ pos = v.tell()
+ left = pos - left
+ right = pos + right
+ getattr(self, io + '_info1').label = `left`
+ getattr(self, io + '_info2').label = `pos`
+ getattr(self, io + '_info3').label = `right`
+
+main()
diff --git a/Demo/sgi/video/VeditForm.fd b/Demo/sgi/video/VeditForm.fd
new file mode 100644
index 0000000..6bffa98
--- /dev/null
+++ b/Demo/sgi/video/VeditForm.fd
@@ -0,0 +1,360 @@
+Magic: 12321
+
+Internal Form Definition File
+ (do not change)
+
+Number of forms: 1
+
+=============== FORM ===============
+Name: form
+Width: 480.000000
+Height: 350.000000
+Number of Objects: 23
+
+--------------------
+class: 1
+type: 1
+box: 0.000000 0.000000 480.000000 350.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label:
+name:
+callback:
+argument:
+
+--------------------
+class: 11
+type: 4
+box: 170.000000 110.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: -> Copy ->
+name:
+callback: cb_copy
+argument: 0
+
+--------------------
+class: 11
+type: 4
+box: 10.000000 110.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Forward
+name:
+callback: cb_in_skip
+argument: 0
+
+--------------------
+class: 11
+type: 0
+box: 10.000000 10.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Rewind input
+name:
+callback: cb_in_rewind
+argument: 0
+
+--------------------
+class: 11
+type: 0
+box: 330.000000 10.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Reset output
+name:
+callback: cb_out_rewind
+argument: 0
+
+--------------------
+class: 11
+type: 0
+box: 10.000000 260.000000 80.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Input file...
+name:
+callback: cb_in_new
+argument: 0
+
+--------------------
+class: 11
+type: 0
+box: 330.000000 260.000000 80.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Output file...
+name:
+callback: cb_out_new
+argument: 0
+
+--------------------
+class: 2
+type: 0
+box: 10.000000 210.000000 140.000000 40.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 11.000000
+lcol: 0
+label: (none)
+name: in_file
+callback:
+argument:
+
+--------------------
+class: 2
+type: 0
+box: 330.000000 210.000000 140.000000 40.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 11.000000
+lcol: 0
+label: (none)
+name: out_file
+callback:
+argument:
+
+--------------------
+class: 2
+type: 0
+box: 10.000000 160.000000 30.000000 30.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 8.000000
+lcol: 0
+label:
+name: in_info1
+callback:
+argument:
+
+--------------------
+class: 11
+type: 0
+box: 170.000000 260.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Quit
+name:
+callback: cb_quit
+argument: 0
+
+--------------------
+class: 11
+type: 4
+box: 330.000000 60.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Back
+name:
+callback: cb_out_back
+argument: 0
+
+--------------------
+class: 11
+type: 4
+box: 10.000000 60.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Back
+name:
+callback: cb_in_back
+argument: 0
+
+--------------------
+class: 11
+type: 4
+box: 330.000000 110.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Forward
+name:
+callback: cb_out_skip
+argument: 0
+
+--------------------
+class: 11
+type: 4
+box: 170.000000 60.000000 140.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Uncopy
+name:
+callback: cb_uncopy
+argument: 0
+
+--------------------
+class: 11
+type: 0
+box: 100.000000 260.000000 50.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Close
+name:
+callback: cb_in_close
+argument: 0
+
+--------------------
+class: 11
+type: 0
+box: 420.000000 260.000000 50.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Close
+name:
+callback: cb_out_close
+argument: 0
+
+--------------------
+class: 2
+type: 0
+box: 10.000000 310.000000 460.000000 30.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 11.000000
+lcol: 0
+label: CMIF Video Editor, by Guido van Rossum
+name: msg_area
+callback:
+argument:
+
+--------------------
+class: 2
+type: 0
+box: 50.000000 160.000000 60.000004 40.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 11.000000
+lcol: 0
+label:
+name: in_info2
+callback:
+argument:
+
+--------------------
+class: 2
+type: 0
+box: 120.000000 160.000000 30.000000 30.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 8.000000
+lcol: 0
+label:
+name: in_info3
+callback:
+argument:
+
+--------------------
+class: 2
+type: 0
+box: 330.000000 160.000000 30.000000 30.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 8.000000
+lcol: 0
+label:
+name: out_info1
+callback:
+argument:
+
+--------------------
+class: 2
+type: 0
+box: 370.000000 160.000000 60.000004 40.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 11.000000
+lcol: 0
+label:
+name: out_info2
+callback:
+argument:
+
+--------------------
+class: 2
+type: 0
+box: 440.000000 160.000000 30.000000 30.000000
+boxtype: 6
+colors: 47 47
+alignment: 2
+style: 0
+size: 8.000000
+lcol: 0
+label:
+name: out_info3
+callback:
+argument:
+
+==============================
+create_the_forms
diff --git a/Demo/sgi/video/Viewer.py b/Demo/sgi/video/Viewer.py
new file mode 100755
index 0000000..6203562
--- /dev/null
+++ b/Demo/sgi/video/Viewer.py
@@ -0,0 +1,242 @@
+import gl, GL
+import VFile
+import os
+
+
+class InputViewer:
+
+ def init(self, filename, title, qsize):
+ try:
+ self.vin = VFile.VinFile().init(filename)
+ except (EOFError, VFile.Error):
+ raise IOError, 'bad video input file'
+ if not title:
+ title = os.path.split(filename)[1]
+ self.filename = filename
+ self.title = title
+ self.qsize = qsize
+ gl.foreground()
+ gl.prefsize(self.vin.width, self.vin.height)
+ self.wid = -1
+ self.reset()
+ return self
+
+ def close(self):
+ self.vin.close()
+ if self.wid > 0:
+ gl.winclose(self.wid)
+
+ def rewind(self):
+ self.vin.rewind()
+ self.reset()
+
+ def getinfo(self):
+ return self.vin.getinfo()
+
+ # Internal
+ def reset(self):
+ if self.wid > 0:
+ gl.winset(self.wid)
+ gl.clear()
+ self.vin.initcolormap()
+ self.queue = []
+ self.qindex = 0
+ self.lost = 0
+ self.lastt = 0
+ self.eofread = 0
+
+ # Internal
+ def fillq(self):
+ if self.qindex < len(self.queue) or self.eofread: return
+ try:
+ t, d, cd = self.vin.getnextframe()
+ except EOFError:
+ self.eofread = 1
+ return
+ dt = t - self.lastt
+ self.lastt = t
+ self.queue.append(dt, d, cd)
+ while len(self.queue) > self.qsize:
+ del self.queue[0]
+ self.qindex = self.qindex - 1
+ self.lost = self.lost + 1
+
+ def show(self):
+ if self.wid < 0:
+ gl.foreground()
+ gl.prefsize(self.vin.width, self.vin.height)
+ self.wid = gl.winopen(self.title)
+ gl.clear()
+ self.vin.initcolormap()
+ self.fillq()
+ gl.winset(self.wid)
+ if self.qindex >= len(self.queue):
+ gl.clear()
+ return
+ dt, d, cd = self.queue[self.qindex]
+ self.vin.showframe(d, cd)
+
+ def redraw(self, wid):
+ if wid == self.wid >= 0:
+ gl.winset(self.wid)
+ gl.reshapeviewport()
+ self.show()
+
+ def get(self):
+ if self.qindex >= len(self.queue):
+ self.fillq()
+ if self.eofread:
+ return None
+ item = self.queue[self.qindex]
+ self.qindex = self.qindex + 1
+ return item
+
+ def backup(self):
+ if self.qindex == 0:
+ return 0
+ self.qindex = self.qindex - 1
+ return 1
+
+ def tell(self):
+ return self.lost + self.qindex
+
+ def qsizes(self):
+ return self.qindex, len(self.queue) - self.qindex
+
+
+class OutputViewer:
+
+ def init(self, filename, title, qsize):
+ try:
+ self.vout = VFile.VoutFile().init(filename)
+ except (EOFError, VFile.Error):
+ raise IOError, 'bad video output file'
+ if not title:
+ title = os.path.split(filename)[1]
+ self.filename = filename
+ self.title = title
+ self.qsize = qsize
+ gl.foreground()
+ self.wid = -1
+ self.reset()
+ return self
+
+ def close(self):
+ while self.queue:
+ self.flushq()
+ self.vout.close()
+ if self.wid > 0:
+ gl.winclose(self.wid)
+
+ def rewind(self):
+ info = self.vout.getinfo()
+ self.vout.close()
+ self.vout = VFile.VoutFile().init(self.filename)
+ self.vout.setinfo(info)
+ self.reset()
+
+ def getinfo(self):
+ return self.vout.getinfo()
+
+ def setinfo(self, info):
+ if info == self.getinfo(): return # No change
+ self.vout.setinfo(info)
+ if self.wid > 0:
+ gl.winclose(self.wid)
+ self.wid = -1
+
+ # Internal
+ def reset(self):
+ if self.wid > 0:
+ gl.winset(self.wid)
+ gl.clear()
+ self.vout.initcolormap()
+ self.queue = []
+ self.spares = []
+ self.written = 0
+ self.lastt = 0
+
+ # Internal
+ def flushq(self):
+ if self.written == 0:
+ self.vout.writeheader()
+ dt, d, cd = self.queue[0]
+ self.lastt = self.lastt + dt
+ self.vout.writeframe(self.lastt, d, cd)
+ del self.queue[0]
+ self.written = self.written + 1
+
+ def show(self):
+ if self.wid < 0:
+ gl.foreground()
+ gl.prefsize(self.vout.width, self.vout.height)
+ self.wid = gl.winopen(self.title)
+ gl.clear()
+ self.vout.initcolormap()
+ gl.winset(self.wid)
+ if not self.queue:
+ gl.clear()
+ return
+ dt, d, cd = self.queue[-1]
+ self.vout.showframe(d, cd)
+
+ def redraw(self, wid):
+ if wid == self.wid >= 0:
+ gl.winset(self.wid)
+ gl.reshapeviewport()
+ self.show()
+
+ def backup(self):
+ if len(self.queue) < 1: return 0
+ self.spares.insert(0, self.queue[-1])
+ del self.queue[-1]
+ return 1
+
+ def forward(self):
+ if not self.spares: return 0
+ self.queue.append(self.spares[0])
+ del self.spares[0]
+ return 1
+
+ def put(self, item):
+ self.queue.append(item)
+ self.spares = []
+ while len(self.queue) > self.qsize:
+ self.flushq()
+
+ def tell(self):
+ return self.written + len(self.queue)
+
+ def qsizes(self):
+ return len(self.queue), len(self.spares)
+
+
+def test():
+ import sys
+ a = InputViewer().init(sys.argv[1], '')
+ b = OutputViewer().init(sys.argv[2], '')
+ b.setinfo(a.getinfo())
+
+ while 1:
+ a.show()
+ data = a.get()
+ if data is None:
+ break
+ b.put(data)
+ b.show()
+
+ while a.backup():
+ data = a.get()
+ b.put(data)
+ b.show()
+ if a.backup(): a.show()
+
+ while 1:
+ data = a.get()
+ if data is None:
+ break
+ b.put(data)
+ b.show()
+ a.show()
+
+ b.close()
diff --git a/Demo/sgi/video/Vplay.py b/Demo/sgi/video/Vplay.py
index 5ab623d..b8d06a1 100755
--- a/Demo/sgi/video/Vplay.py
+++ b/Demo/sgi/video/Vplay.py
@@ -200,13 +200,15 @@ def playonce(vin):
vin.magnify = magnify
if threading:
+ MAXSIZE = 20 # Don't read ahead too much
import thread
- queue = []
+ import Queue
+ queue = Queue.Queue().init(MAXSIZE)
stop = []
thread.start_new_thread(read_ahead, (vin, queue, stop))
# Get the read-ahead thread going
- while len(queue) < 5 and None not in queue:
- time.millisleep(10)
+ while queue.qsize() < MAXSIZE/2 and not stop:
+ time.millisleep(100)
tin = 0
told = 0
@@ -227,21 +229,18 @@ def playonce(vin):
if debug: sys.stderr.write('\n')
if threading:
stop.append(None)
- while len(stop) < 2:
- time.millisleep(10)
+ 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 not queue:
- if debug: sys.stderr.write('.')
- time.millisleep(10)
- continue
- q0 = queue[0]
- if q0 == None: break
- del queue[0]
- tin, data, cdata = q0
+ 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()
@@ -301,13 +300,13 @@ def playonce(vin):
def read_ahead(vin, queue, stop):
try:
- while not stop: queue.append(vin.getnextframe())
+ while not stop: queue.put(vin.getnextframe())
except EOFError:
- queue.append(None)
+ pass
+ queue.put(None)
stop.append(None)
-
# Don't forget to call the main program
try: