]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Created Vedit.py, the video editor. This uses the classes in Viewer.py.
authorGuido van Rossum <guido@python.org>
Tue, 25 Aug 1992 12:29:30 +0000 (12:29 +0000)
committerGuido van Rossum <guido@python.org>
Tue, 25 Aug 1992 12:29:30 +0000 (12:29 +0000)
Viewer.py in turn requires changes to VFile.py (unfortunately that file
is now a complete mess...).

Demo/sgi/video/README
Demo/sgi/video/VFile.py
Demo/sgi/video/Vedit.py [new file with mode: 0755]
Demo/sgi/video/VeditForm.fd [new file with mode: 0644]
Demo/sgi/video/Viewer.py [new file with mode: 0755]
Demo/sgi/video/Vplay.py

index eedb85f568ddfca1eadf219e487eca2d396ec532..85855a9157300a298ebd2d490690adcd0c494712 100644 (file)
@@ -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:
index 17f677f315d13472655480e76bba5ff63ead2182..b16b2ab78033632ffcac9e67dcf6cf0bb2fcd78f 100755 (executable)
@@ -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 (executable)
index 0000000..fa8631a
--- /dev/null
@@ -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 (file)
index 0000000..6bffa98
--- /dev/null
@@ -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 (executable)
index 0000000..6203562
--- /dev/null
@@ -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()
index 5ab623d5966529396f913bf2611747f0962a09f7..b8d06a1ff399a0212306826894c10f17dfc26741 100755 (executable)
@@ -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: