mirror of https://github.com/python/cpython
Remove the SGI demos. These were all ancient and nobody cared enough.
This commit is contained in:
parent
d679e09970
commit
16aac45fc2
|
@ -43,12 +43,6 @@ rpc A set of classes for building clients and servers for
|
|||
scripts Some useful Python scripts that I put in my bin
|
||||
directory. No optional built-in modules needed.
|
||||
|
||||
sgi Demos that only run on Silicon Graphics machines.
|
||||
These require at least one of the optional built-in
|
||||
modules that only make sense for the SGI, such as
|
||||
'gl', 'al', and 'sv'. Split in subdirectories
|
||||
per subject.
|
||||
|
||||
sockets Examples for the new built-in module 'socket'.
|
||||
|
||||
threads Demos that use the 'thread' module. (Currently these
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
cmpaf_form.fdc
|
|
@ -1,46 +0,0 @@
|
|||
Introduction.
|
||||
|
||||
A number of programs have been written which access the Silicon
|
||||
Graphics CD-ROM player. These programs all use the interface defined
|
||||
in readcd.py (see readcd.doc for documentation).
|
||||
|
||||
Specifying music stretches.
|
||||
|
||||
The programs that are capable of reading music CD's all use the same
|
||||
syntax to describe which part of the CD is to be read. The syntax
|
||||
closely corresponds to the available methods in readcd.py.
|
||||
|
||||
The music to be read is divided into stretches of music. Each stretch
|
||||
must be specified as a separate argument on the command line. A
|
||||
stretch can be a whole CD track, specified as a single number; or it
|
||||
can be a start time and a end time. The start and end times must be
|
||||
specified as a tuple, thus: ``(starttime, endtime)''. Don't forget to
|
||||
quote the parenthesis to the shell. Both starttime and endtime can be
|
||||
``None'', a simple number which refers to a CD track, or a tuple
|
||||
consisting of either 3 or 4 elements. A starttime of ``None'' refers
|
||||
to the start of the CD, an endtime of ``None'' refers to the end of
|
||||
the CD. A tuple of 3 elements is an absolute time on the CD. The
|
||||
three elements are (minutes, seconds, frames). A tuple of 4 elements
|
||||
is a track-relative time. The four elements are (track, minutes,
|
||||
seconds, frames).
|
||||
|
||||
When one stretch ends at the end of a track and the following stretch
|
||||
starts at the next track, there is the option of either playing or not
|
||||
playing the pause between the two tracks. When either the end time of
|
||||
the first stretch or the start time of the second stretch is specified
|
||||
using absolute or track-relative times, the pause will not be played.
|
||||
When both times are specified as simple track numbers, the pause will
|
||||
be played.
|
||||
|
||||
If no stretches are specified, the whole CD will be played.
|
||||
|
||||
The programs.
|
||||
|
||||
Currently, the following programs exist.
|
||||
playcd [ stretch specification ]
|
||||
Play (part of) a CD through the system loadspeaker or
|
||||
headphone set.
|
||||
cdaiff [ file [ stretch specification ] ]
|
||||
Copy (part of) a CD to a file. The file will be written in
|
||||
AIFF format. If no file is specified, cdaiff will write to
|
||||
the file ``@'' in the current directory.
|
|
@ -1,28 +0,0 @@
|
|||
These are some programs to work with the SCSI CD-ROM player's audio
|
||||
interface (see cdaudio(3) in IRIX 4.0 or higher; tested only on 4.0.2).
|
||||
|
||||
See also the SGI-specific standard module 'readcd', documented as
|
||||
"readcd.lib" in the library.
|
||||
|
||||
cdwin.py A trivial window interface to play a CD over the CD
|
||||
player's audio jack. More functionality is left as an
|
||||
excersice to the reader. Needs module stdwin.
|
||||
|
||||
listcd.py List the table-of-contents of a CD (data CDs will
|
||||
appear as a single track).
|
||||
|
||||
playcd.py Read audio data from the CD and play it over the
|
||||
Indigo's built-in speker or audio jack. Needs module al.
|
||||
|
||||
sendcd.py Read audio data from the CD and send it as UDP packets
|
||||
over the network (to recvcd.py).
|
||||
|
||||
recvcd.py Receive UDP packets containing CD audio data (from
|
||||
sendcd.py) and play them over the Indigo's built-in
|
||||
speaker or audio jack. Needs module al. (Doesn't
|
||||
actually use module cd.)
|
||||
|
||||
cdaiff.py Dump CD audio to disk in AIFF format.
|
||||
|
||||
Note that to read *data* CD-ROMs you must open /dev/rdsk/dks0d4s7 or
|
||||
some such special file...
|
|
@ -1,33 +0,0 @@
|
|||
import sys
|
||||
import readcd
|
||||
import aifc
|
||||
import AL
|
||||
import cd
|
||||
|
||||
Error = 'cdaiff.Error'
|
||||
|
||||
def writeaudio(a, type, data):
|
||||
a.writeframesraw(data)
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1:
|
||||
a = aifc.open(sys.argv[1], 'w')
|
||||
else:
|
||||
a = aifc.open('@', 'w')
|
||||
a.setsampwidth(AL.SAMPLE_16)
|
||||
a.setnchannels(AL.STEREO)
|
||||
a.setframerate(AL.RATE_44100)
|
||||
r = readcd.Readcd()
|
||||
for arg in sys.argv[2:]:
|
||||
x = eval(arg)
|
||||
try:
|
||||
if len(x) <> 2:
|
||||
raise Error, 'bad argument'
|
||||
r.appendstretch(x[0], x[1])
|
||||
except TypeError:
|
||||
r.appendtrack(x)
|
||||
r.setcallback(cd.audio, writeaudio, a)
|
||||
r.play()
|
||||
a.close()
|
||||
|
||||
main()
|
|
@ -1,24 +0,0 @@
|
|||
# List track info from CD player.
|
||||
|
||||
import cd
|
||||
|
||||
def main():
|
||||
c = cd.open()
|
||||
info = []
|
||||
while 1:
|
||||
try:
|
||||
info.append(c.gettrackinfo(len(info) + 1))
|
||||
except RuntimeError:
|
||||
break
|
||||
for i in range(len(info)):
|
||||
start, total = info[i]
|
||||
print 'Track', zfill(i+1), triple(start), triple(total)
|
||||
|
||||
def triple((a, b, c)):
|
||||
return zfill(a) + ':' + zfill(b) + ':' + zfill(c)
|
||||
|
||||
def zfill(n):
|
||||
s = `n`
|
||||
return '0' * (2 - len(s)) + s
|
||||
|
||||
main()
|
|
@ -1,102 +0,0 @@
|
|||
# Play CD audio on speaker or headphones.
|
||||
|
||||
callbacktypes = ['audio','pnum','index','ptime','atime','catalog','ident','control']
|
||||
|
||||
def playaudio(port, type, audio):
|
||||
port.writesamps(audio)
|
||||
|
||||
def prtrack(cdinfo, type, pnum):
|
||||
if cdinfo.track[pnum] <> '':
|
||||
print 'playing "' + cdinfo.track[pnum] + '"'
|
||||
else:
|
||||
print callbacktypes[type]+': '+`pnum`
|
||||
|
||||
def callback(arg, type, data):
|
||||
print callbacktypes[type]+': '+`data`
|
||||
|
||||
def tcallback(arg, type, data):
|
||||
print callbacktypes[type]+': '+triple(data)
|
||||
|
||||
def triple((a, b, c)):
|
||||
return zfill(a) + ':' + zfill(b) + ':' + zfill(c)
|
||||
|
||||
def zfill(n):
|
||||
s = `n`
|
||||
return '0' * (2 - len(s)) + s
|
||||
|
||||
def prtrackinfo(info):
|
||||
for i in range(len(info)):
|
||||
start, total = info[i]
|
||||
print 'Track', zfill(i+1), triple(start), triple(total)
|
||||
|
||||
statedict = ['ERROR', 'NODISK', 'READY', 'PLAYING', 'PAUSED', 'STILL']
|
||||
|
||||
def prstatus(status):
|
||||
state, track, curtime, abstime, totaltime, first, last, \
|
||||
scsi_audio, cur_block, dummy = status
|
||||
print 'Status:',
|
||||
if 0 <= state < len(statedict):
|
||||
print statedict[state]
|
||||
else:
|
||||
print state
|
||||
print 'Track: ', track
|
||||
print 'Time: ', triple(curtime)
|
||||
print 'Abs: ', triple(abstime)
|
||||
print 'Total: ', triple(totaltime)
|
||||
print 'First: ', first
|
||||
print 'Last: ', last
|
||||
print 'SCSI: ', scsi_audio
|
||||
print 'Block: ', cur_block
|
||||
print 'Future:', dummy
|
||||
|
||||
def main():
|
||||
import sys, readcd, al, AL, cd, cdplayer
|
||||
verbose = 0
|
||||
r = readcd.Readcd()
|
||||
prstatus(r.getstatus())
|
||||
prtrackinfo(r.gettrackinfo())
|
||||
cdinfo = cdplayer.Cdplayer(r.gettrackinfo())
|
||||
if cdinfo.title <> '':
|
||||
print 'Title: "' + cdinfo.title + '"'
|
||||
if cdinfo.artist <> '':
|
||||
print 'Artist: ' + cdinfo.artist
|
||||
for arg in sys.argv[1:]:
|
||||
if arg == '-v':
|
||||
verbose = 1
|
||||
continue
|
||||
x = eval(arg)
|
||||
try:
|
||||
l = len(x)
|
||||
r.appendstretch(x[0], x[1])
|
||||
except TypeError:
|
||||
r.appendtrack(x)
|
||||
try:
|
||||
oldparams = [AL.OUTPUT_RATE, 0]
|
||||
params = oldparams[:]
|
||||
al.getparams(AL.DEFAULT_DEVICE, oldparams)
|
||||
params[1] = AL.RATE_44100
|
||||
al.setparams(AL.DEFAULT_DEVICE, params)
|
||||
config = al.newconfig()
|
||||
config.setwidth(AL.SAMPLE_16)
|
||||
config.setchannels(AL.STEREO)
|
||||
port = al.openport('CD Player', 'w', config)
|
||||
|
||||
for i in range(8):
|
||||
r.setcallback(i, callback, None)
|
||||
if verbose:
|
||||
r.setcallback(cd.ptime, tcallback, None)
|
||||
r.setcallback(cd.atime, tcallback, None)
|
||||
else:
|
||||
r.removecallback(cd.ptime)
|
||||
r.removecallback(cd.atime)
|
||||
r.setcallback(cd.pnum, prtrack, cdinfo)
|
||||
r.setcallback(cd.audio, playaudio, port)
|
||||
|
||||
data = r.play()
|
||||
except KeyboardInterrupt:
|
||||
status = r.getstatus()
|
||||
print 'Interrupted at '+triple(status[2])+' into track '+ \
|
||||
`status[1]`+' (absolute time '+triple(status[3])+')'
|
||||
al.setparams(AL.DEFAULT_DEVICE, oldparams)
|
||||
|
||||
main()
|
|
@ -1,36 +0,0 @@
|
|||
# Receive UDP packets from sendcd.py and play them on the speaker or
|
||||
# audio jack.
|
||||
|
||||
import al, AL
|
||||
from socket import *
|
||||
from cd import DATASIZE
|
||||
|
||||
PORT = 50505 # Must match the port in sendcd.py
|
||||
|
||||
def main():
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.bind('', PORT)
|
||||
|
||||
oldparams = [AL.OUTPUT_RATE, 0]
|
||||
params = oldparams[:]
|
||||
al.getparams(AL.DEFAULT_DEVICE, oldparams)
|
||||
params[1] = AL.RATE_44100
|
||||
try:
|
||||
al.setparams(AL.DEFAULT_DEVICE, params)
|
||||
config = al.newconfig()
|
||||
config.setwidth(AL.SAMPLE_16)
|
||||
config.setchannels(AL.STEREO)
|
||||
port = al.openport('CD Player', 'w', config)
|
||||
|
||||
while 1:
|
||||
data = s.recv(DATASIZE)
|
||||
if not data:
|
||||
print 'EOF'
|
||||
break
|
||||
port.writesamps(data)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
al.setparams(AL.DEFAULT_DEVICE, oldparams)
|
||||
|
||||
main()
|
|
@ -1,154 +0,0 @@
|
|||
# Read CD audio data from the SCSI CD player and send it as UDP
|
||||
# packets to "recvcd.py" on another host.
|
||||
#
|
||||
# Usage: python sendcd.py [options] host [track | minutes seconds [frames]]
|
||||
#
|
||||
# Options:
|
||||
# "-l" list track info and quit.
|
||||
# "-s" display status and quit.
|
||||
#
|
||||
# Arguments:
|
||||
# host host to send the audio data to (required unless -l or -s).
|
||||
# track track number where to start; alternatively,
|
||||
# min sec [frames] absolute address where to start;
|
||||
# default is continue at current point according to status.
|
||||
|
||||
import cd
|
||||
import sys
|
||||
from socket import *
|
||||
import getopt
|
||||
|
||||
PORT = 50505 # Must match the port in readcd.py
|
||||
|
||||
def main():
|
||||
try:
|
||||
optlist, args = getopt.getopt(sys.argv[1:], 'ls')
|
||||
except getopt.error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
sys.exit(2)
|
||||
|
||||
player = cd.open()
|
||||
prstatus(player)
|
||||
size = player.bestreadsize()
|
||||
|
||||
if optlist:
|
||||
for opt, arg in optlist:
|
||||
if opt == '-l':
|
||||
prtrackinfo(player)
|
||||
elif opt == '-s':
|
||||
prstatus(player)
|
||||
return
|
||||
|
||||
if not args:
|
||||
sys.stderr.write('usage: ' + sys.argv[0] + ' host [track]\n')
|
||||
sys.exit(2)
|
||||
host, args = args[0], args[1:]
|
||||
|
||||
sys.stdout.write('waiting for socket... ')
|
||||
sys.stdout.flush()
|
||||
port = socket(AF_INET, SOCK_DGRAM)
|
||||
port.connect(host, PORT)
|
||||
print 'socket connected'
|
||||
|
||||
parser = cd.createparser()
|
||||
parser.setcallback(cd.audio, audiocallback, port)
|
||||
parser.setcallback(cd.pnum, pnumcallback, player)
|
||||
parser.setcallback(cd.index, indexcallback, None)
|
||||
## cd.ptime: too many calls
|
||||
## cd.atime: too many calls
|
||||
parser.setcallback(cd.catalog, catalogcallback, None)
|
||||
parser.setcallback(cd.ident, identcallback, None)
|
||||
parser.setcallback(cd.control, controlcallback, None)
|
||||
|
||||
if len(args) >= 2:
|
||||
if len(args) >= 3:
|
||||
[min, sec, frame] = args[:3]
|
||||
else:
|
||||
[min, sec] = args
|
||||
frame = '0'
|
||||
min, sec, frame = eval(min), eval(sec), eval(frame)
|
||||
print 'Seek to', triple(min, sec, frame)
|
||||
dummy = player.seek(min, sec, frame)
|
||||
elif len(args) == 1:
|
||||
track = eval(args[0])
|
||||
print 'Seek to track', track
|
||||
dummy = player.seektrack(track)
|
||||
else:
|
||||
min, sec, frame = player.getstatus()[3]
|
||||
print 'Try to seek back to', triple(min, sec, frame)
|
||||
try:
|
||||
player.seek(min, sec, frame)
|
||||
except RuntimeError:
|
||||
print 'Seek failed'
|
||||
|
||||
try:
|
||||
while 1:
|
||||
frames = player.readda(size)
|
||||
if frames == '':
|
||||
print 'END OF CD'
|
||||
break
|
||||
parser.parseframe(frames)
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupted]'
|
||||
pass
|
||||
|
||||
def prtrackinfo(player):
|
||||
info = []
|
||||
while 1:
|
||||
try:
|
||||
info.append(player.gettrackinfo(len(info) + 1))
|
||||
except RuntimeError:
|
||||
break
|
||||
for i in range(len(info)):
|
||||
start, total = info[i]
|
||||
print 'Track', zfill(i+1), triple(start), triple(total)
|
||||
|
||||
def audiocallback(port, type, data):
|
||||
## sys.stdout.write('#')
|
||||
## sys.stdout.flush()
|
||||
port.send(data)
|
||||
|
||||
def pnumcallback(player, type, data):
|
||||
print 'pnum =', `data`
|
||||
prstatus(player)
|
||||
|
||||
def indexcallback(arg, type, data):
|
||||
print 'index =', `data`
|
||||
|
||||
def catalogcallback(arg, type, data):
|
||||
print 'catalog =', `data`
|
||||
|
||||
def identcallback(arg, type, data):
|
||||
print 'ident =', `data`
|
||||
|
||||
def controlcallback(arg, type, data):
|
||||
print 'control =', `data`
|
||||
|
||||
statedict = ['ERROR', 'NODISK', 'READY', 'PLAYING', 'PAUSED', 'STILL']
|
||||
|
||||
def prstatus(player):
|
||||
state, track, curtime, abstime, totaltime, first, last, \
|
||||
scsi_audio, cur_block, dummy = player.getstatus()
|
||||
print 'Status:',
|
||||
if 0 <= state < len(statedict):
|
||||
print statedict[state]
|
||||
else:
|
||||
print state
|
||||
print 'Track: ', track
|
||||
print 'Time: ', triple(curtime)
|
||||
print 'Abs: ', triple(abstime)
|
||||
print 'Total: ', triple(totaltime)
|
||||
print 'First: ', first
|
||||
print 'Last: ', last
|
||||
print 'SCSI: ', scsi_audio
|
||||
print 'Block: ', cur_block
|
||||
print 'Future:', dummy
|
||||
|
||||
def triple((a, b, c)):
|
||||
return zfill(a) + ':' + zfill(b) + ':' + zfill(c)
|
||||
|
||||
def zfill(n):
|
||||
s = `n`
|
||||
return '0' * (2 - len(s)) + s
|
||||
|
||||
main()
|
|
@ -1 +0,0 @@
|
|||
tcache.fdc test_cb.fdc test_nocb.fdc
|
|
@ -1,51 +0,0 @@
|
|||
Magic: 12321
|
||||
|
||||
Internal Form Definition File
|
||||
(do not change)
|
||||
|
||||
Number of forms: 2
|
||||
|
||||
=============== FORM ===============
|
||||
Name: first
|
||||
Width: 340.000000
|
||||
Height: 160.000000
|
||||
Number of Objects: 1
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 340.000000 160.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 10.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
=============== FORM ===============
|
||||
Name: second
|
||||
Width: 150.000000
|
||||
Height: 400.000000
|
||||
Number of Objects: 1
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 150.000000 400.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 10.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
==============================
|
||||
create_the_forms
|
|
@ -1,32 +0,0 @@
|
|||
# Test bug in caching of forms
|
||||
|
||||
import sys
|
||||
import os
|
||||
import flp
|
||||
|
||||
filename = 'tcache.fd'
|
||||
cachename = filename + 's'
|
||||
|
||||
def first():
|
||||
try:
|
||||
os.unlink(cachename)
|
||||
except os.error:
|
||||
pass
|
||||
first = flp.parse_form(filename, 'first')
|
||||
|
||||
def second():
|
||||
forms = flp.parse_forms(filename)
|
||||
k = forms.keys()
|
||||
if 'first' in k and 'second' in k:
|
||||
print 'OK'
|
||||
else:
|
||||
print 'BAD!', k
|
||||
|
||||
def main():
|
||||
if sys.argv[1:]:
|
||||
second()
|
||||
else:
|
||||
first()
|
||||
print 'Now run the script again with an argument'
|
||||
|
||||
main()
|
|
@ -1,75 +0,0 @@
|
|||
Magic: 12321
|
||||
|
||||
Internal Form Definition File
|
||||
(do not change)
|
||||
|
||||
Number of forms: 1
|
||||
|
||||
=============== FORM ===============
|
||||
Name: main_form
|
||||
Width: 170.000000
|
||||
Height: 190.000000
|
||||
Number of Objects: 4
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 170.000000 190.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 140.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 1
|
||||
name: button1
|
||||
callback: button1CB
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 100.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 2
|
||||
name: button2
|
||||
callback: button2CB
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 6
|
||||
box: 10.000000 10.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: EXIT
|
||||
name: exitbutton
|
||||
callback: exitbuttonCB
|
||||
argument: 0
|
||||
|
||||
==============================
|
||||
create_the_forms
|
|
@ -1,61 +0,0 @@
|
|||
#
|
||||
# Example 2 - Using fl in python with callbacks.
|
||||
#
|
||||
# The form is named 'main_form' and resides on file 'test_cb.fd'.
|
||||
# It has three objects named button1, button2 and exitbutton.
|
||||
# All buttons have callbacks with the same names as their corresponding
|
||||
# buttons but with CB appended.
|
||||
#
|
||||
import fl # The forms library
|
||||
import FL # Symbolic constants for the above
|
||||
import flp # The module to parse .fd files
|
||||
import sys
|
||||
|
||||
# The following struct is created to hold the instance variables
|
||||
# main_form, button1, button2 and exitbutton.
|
||||
|
||||
class myform:
|
||||
#
|
||||
# The constructor parses and creates the form, but doesn't
|
||||
# display it (yet).
|
||||
def __init__(self, number):
|
||||
#
|
||||
# First we parse the form
|
||||
parsetree = flp.parse_form('test_cb', 'main_form')
|
||||
#
|
||||
# Next we create it
|
||||
|
||||
flp.create_full_form(self, parsetree)
|
||||
|
||||
# And keep our number
|
||||
self.number = number
|
||||
|
||||
#
|
||||
# The show function displays the form. It doesn't do any interaction,
|
||||
# though.
|
||||
def show(self):
|
||||
self.main_form.show_form(FL.PLACE_SIZE, 1, '')
|
||||
|
||||
# The callback functions
|
||||
def button1CB(self, obj, arg):
|
||||
print 'Button 1 pressed on form', self.number
|
||||
|
||||
def button2CB(self, obj, arg):
|
||||
print 'Button 2 pressed on form', self.number
|
||||
|
||||
def exitbuttonCB(self, obj, arg):
|
||||
print 'Ok, bye bye'
|
||||
sys.exit(0)
|
||||
|
||||
#
|
||||
# The main program. Instantiate two variables of the forms class
|
||||
# and interact with them.
|
||||
|
||||
form1 = myform(1)
|
||||
form2 = myform(2)
|
||||
|
||||
form1.show()
|
||||
form2.show()
|
||||
|
||||
obj = fl.do_forms()
|
||||
print 'do_forms() returned. This should not happen. obj=', obj
|
|
@ -1,75 +0,0 @@
|
|||
Magic: 12321
|
||||
|
||||
Internal Form Definition File
|
||||
(do not change)
|
||||
|
||||
Number of forms: 1
|
||||
|
||||
=============== FORM ===============
|
||||
Name: main_form
|
||||
Width: 170.000000
|
||||
Height: 190.000000
|
||||
Number of Objects: 4
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 170.000000 190.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 140.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 1
|
||||
name: button1
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 100.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 2
|
||||
name: button2
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 6
|
||||
box: 10.000000 10.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: EXIT
|
||||
name: exitbutton
|
||||
callback:
|
||||
argument:
|
||||
|
||||
==============================
|
||||
create_the_forms
|
|
@ -1,45 +0,0 @@
|
|||
#
|
||||
# Example 1 - Using fl in python without callbacks.
|
||||
#
|
||||
# The form is named 'main_form' and resides on file 'test_nocb.fd'.
|
||||
# It has three objects named button1, button2 and exitbutton.
|
||||
#
|
||||
import fl # The forms library
|
||||
import FL # Symbolic constants for the above
|
||||
import flp # The module to parse .fd files
|
||||
import sys
|
||||
|
||||
# The following struct is created to hold the instance variables
|
||||
# main_form, button1, button2 and exitbutton.
|
||||
|
||||
class struct: pass
|
||||
container = struct()
|
||||
|
||||
#
|
||||
# We now first parse the forms file
|
||||
|
||||
parsetree = flp.parse_form('test_nocb', 'main_form')
|
||||
|
||||
#
|
||||
# Next we create it
|
||||
|
||||
flp.create_full_form(container, parsetree)
|
||||
|
||||
#
|
||||
# And display it
|
||||
|
||||
container.main_form.show_form(FL.PLACE_MOUSE, 1, '')
|
||||
|
||||
#
|
||||
# And interact until the exit button is pressed
|
||||
while 1:
|
||||
selected_obj = fl.do_forms()
|
||||
if selected_obj == container.button1:
|
||||
print 'Button 1 selected'
|
||||
elif selected_obj == container.button2:
|
||||
print 'Button 2 selected'
|
||||
elif selected_obj == container.exitbutton:
|
||||
print 'Ok, bye bye'
|
||||
sys.exit(0)
|
||||
else:
|
||||
print 'do_forms() returned unknown object ', selected_obj
|
|
@ -1,35 +0,0 @@
|
|||
These demos run only on SGI machines and require the 'gl' built-in module.
|
||||
The demonstrate the abilities of SGI's GL library as well as the ease of
|
||||
GL programming in Python. Most demos require the Z-buffer (aka
|
||||
24-bitplane) option. Press ESC to get out of any of them.
|
||||
|
||||
backface.py Demonstrates the 'backface' GL function.
|
||||
|
||||
kites.py Show 3 flying kites. Demonstrates the rendering speed
|
||||
obtainable by Python programs.
|
||||
|
||||
kunst.py Cute demo showing a ball suspended on four cables in
|
||||
the central room of the CWI building. You can specify
|
||||
three functions Fx(t), Fy(t), Fz(t) which define the
|
||||
movement of the ball. Try something like sin(t),
|
||||
cos(t), sin(2*t).
|
||||
|
||||
mclock.py A colorful clock with more options than you can
|
||||
remember. Works on 8-bit machines, but allows more
|
||||
colors on 24-bit machines. See mclock.doc for more
|
||||
info.
|
||||
|
||||
mixing.py Demonstrates the effect of color mixing: through
|
||||
frequent color switching it gives the effect of white
|
||||
light.
|
||||
|
||||
nurbs.py A simple demonstration of the 'nurbs' GL functions.
|
||||
Press left mouse button to toggle surface trimming.
|
||||
|
||||
zrgb.py Displays a 3-D Gouraud-shaded figure which can be moved
|
||||
around with the mouse.
|
||||
|
||||
glstdwin/ This is quite different: a partial STDWIN emulation
|
||||
using GL! Requires only small changes to Python
|
||||
programs that use STDWIN. Some features not yet
|
||||
implemented, e.g., scroll bars.
|
|
@ -1,140 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# backface
|
||||
#
|
||||
# draw a cube that can run with backface() turned on or off.
|
||||
# cube is moved when LEFTMOUSE is pressed and mouse itself is moved.
|
||||
|
||||
from gl import *
|
||||
from DEVICE import *
|
||||
from GL import *
|
||||
|
||||
CUBE_SIZE = 200.0
|
||||
CUBE_OBJ = 1
|
||||
|
||||
def main () :
|
||||
#
|
||||
x = 0
|
||||
y = 0
|
||||
moveit = 0
|
||||
#
|
||||
initialize()
|
||||
#
|
||||
while (1) :
|
||||
#
|
||||
while (qtest()) :
|
||||
dev, val = qread()
|
||||
#
|
||||
if dev == ESCKEY :
|
||||
backface(0)
|
||||
return
|
||||
#
|
||||
elif dev == REDRAW :
|
||||
reshapeviewport()
|
||||
drawcube(x,y)
|
||||
#
|
||||
elif dev == LEFTMOUSE :
|
||||
#
|
||||
# LEFTMOUSE down
|
||||
moveit = val
|
||||
#
|
||||
elif dev == BKEY :
|
||||
backface(1)
|
||||
drawcube(x,y)
|
||||
#
|
||||
elif dev == FKEY :
|
||||
backface(0)
|
||||
drawcube(x,y)
|
||||
#
|
||||
if moveit :
|
||||
x = getvaluator(MOUSEX)
|
||||
y = getvaluator(MOUSEY)
|
||||
drawcube(x,y)
|
||||
|
||||
|
||||
def initialize () :
|
||||
foreground ()
|
||||
keepaspect (1, 1)
|
||||
gid = winopen('backface')
|
||||
winset(gid)
|
||||
winconstraints()
|
||||
#
|
||||
doublebuffer()
|
||||
gconfig()
|
||||
shademodel(FLAT)
|
||||
#
|
||||
ortho(-1024.0, 1024.0, -1024.0, 1024.0, -1024.0, 1024.0)
|
||||
#
|
||||
qdevice(ESCKEY)
|
||||
qdevice(REDRAW)
|
||||
qdevice(LEFTMOUSE)
|
||||
qdevice(BKEY)
|
||||
qdevice(FKEY)
|
||||
qenter(REDRAW,gid)
|
||||
#
|
||||
backface(1)
|
||||
|
||||
#
|
||||
# define a cube
|
||||
def cube () :
|
||||
#
|
||||
# front face
|
||||
pushmatrix()
|
||||
translate(0.0,0.0,CUBE_SIZE)
|
||||
color(RED)
|
||||
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
|
||||
popmatrix()
|
||||
#
|
||||
# right face
|
||||
pushmatrix()
|
||||
translate(CUBE_SIZE, 0.0, 0.0)
|
||||
rotate(900, 'y')
|
||||
color(GREEN)
|
||||
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
|
||||
popmatrix()
|
||||
#
|
||||
# back face
|
||||
pushmatrix()
|
||||
translate(0.0, 0.0, -CUBE_SIZE)
|
||||
rotate(1800, 'y')
|
||||
color(BLUE)
|
||||
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
|
||||
popmatrix()
|
||||
#
|
||||
# left face
|
||||
pushmatrix()
|
||||
translate(-CUBE_SIZE, 0.0, 0.0)
|
||||
rotate(-900, 'y')
|
||||
color(CYAN)
|
||||
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
|
||||
popmatrix()
|
||||
#
|
||||
# top face
|
||||
pushmatrix()
|
||||
translate(0.0, CUBE_SIZE, 0.0)
|
||||
rotate(-900, 'x')
|
||||
color(MAGENTA)
|
||||
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
|
||||
popmatrix()
|
||||
#
|
||||
# bottom face
|
||||
pushmatrix()
|
||||
translate(0.0, -CUBE_SIZE, 0.0)
|
||||
rotate(900, 'x')
|
||||
color(YELLOW)
|
||||
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
|
||||
popmatrix()
|
||||
|
||||
def drawcube(x,y) :
|
||||
#
|
||||
pushmatrix()
|
||||
rotate(2*x, 'x')
|
||||
rotate(2*y, 'y')
|
||||
color(BLACK)
|
||||
clear()
|
||||
cube()
|
||||
popmatrix()
|
||||
swapbuffers()
|
||||
|
||||
|
||||
main ()
|
|
@ -1,20 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Print the values of all values that can be inquired with getgdesc().
|
||||
# See man getgdesc() for a description.
|
||||
|
||||
import gl
|
||||
import GL
|
||||
|
||||
def main():
|
||||
names = []
|
||||
maxlen = 0
|
||||
for name in dir(GL):
|
||||
if name[:3] == 'GD_':
|
||||
names.append(name)
|
||||
maxlen = max(maxlen, len(name))
|
||||
for name in names:
|
||||
print name + (maxlen - len(name))*' ' + '=',
|
||||
print gl.getgdesc(getattr(GL, name))
|
||||
|
||||
main()
|
|
@ -1,194 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# *** This only works correctly on a 24 bit-plane machine. ***
|
||||
#
|
||||
# A simple Python program that tests the some parts of the
|
||||
# GL library. It shows the speed that can be obtained when
|
||||
# doing simple graphics.
|
||||
#
|
||||
# The bottleneck in this program is NOT Python but the graphics
|
||||
# engine; i.e Python can feed the graphics pipeline fast enough
|
||||
# on the 4D/25G.
|
||||
#
|
||||
# This program show 3 kites flying around the screen. It uses
|
||||
#
|
||||
# * bgnpolygon, endpolygon
|
||||
# * v3, n3
|
||||
# * lmdef, lmbind
|
||||
#
|
||||
# Usage :
|
||||
#
|
||||
# ESC -> exit program
|
||||
# MOUSE3 -> freeze toggle
|
||||
# MOUSE2 -> one step (use this in freeze state)
|
||||
|
||||
from GL import *
|
||||
from gl import *
|
||||
import DEVICE
|
||||
from math import *
|
||||
|
||||
#
|
||||
# viewobj : sets the rotation, translation and scaling
|
||||
# set appropiate material, call drawobject()
|
||||
#
|
||||
def viewobj (r, s, t, mat) :
|
||||
pushmatrix()
|
||||
rot (r * 10.0, 'X')
|
||||
rot (r * 10.0, 'Y')
|
||||
rot (r * 10.0, 'Z')
|
||||
scale (s[0], s[1], s[2])
|
||||
translate (t[0], t[1], t[2])
|
||||
lmbind(MATERIAL, mat)
|
||||
drawobject()
|
||||
popmatrix()
|
||||
|
||||
#
|
||||
# makeobj : the constructor of the object
|
||||
#
|
||||
def mkobj () :
|
||||
v0 = (-5.0 ,0.0, 0.0)
|
||||
v1 = (0.0 ,5.0, 0.0)
|
||||
v2 = (5.0 ,0.0, 0.0)
|
||||
v3 = (0.0 ,2.0, 0.0)
|
||||
n0 = (sqrt(2.0)/2.0, sqrt(2.0)/2.0, 0.0)
|
||||
vn = ((v0, n0), (v1, n0), (v2, n0), (v3, n0))
|
||||
#
|
||||
return vn
|
||||
|
||||
#
|
||||
# the object itself as an array of vertices and normals
|
||||
#
|
||||
kite = mkobj ()
|
||||
|
||||
#
|
||||
# drawobject : draw a triangle. with bgnpolygon
|
||||
#
|
||||
def drawobject () :
|
||||
#
|
||||
bgnpolygon()
|
||||
vnarray (kite)
|
||||
endpolygon()
|
||||
|
||||
#
|
||||
# identity matrix
|
||||
#
|
||||
idmat=[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
|
||||
|
||||
#
|
||||
# the rgb-value of light-blue
|
||||
#
|
||||
LightBlue = (43,169,255)
|
||||
|
||||
#
|
||||
# the different materials.
|
||||
#
|
||||
m1=[SPECULAR,0.0,0.0,0.6,DIFFUSE,0.0,0.0,0.8,SHININESS,20.0,LMNULL]
|
||||
m2=[SPECULAR,0.8,0.0,0.1,DIFFUSE,0.8,0.0,0.3,SHININESS,120.0,LMNULL]
|
||||
m3=[SPECULAR,0.0,1.0,0.0,DIFFUSE,0.0,0.6,0.0,SHININESS,120.0,LMNULL]
|
||||
|
||||
#
|
||||
# lightsources
|
||||
#
|
||||
light1 = [LCOLOR,1.0,1.0,1.0,POSITION,15.0,15.0,0.0,1.0,LMNULL]
|
||||
light2 = [LCOLOR,1.0,1.0,1.0,POSITION,-15.0,15.0,0.0,1.0,LMNULL]
|
||||
|
||||
#
|
||||
# the lightmodel
|
||||
#
|
||||
model = [AMBIENT,0.2,0.2,0.2,LMNULL]
|
||||
|
||||
#
|
||||
# initgl : opens the window, configures the pipeline to 2buf and zbuf,
|
||||
# sets the viewing, defines and binds the materials
|
||||
#
|
||||
def initgl () :
|
||||
#
|
||||
# open window
|
||||
#
|
||||
foreground ()
|
||||
keepaspect (1, 1)
|
||||
prefposition (100, 500, 100, 500)
|
||||
w = winopen ('PYTHON lights')
|
||||
keepaspect (1, 1)
|
||||
winconstraints()
|
||||
#
|
||||
# configure pipeline (zbuf, 2buf, GOURAUD and RGBmode)
|
||||
#
|
||||
zbuffer (1)
|
||||
doublebuffer ()
|
||||
shademodel (GOURAUD)
|
||||
RGBmode ()
|
||||
gconfig ()
|
||||
#
|
||||
# define and bind materials (set perspective BEFORE loadmat !)
|
||||
#
|
||||
mmode(MVIEWING)
|
||||
perspective (900, 1.0, 1.0, 20.0)
|
||||
loadmatrix(idmat)
|
||||
lmdef(DEFMATERIAL, 1, m1)
|
||||
lmdef(DEFMATERIAL, 2, m2)
|
||||
lmdef(DEFMATERIAL, 3, m3)
|
||||
lmdef(DEFLIGHT, 1, light1)
|
||||
lmdef(DEFLIGHT, 2, light2)
|
||||
lmdef(DEFLMODEL, 1, model)
|
||||
lmbind(LIGHT0,1)
|
||||
lmbind(LIGHT1,2)
|
||||
lmbind(LMODEL,1)
|
||||
#
|
||||
# set viewing
|
||||
#
|
||||
lookat (0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0)
|
||||
#
|
||||
# ask for the REDRAW and ESCKEY events
|
||||
#
|
||||
qdevice(DEVICE.MOUSE3)
|
||||
qdevice(DEVICE.MOUSE2)
|
||||
qdevice(DEVICE.REDRAW)
|
||||
qdevice(DEVICE.ESCKEY)
|
||||
|
||||
#
|
||||
# GoForIT : use 2buf to redraw the object 2n times. index i is used as
|
||||
# the (smoothly changing) rotation angle
|
||||
#
|
||||
def GoForIt(i) :
|
||||
freeze = 1
|
||||
while 1 :
|
||||
if freeze <> 0 :
|
||||
i = i + 1
|
||||
#
|
||||
# clear z-buffer and clear background to light-blue
|
||||
#
|
||||
zclear()
|
||||
c3i (LightBlue)
|
||||
clear()
|
||||
#
|
||||
# draw the 3 traiangles scaled above each other.
|
||||
#
|
||||
viewobj(float(i),[1.0,1.0,1.0],[1.0,1.0,1.0],1)
|
||||
viewobj(float(i),[0.75,0.75,0.75],[0.0,2.0,2.0],2)
|
||||
viewobj(float(i),[0.5,0.5,0.5],[0.0,4.0,4.0],3)
|
||||
#
|
||||
swapbuffers()
|
||||
#
|
||||
if qtest() <> 0 :
|
||||
dev, val = qread()
|
||||
if dev == DEVICE.ESCKEY :
|
||||
break
|
||||
elif dev == DEVICE.REDRAW :
|
||||
reshapeviewport ()
|
||||
elif dev == DEVICE.MOUSE3 and val <> 0 :
|
||||
freeze = 1 - freeze
|
||||
elif dev == DEVICE.MOUSE2 and val <> 0 :
|
||||
i = i + 1
|
||||
|
||||
|
||||
# the main program
|
||||
#
|
||||
def main () :
|
||||
initgl ()
|
||||
GoForIt (0)
|
||||
|
||||
#
|
||||
# exec main
|
||||
#
|
||||
main ()
|
|
@ -1,426 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
# Simulate the artwork in the hall.
|
||||
# Jack Jansen, Feb 91.
|
||||
|
||||
from gl import *
|
||||
from GL import *
|
||||
from math import *
|
||||
from DEVICE import *
|
||||
import sys
|
||||
import __main__
|
||||
main_dict = __main__.__dict__
|
||||
|
||||
SPOTDIRECTION = 103
|
||||
SPOTLIGHT = 104
|
||||
|
||||
#
|
||||
# Make a cylinder paralel with the Z axis with center (X,Y,0)
|
||||
# and radius 1
|
||||
def mkcyl(nslice, nparts, docircle):
|
||||
cyl = []
|
||||
step = 2.0 / float(nslice)
|
||||
z = -1.0
|
||||
for i in range(nslice):
|
||||
cyl.append(mkslice(z, z+step, nparts, docircle))
|
||||
z = z + step
|
||||
return drawcylinder(cyl)
|
||||
#
|
||||
# Make one part of a cylinder
|
||||
#
|
||||
def mkslice(z1, z2, nparts, docircle):
|
||||
if docircle:
|
||||
w1 = z1
|
||||
w2 = z2
|
||||
w1 = sqrt(1.0-w1*w1)
|
||||
w2 = sqrt(1.0-w2*w2)
|
||||
normalz = 1.0
|
||||
else:
|
||||
w1 = 1.0
|
||||
w2 = 1.0
|
||||
normalz = 0.0
|
||||
slice = []
|
||||
step = (2.0*pi)/float(nparts)
|
||||
angle = 0.0
|
||||
for i in range(nparts+1):
|
||||
vx = cos(angle)
|
||||
vy = sin(angle)
|
||||
slice.append( ((vx*w1,vy*w1,z1), (vx*w1, vy*w1, z1*normalz)) )
|
||||
slice.append( ((vx*w2,vy*w2,z2), (vx*w2, vy*w2, z2*normalz)) )
|
||||
angle = angle + step
|
||||
return slice
|
||||
#
|
||||
# Drawcylinder : draw the cylinder
|
||||
#
|
||||
class struct: pass
|
||||
curobj = struct()
|
||||
curobj.curobj = 1
|
||||
def drawcylinder(cyl):
|
||||
obj = curobj.curobj
|
||||
curobj.curobj = curobj.curobj+1
|
||||
makeobj(obj)
|
||||
for slice in cyl:
|
||||
bgntmesh()
|
||||
vnarray(slice)
|
||||
endtmesh()
|
||||
closeobj()
|
||||
return obj
|
||||
#
|
||||
def drawnormals(cyl):
|
||||
for slice in cyl:
|
||||
for triang in slice:
|
||||
bgnline()
|
||||
v3f(triang[0])
|
||||
v3f(triang[0][0] + triang[1][0], triang[0][1] + triang[1][1], triang[0][2] + triang[1][2])
|
||||
endline()
|
||||
def drawfloors():
|
||||
obj = curobj.curobj
|
||||
curobj.curobj = curobj.curobj+1
|
||||
makeobj(obj)
|
||||
bgnpolygon()
|
||||
v3i(4,6,-6)
|
||||
v3i(-6,6,-6)
|
||||
v3i(-6,-6,-6)
|
||||
v3i(4,-6,-6)
|
||||
endpolygon()
|
||||
for floor in range(3):
|
||||
pos = -1 + 5*floor
|
||||
bgnpolygon()
|
||||
v3i(4,4,pos)
|
||||
v3i(-6,4,pos)
|
||||
v3i(-6,6,pos)
|
||||
v3i(4,6,pos)
|
||||
endpolygon()
|
||||
bgnpolygon()
|
||||
v3i(-4,4,pos)
|
||||
v3i(-4,-4,pos)
|
||||
v3i(-6,-4,pos)
|
||||
v3i(-6,4,pos)
|
||||
endpolygon()
|
||||
bgnpolygon()
|
||||
v3i(-6,-4,pos)
|
||||
v3i(-6,-6,pos)
|
||||
v3i(4,-6,pos)
|
||||
v3i(4,-4,pos)
|
||||
endpolygon()
|
||||
closeobj()
|
||||
return obj
|
||||
def drawdoors():
|
||||
obj = curobj.curobj
|
||||
curobj.curobj = curobj.curobj+1
|
||||
makeobj(obj)
|
||||
for floor in range(3):
|
||||
pos = -1+5*floor
|
||||
bgnpolygon()
|
||||
v3i(-2,6,pos)
|
||||
v3i(-2,6,pos+3)
|
||||
v3i(0,6,pos+3)
|
||||
v3i(0,6,pos)
|
||||
endpolygon()
|
||||
closeobj()
|
||||
return obj
|
||||
def drawrailing():
|
||||
obj = curobj.curobj
|
||||
curobj.curobj = curobj.curobj+1
|
||||
makeobj(obj)
|
||||
for floor in range(3):
|
||||
pos = -1 + 5*floor
|
||||
bgnpolygon()
|
||||
v3i(4,4,pos)
|
||||
v3i(4,4,pos-1)
|
||||
v3i(-4,4,pos-1)
|
||||
v3i(-4,4,pos)
|
||||
endpolygon()
|
||||
bgnpolygon()
|
||||
v3i(-4,4,pos)
|
||||
v3i(-4,4,pos-1)
|
||||
v3i(-4,-4,pos-1)
|
||||
v3i(-4,-4,pos)
|
||||
endpolygon()
|
||||
bgnpolygon()
|
||||
v3i(-4,-4,pos)
|
||||
v3i(-4,-4,pos-1)
|
||||
v3i(4,-4,pos-1)
|
||||
v3i(4,-4,pos)
|
||||
endpolygon()
|
||||
closeobj()
|
||||
return obj
|
||||
def drawwalls():
|
||||
obj = curobj.curobj
|
||||
curobj.curobj = curobj.curobj+1
|
||||
makeobj(obj)
|
||||
bgnpolygon()
|
||||
v3i(4,6,-6)
|
||||
v3i(4,6,18)
|
||||
v3i(-6,6,18)
|
||||
v3i(-6,6,-6)
|
||||
endpolygon()
|
||||
bgnpolygon()
|
||||
v3i(-6,6,-6)
|
||||
v3i(-6,6,18)
|
||||
v3i(-6,-6,18)
|
||||
v3i(-6,-6,-6)
|
||||
endpolygon()
|
||||
bgnpolygon()
|
||||
v3i(-6,-6,-6)
|
||||
v3i(-6,-6,18)
|
||||
v3i(4,-6,18)
|
||||
v3i(4,-6,-6)
|
||||
endpolygon()
|
||||
bgnpolygon()
|
||||
v3i(4,-6,-6)
|
||||
v3i(4,-6,18)
|
||||
v3i(4,4,18)
|
||||
v3i(4,4,-6)
|
||||
endpolygon()
|
||||
closeobj()
|
||||
return obj
|
||||
def axis():
|
||||
bgnline()
|
||||
cpack(0xff0000)
|
||||
v3i(-1,0,0)
|
||||
v3i(1,0,0)
|
||||
v3f(1.0, 0.1, 0.1)
|
||||
endline()
|
||||
bgnline()
|
||||
cpack(0xff00)
|
||||
v3i(0,-1,0)
|
||||
v3i(0,1,0)
|
||||
v3f(0.1, 1.0, 0.1)
|
||||
endline()
|
||||
bgnline()
|
||||
cpack(0xff)
|
||||
v3i(0,0,-1)
|
||||
v3i(0,0,1)
|
||||
v3f(0.1,0.1,1.0)
|
||||
endline()
|
||||
#
|
||||
green_velvet = [ DIFFUSE, 0.05, 0.4, 0.05, LMNULL]
|
||||
silver = [ DIFFUSE, 0.3, 0.3, 0.3, SPECULAR, 0.9, 0.9, 0.95, \
|
||||
SHININESS, 40.0, LMNULL]
|
||||
floormat = [ AMBIENT, 0.5, 0.25, 0.15, DIFFUSE, 0.5, 0.25, 0.15, SPECULAR, 0.6, 0.3, 0.2, SHININESS, 20.0, LMNULL]
|
||||
wallmat = [ DIFFUSE, 0.4, 0.2, 0.1, AMBIENT, 0.4, 0.20, 0.10, SPECULAR, 0.0, 0.0, 0.0, SHININESS, 20.0, LMNULL]
|
||||
offwhite = [ DIFFUSE, 0.8, 0.8, 0.6, AMBIENT, 0.8, 0.8, 0.6, SPECULAR, 0.9, 0.9, 0.9, SHININESS, 30.0, LMNULL]
|
||||
doormat = [ DIFFUSE, 0.1, 0.2, 0.5, AMBIENT, 0.2, 0.4, 1.0, SPECULAR, 0.2, 0.4, 1.0, SHININESS, 60.0, LMNULL]
|
||||
|
||||
toplight = [ LCOLOR, 1.0, 1.0, 0.5, \
|
||||
POSITION, 0.0, 0.0, 11.0, 1.0, LMNULL]
|
||||
floor1light = [ LCOLOR, 1.0, 1.0, 1.0, POSITION, 3.9, -3.9, 0.0, 1.0, \
|
||||
SPOTDIRECTION, 1.0, 1.0, 0.0, SPOTLIGHT, 10.0, 90.0, LMNULL]
|
||||
|
||||
lmodel = [ AMBIENT, 0.92, 0.8, 0.5, LOCALVIEWER, 1.0, LMNULL]
|
||||
#
|
||||
def lighting():
|
||||
lmdef(DEFMATERIAL, 1, green_velvet)
|
||||
lmdef(DEFMATERIAL, 2, silver)
|
||||
lmdef(DEFMATERIAL, 3, floormat)
|
||||
lmdef(DEFMATERIAL, 4, wallmat)
|
||||
lmdef(DEFMATERIAL, 5, offwhite)
|
||||
lmdef(DEFMATERIAL, 6, doormat)
|
||||
lmdef(DEFLIGHT, 1, toplight)
|
||||
lmdef(DEFLIGHT, 2, floor1light)
|
||||
lmdef(DEFLMODEL, 1, lmodel)
|
||||
lmbind(MATERIAL, 1)
|
||||
lmbind(LIGHT0, 1)
|
||||
lmbind(LIGHT1, 2)
|
||||
lmbind(LMODEL, 1)
|
||||
IdMat=[1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0]
|
||||
#
|
||||
def defun(axis):
|
||||
done = 0
|
||||
while not done:
|
||||
print 'F'+axis+'(t) = ',
|
||||
s = sys.stdin.readline(100)
|
||||
print
|
||||
try:
|
||||
s = 'def f'+axis+'(t): return '+s
|
||||
exec(s, main_dict)
|
||||
done = 1
|
||||
except RuntimeError:
|
||||
print 'Sorry, there is a syntax error in your expression'
|
||||
def getfunctions():
|
||||
print 'Welcome to the CWI art simulator. You can now enter X, Y and Z'
|
||||
print 'coordinates as a function of t.'
|
||||
print 'Normal trig functions are available. Please use floating point'
|
||||
print 'values only (so 0.0 for 0). Comments to jack@cwi.nl'
|
||||
defun('x')
|
||||
defun('y')
|
||||
defun('z')
|
||||
print 'Ok, here you go. Use mouse+right button to move up/down,'
|
||||
print 'mouse+middle to speed up/slow down time. type ESC to quit simulation'
|
||||
def main():
|
||||
getfunctions()
|
||||
foreground()
|
||||
prefposition(100,600,100,600)
|
||||
void = winopen('cyl')
|
||||
qdevice(ESCKEY)
|
||||
qdevice(MOUSE1)
|
||||
qdevice(MOUSE2)
|
||||
qdevice(PKEY)
|
||||
RGBmode()
|
||||
doublebuffer()
|
||||
gconfig()
|
||||
zbuffer(1)
|
||||
mmode(MVIEWING)
|
||||
perspective(400, 1.0, 1.0, 20.0)
|
||||
loadmatrix(IdMat)
|
||||
vx = 0.0
|
||||
vy = -6.0
|
||||
vz = 0.0
|
||||
lookat(0.0, -6.0, 0.0, 0.0, 0.0, 0.0, 0)
|
||||
lighting()
|
||||
t = -1.0
|
||||
step = 1.0
|
||||
bol = mkcyl(12,24, 1)
|
||||
cable = mkcyl(1, 6, 0)
|
||||
floors = drawfloors()
|
||||
walls = drawwalls()
|
||||
pillar = mkcyl(1,4,0)
|
||||
railing = drawrailing()
|
||||
doors = drawdoors()
|
||||
shademodel(GOURAUD)
|
||||
mousing = -1
|
||||
pausing = 0
|
||||
while 1:
|
||||
#
|
||||
# Check for some user input
|
||||
#
|
||||
if qtest():
|
||||
dev, value = qread()
|
||||
if dev == PKEY and value == 1:
|
||||
pausing = 1
|
||||
if dev == ESCKEY:
|
||||
break
|
||||
elif (dev==MOUSE1 or dev==MOUSE2) and value == 1:
|
||||
if mousing > 0:
|
||||
vx = 0.0
|
||||
vy = -6.0
|
||||
vz = 0.0
|
||||
mousing = dev
|
||||
oldx = getvaluator(MOUSEX)
|
||||
oldy = getvaluator(MOUSEY)
|
||||
elif (dev==MOUSE1 or dev==MOUSE2):
|
||||
mousing = -1
|
||||
if mousing >= 0:
|
||||
newx = getvaluator(MOUSEX)
|
||||
newy = getvaluator(MOUSEY)
|
||||
if newy <> oldy and mousing==MOUSE1:
|
||||
vz = vz + float(newy - oldy)/100.0
|
||||
dist = sqrt(vx*vx + vy*vy + vz*vz)
|
||||
perspective(400, 1.0, 1.0, dist+16.0)
|
||||
loadmatrix(IdMat)
|
||||
if vz < 0.0:
|
||||
lookat(vx, vy, vz, 0.0, 0.0, 0.0, 1800)
|
||||
else:
|
||||
lookat(vx, vy, vz, 0.0, 0.0, 0.0, 0)
|
||||
if newy <> oldy and mousing==MOUSE2:
|
||||
step = step * exp(float(newy-oldy)/400.0)
|
||||
if getbutton(CTRLKEY) == 0:
|
||||
t = t + step
|
||||
else:
|
||||
t = t - step
|
||||
if getbutton(LEFTSHIFTKEY) == 0:
|
||||
shademodel(GOURAUD)
|
||||
else:
|
||||
shademodel(FLAT)
|
||||
#
|
||||
# Draw background and axis
|
||||
cpack(0x105090)
|
||||
clear()
|
||||
zclear()
|
||||
cpack(0x905010)
|
||||
axis()
|
||||
#
|
||||
# Draw object
|
||||
#
|
||||
bolx = fx(t)
|
||||
boly = fy(t)
|
||||
bolz = fz(t)
|
||||
err = ''
|
||||
if bolx < -4.0 or bolx > 4.0:
|
||||
err = 'X('+`bolx`+') out of range [-4,4]'
|
||||
if boly < -4.0 or boly > 4.0:
|
||||
err = 'Y('+`boly`+') out of range [-4,4]'
|
||||
if bolz < -4.0 or bolz > 8.0:
|
||||
err = 'Z('+`bolz`+') out of range [-4,8]'
|
||||
if not err:
|
||||
pushmatrix()
|
||||
translate(bolx, boly, bolz)
|
||||
scale(0.3, 0.3, 0.3)
|
||||
lmbind(MATERIAL, 2)
|
||||
callobj(bol)
|
||||
popmatrix()
|
||||
#
|
||||
# Draw the cables
|
||||
#
|
||||
bolz = bolz + 0.3
|
||||
pushmatrix()
|
||||
linesmooth(SML_ON)
|
||||
bgnline()
|
||||
v3i(-4,-4,9)
|
||||
v3f(bolx, boly, bolz)
|
||||
endline()
|
||||
bgnline()
|
||||
v3i(-4,4,9)
|
||||
v3f(bolx, boly, bolz)
|
||||
endline()
|
||||
bgnline()
|
||||
v3i(4,-4,9)
|
||||
v3f(bolx, boly, bolz)
|
||||
endline()
|
||||
bgnline()
|
||||
v3i(4,4,9)
|
||||
v3f(bolx, boly, bolz)
|
||||
endline()
|
||||
popmatrix()
|
||||
#
|
||||
# draw the floors
|
||||
#
|
||||
lmbind(MATERIAL, 3)
|
||||
callobj(floors)
|
||||
lmbind(MATERIAL, 4)
|
||||
callobj(walls)
|
||||
lmbind(MATERIAL, 5)
|
||||
pushmatrix()
|
||||
translate(-4.5,4.5,3.0)
|
||||
scale(0.2,0.2,9.0)
|
||||
rotate(450,'z')
|
||||
callobj(pillar)
|
||||
popmatrix()
|
||||
callobj(railing)
|
||||
lmbind(MATERIAL, 6)
|
||||
pushmatrix()
|
||||
translate(0.0, -0.01, 0.0)
|
||||
callobj(doors)
|
||||
popmatrix()
|
||||
if mousing == MOUSE2 or err:
|
||||
cpack(0xff0000)
|
||||
cmov(0.0, 0.0, 0.4)
|
||||
charstr('t='+`t`)
|
||||
if mousing == MOUSE2:
|
||||
cpack(0xff0000)
|
||||
cmov(0.0, 0.0, 0.2)
|
||||
charstr('delta-t='+`step`)
|
||||
if err:
|
||||
cpack(0xff00)
|
||||
cmov(0.0, 0.0, 0.2)
|
||||
print err
|
||||
charstr(err)
|
||||
pausing = 1
|
||||
if pausing:
|
||||
cpack(0xff00)
|
||||
cmov(0.0, 0.0, 0.0)
|
||||
charstr('Pausing, type P to continue')
|
||||
swapbuffers()
|
||||
if pausing:
|
||||
while 1:
|
||||
dv=qread()
|
||||
if dv==(PKEY,1):
|
||||
break
|
||||
if dv==(ESCKEY,1):
|
||||
sys.exit(0)
|
||||
pausing = 0
|
||||
#
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(1)
|
|
@ -1,60 +0,0 @@
|
|||
Newsgroups: cwi.sgi
|
||||
Subject: Re: new clock
|
||||
Distribution: cwi.sgi
|
||||
References: <2246@charon.cwi.nl>
|
||||
|
||||
Last week I wrote:
|
||||
|
||||
>For your enjoyment I have implemented a colorful clock.
|
||||
|
||||
The clock has now been extended with some new facilities: a menu, an
|
||||
alarm and a gong. These may require some explanation beyond what's in
|
||||
the usage message.
|
||||
|
||||
Menu
|
||||
----
|
||||
The right mouse button now pops up a menu that allows you to turn the
|
||||
seconds hand on or off and to switch the alarm off.
|
||||
|
||||
Alarm
|
||||
-----
|
||||
|
||||
The left and middle buttons set the alarm. When it is on, the alarm
|
||||
time is displayed as a time on a 24 hour clock in the bottom left
|
||||
corner. It is also indicated by two red triangles, corresponding to the
|
||||
little (hours) and big (minutes) hand. These hands can be moved around:
|
||||
the left mouse button moves the minutes hand, the middle button moves
|
||||
the hourds hand. Watch out for differences of twelve hours (always
|
||||
check the digital display); these can be corrected by dragging the hours
|
||||
hand once around the dial.
|
||||
|
||||
When the alarm goes off, two things happen: a shell command specified on
|
||||
the command line with the -a option is executed (in the background), and
|
||||
the clock's colors change every two seconds, for five minutes. You can
|
||||
also turn the alarm off by using the menu accessible through the right
|
||||
mouse button.
|
||||
|
||||
There is no default command for the -a option; if it is not specified,
|
||||
only the changing of the colors happens. If you have an 8 ohm speaker
|
||||
connected to the audio output of your Personal Iris, a suitable command
|
||||
would be:
|
||||
|
||||
mclock -a '/ufs/guido/bin/sgi/play /ufs/guido/lib/sounds/alarm'
|
||||
|
||||
Gong
|
||||
----
|
||||
|
||||
Some people like a clock that makes noises every hour, or even more
|
||||
often. This is supported by the -g and -G options. With -g you specify
|
||||
a shell command to be executed to sound the gong; with -G you can
|
||||
specify the interval between gong calls, in seconds (default is one hour).
|
||||
The shell command is executed in the background. It is given two
|
||||
arguments: the hours (on a 24 hour clock!) and the minutes. The
|
||||
executable Python script /ufs/guido/bin/sgi/chime is a suitable example.
|
||||
Again, this only works if you have installed a speaker (I bet 8 ohm
|
||||
speakers are going to be in demand!)
|
||||
|
||||
--
|
||||
Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
|
||||
guido@cwi.nl or ..!hp4nl!cwi.nl!guido or guido%cwi.nl@uunet.uu.net
|
||||
"A thing of beauty is a joy till sunrise"
|
|
@ -1,736 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# "M Clock"
|
||||
#
|
||||
# An implementation in software of an original design by Rob Juda.
|
||||
# Clock implementation: Guido van Rossum.
|
||||
# Alarm and Gong features: Sape Mullender.
|
||||
#
|
||||
# XXX TO DO:
|
||||
# add arguments to specify initial window position and size
|
||||
# find out local time zone difference automatically
|
||||
# add a date indicator
|
||||
# allow multiple alarms
|
||||
# allow the menu to change more parameters
|
||||
|
||||
import sys
|
||||
|
||||
from gl import *
|
||||
from GL import *
|
||||
from DEVICE import *
|
||||
import time
|
||||
import getopt
|
||||
import string
|
||||
import os
|
||||
from math import pi
|
||||
import math
|
||||
|
||||
FULLC = 3600 # Full circle in 1/10-ths of a degree
|
||||
MIDN = 900 # Angle of the 12 o'clock position
|
||||
R, G, B = 0, 1, 2 # Indices of colors in RGB list
|
||||
|
||||
HOUR = 3600 # Number of seconds per hour
|
||||
MINUTE = 60 # Number of seconds per minute
|
||||
|
||||
class struct: pass # Class to define featureless structures
|
||||
Gl = struct() # Object to hold writable global variables
|
||||
|
||||
# Default constants (used in multiple places)
|
||||
|
||||
SCREENBG = 127, 156, 191
|
||||
NPARTS = 9
|
||||
TITLE = 'M Clock'
|
||||
|
||||
# Set timezone, check for daylight saving time
|
||||
TZDIFF = time.timezone
|
||||
if time.localtime(time.time())[-1]:
|
||||
TZDIFF = time.altzone
|
||||
|
||||
# Default parameters
|
||||
|
||||
Gl.foreground = 0 # If set, run in the foreground
|
||||
Gl.fullscreen = 0 # If set, run on full screen
|
||||
Gl.tzdiff = TZDIFF # Seconds west of Greenwich (winter time)
|
||||
Gl.nparts = NPARTS # Number of parts each circle is divided in (>= 2)
|
||||
Gl.debug = 0 # If set, print debug output
|
||||
Gl.doublebuffer = 1 # If set, use double buffering
|
||||
Gl.update = 0 # Update interval; seconds hand is suppressed if > 1
|
||||
Gl.colorsubset = 0 # If set, display only a subset of the colors
|
||||
Gl.cyan = 0 # If set, display cyan overlay (big hand)
|
||||
Gl.magenta = 0 # If set, display magenta overlay (little hand)
|
||||
Gl.yellow = 0 # If set, display yellow overlay (fixed background)
|
||||
Gl.black = 0 # If set, display black overlay (hands)
|
||||
Gl.colormap = 0 # If set, use colormap mode instead of RGB mode
|
||||
Gl.warnings = 0 # If set, print warnings
|
||||
Gl.title = '' # Window title (default set later)
|
||||
Gl.name = 'mclock' # Window title for resources
|
||||
Gl.border = 1 # If set, use a window border (and title)
|
||||
Gl.bg = 0, 0, 0 # Background color R, G, B value
|
||||
Gl.iconic = 0 # Set in iconic state
|
||||
Gl.fg = 255, 0, 0 # Alarm background RGB (either normal or alarm)
|
||||
Gl.ox,Gl.oy = 0,0 # Window origin
|
||||
Gl.cx,Gl.cy = 0,0 # Window size
|
||||
Gl.alarm_set = 0 # Alarm on or off
|
||||
Gl.alarm_on = 0 # Alarm is ringing
|
||||
Gl.alarm_time = 0 # Alarm time in seconds after midnight
|
||||
Gl.alarm_hours = 0 # Alarm hour setting, 24 hour clock
|
||||
Gl.alarm_minutes = 0 # Alarm minutes setting
|
||||
Gl.alarm_rgb = 0,0,0 # Alarm display RGB colors
|
||||
Gl.alarm_cmd = '' # Command to execute when alarm goes off
|
||||
Gl.mouse2down = 0 # Mouse button state
|
||||
Gl.mouse3down = 0 # Mouse button state
|
||||
Gl.gong_cmd = '' # Command to execute when chimes go off
|
||||
Gl.gong_int = 3600 # Gong interval
|
||||
Gl.indices = R, G, B # Colors (permuted when alarm is on)
|
||||
|
||||
def main():
|
||||
#
|
||||
sys.stdout = sys.stderr # All output is errors/warnings etc.
|
||||
#
|
||||
try:
|
||||
args = getoptions()
|
||||
except string.atoi_error, value:
|
||||
usage(string.atoi_error, value)
|
||||
except getopt.error, msg:
|
||||
usage(getopt.error, msg)
|
||||
#
|
||||
if args:
|
||||
realtime = 0
|
||||
hours = string.atoi(args[0])
|
||||
minutes = seconds = 0
|
||||
if args[1:]: minutes = string.atoi(args[1])
|
||||
if args[2:]: seconds = string.atoi(args[2])
|
||||
localtime = ((hours*60)+minutes)*60+seconds
|
||||
else:
|
||||
realtime = 1
|
||||
#
|
||||
if Gl.title == '':
|
||||
if realtime:
|
||||
Gl.title = TITLE
|
||||
else:
|
||||
title = ''
|
||||
for arg in args: title = title + ' ' + arg
|
||||
Gl.title = title[1:]
|
||||
del title
|
||||
#
|
||||
wid = makewindow()
|
||||
Gl.ox,Gl.oy = getorigin()
|
||||
Gl.cx,Gl.cy = getsize()
|
||||
initmenu()
|
||||
clearall()
|
||||
#
|
||||
if not Gl.update:
|
||||
Gl.update = 60
|
||||
#
|
||||
if Gl.update <= 1:
|
||||
Gl.timernoise = 6
|
||||
else:
|
||||
Gl.timernoise = 60
|
||||
noise(TIMER0, Gl.timernoise)
|
||||
#
|
||||
qdevice(WINSHUT)
|
||||
qdevice(WINQUIT)
|
||||
qdevice(ESCKEY)
|
||||
if realtime:
|
||||
qdevice(TIMER0)
|
||||
qdevice(REDRAW)
|
||||
qdevice(WINFREEZE)
|
||||
qdevice(WINTHAW)
|
||||
qdevice(MENUBUTTON) # MOUSE1
|
||||
qdevice(MOUSE3) # Left button
|
||||
qdevice(MOUSE2) # Middle button
|
||||
unqdevice(INPUTCHANGE)
|
||||
#
|
||||
lasttime = 0
|
||||
Gl.change = 1
|
||||
while 1:
|
||||
if realtime:
|
||||
localtime = int(time.time() - Gl.tzdiff)
|
||||
if Gl.alarm_set:
|
||||
if localtime%(24*HOUR) == Gl.alarm_time:
|
||||
# Ring the alarm!
|
||||
if Gl.debug:
|
||||
print 'Rrrringg!'
|
||||
Gl.alarm_on = 1
|
||||
if Gl.alarm_cmd <> '':
|
||||
d = os.system(Gl.alarm_cmd+' '+`Gl.alarm_time/3600`+' '+`(Gl.alarm_time/60)%60` + ' &')
|
||||
Gl.change = 1
|
||||
clearall()
|
||||
if Gl.alarm_on:
|
||||
if (localtime - Gl.alarm_time) % (24*HOUR) > 300:
|
||||
# More than 5 minutes away from alarm
|
||||
Gl.alarm_on = 0
|
||||
if Gl.debug:
|
||||
print 'Alarm turned off'
|
||||
Gl.change = 1
|
||||
clearall()
|
||||
Gl.indices = R, G, B
|
||||
else:
|
||||
if localtime % 2 == 0:
|
||||
# Permute color indices
|
||||
Gl.indices = Gl.indices[2:] + Gl.indices[:2]
|
||||
Gl.change = 1
|
||||
if Gl.gong_cmd <> '' and localtime%Gl.gong_int == 0:
|
||||
d = os.system(Gl.gong_cmd+' '+`(localtime/3600)%24`+' '+`(localtime/60)%60` + ' &')
|
||||
if localtime/Gl.update <> lasttime/Gl.update:
|
||||
if Gl.debug: print 'new time'
|
||||
Gl.change = 1
|
||||
if Gl.change:
|
||||
if Gl.debug: print 'drawing'
|
||||
doit(localtime)
|
||||
lasttime = localtime
|
||||
Gl.change = 0
|
||||
dev, data = qread()
|
||||
if Gl.debug and dev <> TIMER0:
|
||||
print dev, data
|
||||
if dev == TIMER0:
|
||||
if Gl.debug > 1:
|
||||
print dev, data
|
||||
elif dev == MOUSE3:
|
||||
mousex = getvaluator(MOUSEX)
|
||||
mousey = getvaluator(MOUSEY)
|
||||
if mouseclick(3, data, mousex, mousey):
|
||||
Gl.change = 1
|
||||
elif dev == MOUSE2:
|
||||
mousex = getvaluator(MOUSEX)
|
||||
mousey = getvaluator(MOUSEY)
|
||||
if mouseclick(2, data, mousex, mousey):
|
||||
Gl.change = 1
|
||||
elif dev == MOUSEX:
|
||||
mousex = data
|
||||
if Gl.mouse2down:
|
||||
mouse2track(mousex, mousey)
|
||||
if Gl.mouse3down:
|
||||
mouse3track(mousex, mousey)
|
||||
elif dev == MOUSEY:
|
||||
mousey = data
|
||||
if Gl.mouse2down:
|
||||
mouse2track(mousex, mousey)
|
||||
if Gl.mouse3down:
|
||||
mouse3track(mousex, mousey)
|
||||
elif dev == REDRAW or dev == REDRAWICONIC:
|
||||
if Gl.debug:
|
||||
if dev == REDRAW: print 'REDRAW'
|
||||
else: print 'REDRAWICONIC'
|
||||
reshapeviewport()
|
||||
Gl.ox,Gl.oy = getorigin()
|
||||
Gl.cx,Gl.cy = getsize()
|
||||
Gl.change = 1
|
||||
clearall()
|
||||
elif dev == MENUBUTTON:
|
||||
if Gl.debug: print 'MENUBUTTON'
|
||||
handlemenu()
|
||||
elif dev == WINFREEZE:
|
||||
if Gl.debug: print 'WINFREEZE'
|
||||
Gl.iconic = 1
|
||||
noise(TIMER0, 60*60) # Redraw every 60 seconds only
|
||||
elif dev == WINTHAW:
|
||||
if Gl.debug: print 'WINTHAW'
|
||||
Gl.iconic = 0
|
||||
noise(TIMER0, Gl.timernoise)
|
||||
Gl.change = 1
|
||||
elif dev == ESCKEY or dev == WINSHUT or dev == WINQUIT:
|
||||
if Gl.debug: print 'Exit'
|
||||
sys.exit(0)
|
||||
|
||||
def getoptions():
|
||||
optlist, args = getopt.getopt(sys.argv[1:], 'A:a:B:bc:dFfG:g:n:sT:t:u:wCMYK')
|
||||
for optname, optarg in optlist:
|
||||
if optname == '-A':
|
||||
Gl.fg = eval(optarg) # Should be (r,g,b)
|
||||
elif optname == '-a':
|
||||
Gl.alarm_cmd = optarg
|
||||
elif optname == '-B':
|
||||
Gl.bg = eval(optarg) # Should be (r,g,b)
|
||||
elif optname == '-b':
|
||||
Gl.border = 0
|
||||
elif optname == '-c':
|
||||
Gl.colormap = string.atoi(optarg)
|
||||
elif optname == '-d':
|
||||
Gl.debug = Gl.debug + 1
|
||||
Gl.warnings = 1
|
||||
elif optname == '-F':
|
||||
Gl.foreground = 1
|
||||
elif optname == '-f':
|
||||
Gl.fullscreen = 1
|
||||
elif optname == '-G':
|
||||
Gl.gong_int = 60*string.atoi(optarg)
|
||||
elif optname == '-g':
|
||||
Gl.gong_cmd = optarg
|
||||
elif optname == '-n':
|
||||
Gl.nparts = string.atoi(optarg)
|
||||
elif optname == '-s':
|
||||
Gl.doublebuffer = 0
|
||||
elif optname == '-T':
|
||||
Gl.title = Gl.name = optarg
|
||||
elif optname == '-t':
|
||||
Gl.tzdiff = string.atoi(optarg)
|
||||
elif optname == '-u':
|
||||
Gl.update = string.atoi(optarg)
|
||||
elif optname == '-w':
|
||||
Gl.warnings = 1
|
||||
elif optname == '-C':
|
||||
Gl.cyan = Gl.colorsubset = 1
|
||||
elif optname == '-M':
|
||||
Gl.magenta = Gl.colorsubset = 1
|
||||
elif optname == '-Y':
|
||||
Gl.yellow = Gl.colorsubset = 1
|
||||
elif optname == '-K':
|
||||
Gl.black = Gl.colorsubset = 1
|
||||
else:
|
||||
print 'Unsupported option', optname
|
||||
return args
|
||||
|
||||
def usage(exc, msg):
|
||||
if sys.argv:
|
||||
progname = os.path.basename(sys.argv[0])
|
||||
else:
|
||||
progname = 'mclock'
|
||||
#
|
||||
print progname + ':',
|
||||
if exc == string.atoi_error:
|
||||
print 'non-numeric argument:',
|
||||
print msg
|
||||
#
|
||||
print 'usage:', progname, '[options] [hh [mm [ss]]]'
|
||||
#
|
||||
print '-A r,g,b : alarm background red,green,blue [255,0,0]'
|
||||
print '-a cmd : shell command executed when alarm goes off'
|
||||
print '-B r,g,b : background red,green,blue [0,0,0]'
|
||||
print ' (-B SCREENBG uses the default screen background)'
|
||||
print '-b : suppress window border and title'
|
||||
print '-c cmapid : select explicit colormap'
|
||||
print '-d : more debug output (implies -F, -w)'
|
||||
print '-F : run in foreground'
|
||||
print '-f : use full screen'
|
||||
print '-G intrvl : interval between chimes in minutes [60]'
|
||||
print '-g cmd : shell command executed when chimes go off'
|
||||
print '-s : single buffer mode'
|
||||
print '-w : print various warnings'
|
||||
print '-n nparts : number of parts [' + `NPARTS` + ']'
|
||||
print '-T title : alternate window title [\'' + TITLE + '\']'
|
||||
print '-t tzdiff : time zone difference [' + `TZDIFF` + ']'
|
||||
print '-u update : update interval [60]'
|
||||
print '-CMYK : Cyan, Magenta, Yellow or blacK overlay only'
|
||||
print 'if hh [mm [ss]] is specified, display that time statically'
|
||||
print 'on machines with < 12 bitplanes, -s is forced on'
|
||||
#
|
||||
sys.exit(2)
|
||||
|
||||
def doit(localtime):
|
||||
hands = makehands(localtime)
|
||||
list = makelist(hands)
|
||||
render(list, hands)
|
||||
|
||||
def makehands(localtime):
|
||||
localtime = localtime % (12*HOUR)
|
||||
seconds_hand = MIDN + FULLC - (localtime*60) % FULLC
|
||||
big_hand = (MIDN + FULLC - (localtime%HOUR)) % FULLC
|
||||
little_hand = (MIDN + FULLC - ((localtime/12) % HOUR)) % FULLC
|
||||
return little_hand, big_hand, seconds_hand
|
||||
|
||||
def makelist(hands):
|
||||
little_hand, big_hand, seconds_hand = hands
|
||||
total = []
|
||||
if Gl.cyan or not Gl.colorsubset:
|
||||
total = total + makesublist(big_hand, Gl.indices[0])
|
||||
if Gl.magenta or not Gl.colorsubset:
|
||||
total = total + makesublist(little_hand, Gl.indices[1])
|
||||
if Gl.yellow or not Gl.colorsubset:
|
||||
total = total + makesublist(MIDN, Gl.indices[2])
|
||||
total.sort()
|
||||
return total
|
||||
|
||||
def makesublist(first, icolor):
|
||||
list = []
|
||||
alpha = FULLC/Gl.nparts
|
||||
a = first - alpha/2
|
||||
for i in range(Gl.nparts):
|
||||
angle = (a + i*alpha + FULLC) % FULLC
|
||||
value = 255*(Gl.nparts-1-i)/(Gl.nparts-1)
|
||||
list.append((angle, icolor, value))
|
||||
list.sort()
|
||||
a, icolor, value = list[0]
|
||||
if a <> 0:
|
||||
a, icolor, value = list[len(list)-1]
|
||||
t = 0, icolor, value
|
||||
list.insert(0, t)
|
||||
return list
|
||||
|
||||
def rgb_fg():
|
||||
return Gl.fg
|
||||
# Obsolete code:
|
||||
if Gl.alarm_on:
|
||||
return Gl.bg
|
||||
else:
|
||||
return Gl.fg
|
||||
|
||||
def rgb_bg():
|
||||
return Gl.bg
|
||||
# Obsolete code:
|
||||
if Gl.alarm_on:
|
||||
return Gl.fg
|
||||
else:
|
||||
return Gl.bg
|
||||
|
||||
def clearall():
|
||||
Gl.c3i(rgb_bg())
|
||||
clear()
|
||||
if Gl.doublebuffer:
|
||||
swapbuffers()
|
||||
clear()
|
||||
|
||||
def draw_alarm(color):
|
||||
frontbuffer(TRUE)
|
||||
Gl.c3i(color)
|
||||
pushmatrix()
|
||||
rotate(-((Gl.alarm_time/12)%3600), 'z')
|
||||
bgnpolygon()
|
||||
v2f( 0.00,1.00)
|
||||
v2f( 0.04,1.05)
|
||||
v2f(-0.04,1.05)
|
||||
endpolygon()
|
||||
popmatrix()
|
||||
#
|
||||
pushmatrix()
|
||||
rotate(-((Gl.alarm_time)%3600), 'z')
|
||||
bgnpolygon()
|
||||
v2f( 0.00,1.05)
|
||||
v2f( 0.07,1.10)
|
||||
v2f(-0.07,1.10)
|
||||
endpolygon()
|
||||
popmatrix()
|
||||
#
|
||||
cmov2(-1.06, -1.06)
|
||||
charstr(string.rjust(`Gl.alarm_time/3600`,2))
|
||||
charstr(':')
|
||||
charstr(string.zfill((Gl.alarm_time/60)%60,2))
|
||||
frontbuffer(FALSE)
|
||||
|
||||
def render(list, (little_hand, big_hand, seconds_hand)):
|
||||
#
|
||||
if Gl.colormap:
|
||||
resetindex()
|
||||
#
|
||||
if not list:
|
||||
Gl.c3i((255, 255, 255)) # White
|
||||
circf(0.0, 0.0, 1.0)
|
||||
else:
|
||||
list.append((3600, 0, 255)) # Sentinel
|
||||
#
|
||||
rgb = [255, 255, 255]
|
||||
a_prev = 0
|
||||
for a, icolor, value in list:
|
||||
if a <> a_prev:
|
||||
[r, g, b] = rgb
|
||||
if Gl.debug > 1:
|
||||
print rgb, a_prev, a
|
||||
Gl.c3i((r, g, b))
|
||||
arcf(0.0, 0.0, 1.0, a_prev, a)
|
||||
rgb[icolor] = value
|
||||
a_prev = a
|
||||
#
|
||||
if Gl.black or not Gl.colorsubset:
|
||||
#
|
||||
# Draw the hands -- in black
|
||||
#
|
||||
Gl.c3i((0, 0, 0))
|
||||
#
|
||||
if Gl.update == 1 and not Gl.iconic:
|
||||
# Seconds hand is only drawn if we update every second
|
||||
pushmatrix()
|
||||
rotate(seconds_hand, 'z')
|
||||
bgnline()
|
||||
v2f(0.0, 0.0)
|
||||
v2f(1.0, 0.0)
|
||||
endline()
|
||||
popmatrix()
|
||||
#
|
||||
pushmatrix()
|
||||
rotate(big_hand, 'z')
|
||||
rectf(0.0, -0.01, 0.97, 0.01)
|
||||
circf(0.0, 0.0, 0.01)
|
||||
circf(0.97, 0.0, 0.01)
|
||||
popmatrix()
|
||||
#
|
||||
pushmatrix()
|
||||
rotate(little_hand, 'z')
|
||||
rectf(0.04, -0.02, 0.63, 0.02)
|
||||
circf(0.04, 0.0, 0.02)
|
||||
circf(0.63, 0.0, 0.02)
|
||||
popmatrix()
|
||||
#
|
||||
# Draw the alarm time, if set or being set
|
||||
#
|
||||
if Gl.alarm_set:
|
||||
draw_alarm(rgb_fg())
|
||||
#
|
||||
if Gl.doublebuffer: swapbuffers()
|
||||
|
||||
def makewindow():
|
||||
#
|
||||
if Gl.debug or Gl.foreground:
|
||||
foreground()
|
||||
#
|
||||
if Gl.fullscreen:
|
||||
scrwidth, scrheight = getgdesc(GD_XPMAX), getgdesc(GD_YPMAX)
|
||||
prefposition(0, scrwidth-1, 0, scrheight-1)
|
||||
else:
|
||||
keepaspect(1, 1)
|
||||
prefsize(80, 80)
|
||||
#
|
||||
if not Gl.border:
|
||||
noborder()
|
||||
wid = winopen(Gl.name)
|
||||
wintitle(Gl.title)
|
||||
#
|
||||
if not Gl.fullscreen:
|
||||
keepaspect(1, 1)
|
||||
minsize(10, 10)
|
||||
maxsize(2000, 2000)
|
||||
iconsize(66, 66)
|
||||
winconstraints()
|
||||
#
|
||||
nplanes = getplanes()
|
||||
nmaps = getgdesc(GD_NMMAPS)
|
||||
if Gl.warnings:
|
||||
print nplanes, 'color planes,', nmaps, 'color maps'
|
||||
#
|
||||
if Gl.doublebuffer and not Gl.colormap and nplanes < 12:
|
||||
if Gl.warnings: print 'forcing single buffer mode'
|
||||
Gl.doublebuffer = 0
|
||||
#
|
||||
if Gl.colormap:
|
||||
if not Gl.colormap:
|
||||
Gl.colormap = nmaps - 1
|
||||
if Gl.warnings:
|
||||
print 'not enough color planes available',
|
||||
print 'for RGB mode; forcing colormap mode'
|
||||
print 'using color map number', Gl.colormap
|
||||
if not Gl.colorsubset:
|
||||
needed = 3
|
||||
else:
|
||||
needed = Gl.cyan + Gl.magenta + Gl.yellow
|
||||
needed = needed*Gl.nparts
|
||||
if Gl.bg <> (0, 0, 0):
|
||||
needed = needed+1
|
||||
if Gl.fg <> (0, 0, 0):
|
||||
needed = needed+1
|
||||
if Gl.doublebuffer:
|
||||
if needed > available(nplanes/2):
|
||||
Gl.doublebuffer = 0
|
||||
if Gl.warnings:
|
||||
print 'not enough colors available',
|
||||
print 'for double buffer mode;',
|
||||
print 'forcing single buffer mode'
|
||||
else:
|
||||
nplanes = nplanes/2
|
||||
if needed > available(nplanes):
|
||||
# Do this warning always
|
||||
print 'still not enough colors available;',
|
||||
print 'parts will be left white'
|
||||
print '(needed', needed, 'but have only',
|
||||
print available(nplanes), 'colors available)'
|
||||
#
|
||||
if Gl.doublebuffer:
|
||||
doublebuffer()
|
||||
gconfig()
|
||||
#
|
||||
if Gl.colormap:
|
||||
Gl.c3i = pseudo_c3i
|
||||
fixcolormap()
|
||||
else:
|
||||
Gl.c3i = c3i
|
||||
RGBmode()
|
||||
gconfig()
|
||||
#
|
||||
if Gl.fullscreen:
|
||||
# XXX Should find out true screen size using getgdesc()
|
||||
ortho2(-1.1*1.280, 1.1*1.280, -1.1*1.024, 1.1*1.024)
|
||||
else:
|
||||
ortho2(-1.1, 1.1, -1.1, 1.1)
|
||||
#
|
||||
return wid
|
||||
|
||||
def available(nplanes):
|
||||
return pow(2, nplanes) - 1 # Reserve one pixel for black
|
||||
|
||||
def fixcolormap():
|
||||
multimap()
|
||||
gconfig()
|
||||
nplanes = getplanes()
|
||||
if Gl.warnings:
|
||||
print 'multimap mode has', nplanes, 'color planes'
|
||||
imap = Gl.colormap
|
||||
Gl.startindex = pow(2, nplanes) - 1
|
||||
Gl.stopindex = 1
|
||||
setmap(imap)
|
||||
mapcolor(0, 0, 0, 0) # Fixed entry for black
|
||||
if Gl.bg <> (0, 0, 0):
|
||||
r, g, b = Gl.bg
|
||||
mapcolor(1, r, g, b) # Fixed entry for Gl.bg
|
||||
Gl.stopindex = 2
|
||||
if Gl.fg <> (0, 0, 0):
|
||||
r, g, b = Gl.fg
|
||||
mapcolor(2, r, g, b) # Fixed entry for Gl.fg
|
||||
Gl.stopindex = 3
|
||||
Gl.overflow_seen = 0
|
||||
resetindex()
|
||||
|
||||
def resetindex():
|
||||
Gl.index = Gl.startindex
|
||||
|
||||
r0g0b0 = (0, 0, 0)
|
||||
|
||||
def pseudo_c3i(rgb):
|
||||
if rgb == r0g0b0:
|
||||
index = 0
|
||||
elif rgb == Gl.bg:
|
||||
index = 1
|
||||
elif rgb == Gl.fg:
|
||||
index = 2
|
||||
else:
|
||||
index = definecolor(rgb)
|
||||
color(index)
|
||||
|
||||
def definecolor(rgb):
|
||||
index = Gl.index
|
||||
if index < Gl.stopindex:
|
||||
if Gl.debug: print 'definecolor hard case', rgb
|
||||
# First see if we already have this one...
|
||||
for index in range(Gl.stopindex, Gl.startindex+1):
|
||||
if rgb == getmcolor(index):
|
||||
if Gl.debug: print 'return', index
|
||||
return index
|
||||
# Don't clobber reserverd colormap entries
|
||||
if not Gl.overflow_seen:
|
||||
# Shouldn't happen any more, hence no Gl.warnings test
|
||||
print 'mclock: out of colormap entries'
|
||||
Gl.overflow_seen = 1
|
||||
return Gl.stopindex
|
||||
r, g, b = rgb
|
||||
if Gl.debug > 1: print 'mapcolor', (index, r, g, b)
|
||||
mapcolor(index, r, g, b)
|
||||
Gl.index = index - 1
|
||||
return index
|
||||
|
||||
# Compute n**i
|
||||
def pow(n, i):
|
||||
x = 1
|
||||
for j in range(i): x = x*n
|
||||
return x
|
||||
|
||||
def mouseclick(mouse, updown, x, y):
|
||||
if updown == 1:
|
||||
# mouse button came down, start tracking
|
||||
if Gl.debug:
|
||||
print 'mouse', mouse, 'down at', x, y
|
||||
if mouse == 2:
|
||||
Gl.mouse2down = 1
|
||||
mouse2track(x, y)
|
||||
elif mouse == 3:
|
||||
Gl.mouse3down = 1
|
||||
mouse3track(x, y)
|
||||
else:
|
||||
print 'fatal error'
|
||||
qdevice(MOUSEX)
|
||||
qdevice(MOUSEY)
|
||||
return 0
|
||||
else:
|
||||
# mouse button came up, stop tracking
|
||||
if Gl.debug:
|
||||
print 'mouse', mouse, 'up at', x, y
|
||||
unqdevice(MOUSEX)
|
||||
unqdevice(MOUSEY)
|
||||
if mouse == 2:
|
||||
mouse2track(x, y)
|
||||
Gl.mouse2down = 0
|
||||
elif mouse == 3:
|
||||
mouse3track(x, y)
|
||||
Gl.mouse3down = 0
|
||||
else:
|
||||
print 'fatal error'
|
||||
Gl.alarm_set = 1
|
||||
return 1
|
||||
|
||||
def mouse3track(x, y):
|
||||
# first compute polar coordinates from x and y
|
||||
cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
|
||||
x, y = x - cx, y - cy
|
||||
if (x, y) == (0, 0): return # would cause an exception
|
||||
minutes = int(30.5 + 30.0*math.atan2(float(-x), float(-y))/pi)
|
||||
if minutes == 60: minutes = 0
|
||||
a,b = Gl.alarm_minutes/15, minutes/15
|
||||
if (a,b) == (0,3):
|
||||
# Moved backward through 12 o'clock:
|
||||
Gl.alarm_hours = Gl.alarm_hours - 1
|
||||
if Gl.alarm_hours < 0: Gl.alarm_hours = Gl.alarm_hours + 24
|
||||
if (a,b) == (3,0):
|
||||
# Moved forward through 12 o'clock:
|
||||
Gl.alarm_hours = Gl.alarm_hours + 1
|
||||
if Gl.alarm_hours >= 24: Gl.alarm_hours = Gl.alarm_hours - 24
|
||||
Gl.alarm_minutes = minutes
|
||||
seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
|
||||
if seconds <> Gl.alarm_time:
|
||||
draw_alarm(rgb_bg())
|
||||
Gl.alarm_time = seconds
|
||||
draw_alarm(rgb_fg())
|
||||
|
||||
def mouse2track(x, y):
|
||||
# first compute polar coordinates from x and y
|
||||
cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
|
||||
x, y = x - cx, y - cy
|
||||
if (x, y) == (0, 0): return # would cause an exception
|
||||
hours = int(6.5 - float(Gl.alarm_minutes)/60.0 + 6.0*math.atan2(float(-x), float(-y))/pi)
|
||||
if hours == 12: hours = 0
|
||||
if (Gl.alarm_hours,hours) == (0,11):
|
||||
# Moved backward through midnight:
|
||||
Gl.alarm_hours = 23
|
||||
elif (Gl.alarm_hours,hours) == (12,11):
|
||||
# Moved backward through noon:
|
||||
Gl.alarm_hours = 11
|
||||
elif (Gl.alarm_hours,hours) == (11,0):
|
||||
# Moved forward through noon:
|
||||
Gl.alarm_hours = 12
|
||||
elif (Gl.alarm_hours,hours) == (23,0):
|
||||
# Moved forward through midnight:
|
||||
Gl.alarm_hours = 0
|
||||
elif Gl.alarm_hours < 12:
|
||||
Gl.alarm_hours = hours
|
||||
else:
|
||||
Gl.alarm_hours = hours + 12
|
||||
seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
|
||||
if seconds <> Gl.alarm_time:
|
||||
draw_alarm(rgb_bg())
|
||||
Gl.alarm_time = seconds
|
||||
draw_alarm(rgb_fg())
|
||||
|
||||
def initmenu():
|
||||
Gl.pup = pup = newpup()
|
||||
addtopup(pup, 'M Clock%t|Alarm On/Off|Seconds Hand On/Off|Quit', 0)
|
||||
|
||||
def handlemenu():
|
||||
item = dopup(Gl.pup)
|
||||
if item == 1:
|
||||
# Toggle alarm
|
||||
if Gl.alarm_set:
|
||||
Gl.alarm_set = 0
|
||||
Gl.alarm_on = 0
|
||||
else:
|
||||
Gl.alarm_set = 1
|
||||
Gl.change = 1
|
||||
clearall()
|
||||
elif item == 2:
|
||||
# Toggle Seconds Hand
|
||||
if Gl.update == 1:
|
||||
Gl.update = 60
|
||||
Gl.timernoise = 60
|
||||
else:
|
||||
Gl.update = 1
|
||||
Gl.timernoise = 6
|
||||
Gl.change = 1
|
||||
elif item == 3:
|
||||
if Gl.debug: print 'Exit'
|
||||
sys.exit(0)
|
||||
|
||||
main()
|
|
@ -1,116 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Use Gouraud shading to mix colors. Requires Z-buffer.
|
||||
# It changes the color assignments so fast that you see white.
|
||||
# Left button pauses, middle rotates the square. ESC to quit.
|
||||
# Experiment with a larger window (too slow) or smaller window (really white).
|
||||
|
||||
from GL import *
|
||||
from gl import *
|
||||
import DEVICE
|
||||
from math import *
|
||||
|
||||
#
|
||||
# tekenvlak : draw a square. with bgnpolygon
|
||||
#
|
||||
def tekenvlak (vc) :
|
||||
bgnpolygon()
|
||||
#vcarray (vc)
|
||||
for i in vc :
|
||||
c3f (i[1])
|
||||
v3f (i[0])
|
||||
endpolygon()
|
||||
|
||||
#
|
||||
# tekendoos : draw a box
|
||||
#
|
||||
def tekendoos (col) :
|
||||
v = [(-5.0,0.0,0.0),(0.0,5.0,0.0),(5.0,0.0,0.0),(0.0,-5.0,0.0)]
|
||||
vc = [(v[0],col[0]),(v[1],col[1]),(v[2],col[2]),(v[3],col[1])]
|
||||
tekenvlak (vc)
|
||||
|
||||
#
|
||||
# initialize gl
|
||||
#
|
||||
def initgl () :
|
||||
#
|
||||
# open window
|
||||
#
|
||||
foreground ()
|
||||
keepaspect (1, 1)
|
||||
prefposition (100, 500, 100, 500)
|
||||
w = winopen ('PYTHON RGB')
|
||||
keepaspect (1, 1)
|
||||
winconstraints()
|
||||
#
|
||||
# configure pipeline (2buf, GOURAUD and RGBmode)
|
||||
#
|
||||
doublebuffer ()
|
||||
zbuffer (1)
|
||||
shademodel (GOURAUD)
|
||||
RGBmode ()
|
||||
gconfig ()
|
||||
#
|
||||
# set viewing
|
||||
#
|
||||
perspective (900, 1, 1.0, 10.0)
|
||||
polarview (10.0, 0, 0, 0)
|
||||
#
|
||||
# ask for the REDRAW and ESCKEY events
|
||||
#
|
||||
qdevice(DEVICE.MOUSE2)
|
||||
qdevice(DEVICE.MOUSE3)
|
||||
qdevice(DEVICE.REDRAW)
|
||||
qdevice(DEVICE.ESCKEY)
|
||||
|
||||
|
||||
#
|
||||
# the color black
|
||||
#
|
||||
black = 0
|
||||
#
|
||||
# GoForIT : use 2buf to redraw the object 2n times. index i is used as
|
||||
# the (smoothly changing) rotation angle
|
||||
#
|
||||
def GoForIt(i) :
|
||||
col = [(255.0,0.0,0.0), (0.0,255.0,0.0), (0.0,0.0,255.0)]
|
||||
twist = 0
|
||||
freeze = 1
|
||||
while 1 :
|
||||
if freeze <> 0 :
|
||||
col[0],col[1],col[2] = col[1],col[2],col[0]
|
||||
#
|
||||
# clear z-buffer and clear background to light-blue
|
||||
#
|
||||
zclear()
|
||||
cpack (black)
|
||||
clear()
|
||||
#
|
||||
tekendoos (col)
|
||||
#
|
||||
swapbuffers()
|
||||
#
|
||||
if qtest() <> 0 :
|
||||
dev, val = qread()
|
||||
if dev == DEVICE.ESCKEY :
|
||||
break
|
||||
elif dev == DEVICE.REDRAW :
|
||||
reshapeviewport ()
|
||||
elif dev == DEVICE.MOUSE2 and val <> 0 :
|
||||
twist = twist + 30
|
||||
perspective (900, 1, 1.0, 10.0)
|
||||
polarview (10.0, 0, 0, twist)
|
||||
elif dev == DEVICE.MOUSE3 and val <> 0 :
|
||||
freeze = 1 - freeze
|
||||
|
||||
|
||||
# the main program
|
||||
#
|
||||
def main () :
|
||||
initgl ()
|
||||
GoForIt (0)
|
||||
|
||||
#
|
||||
# exec main
|
||||
#
|
||||
main ()
|
|
@ -1,171 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Rotate a 3D surface created using NURBS.
|
||||
#
|
||||
# Press left mouse button to toggle surface trimming.
|
||||
# Press ESC to quit.
|
||||
#
|
||||
# See the GL manual for an explanation of NURBS.
|
||||
|
||||
from gl import *
|
||||
from GL import *
|
||||
from DEVICE import *
|
||||
|
||||
TRUE = 1
|
||||
FALSE = 0
|
||||
ORDER = 4
|
||||
|
||||
idmat = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
|
||||
|
||||
surfknots = [-1, -1, -1, -1, 1, 1, 1, 1]
|
||||
|
||||
def make_ctlpoints():
|
||||
c = []
|
||||
#
|
||||
ci = []
|
||||
ci.append((-2.5, -3.7, 1.0))
|
||||
ci.append((-1.5, -3.7, 3.0))
|
||||
ci.append((1.5, -3.7, -2.5))
|
||||
ci.append((2.5, -3.7, -0.75))
|
||||
c.append(ci)
|
||||
#
|
||||
ci = []
|
||||
ci.append((-2.5, -2.0, 3.0))
|
||||
ci.append((-1.5, -2.0, 4.0))
|
||||
ci.append((1.5, -2.0, -3.0))
|
||||
ci.append((2.5, -2.0, 0.0))
|
||||
c.append(ci)
|
||||
#
|
||||
ci = []
|
||||
ci.append((-2.5, 2.0, 1.0))
|
||||
ci.append((-1.5, 2.0, 0.0))
|
||||
ci.append((1.5, 2.0, -1.0))
|
||||
ci.append((2.5, 2.0, 2.0))
|
||||
c.append(ci)
|
||||
#
|
||||
ci = []
|
||||
ci.append((-2.5, 2.7, 1.25))
|
||||
ci.append((-1.5, 2.7, 0.1))
|
||||
ci.append((1.5, 2.7, -0.6))
|
||||
ci.append((2.5, 2.7, 0.2))
|
||||
c.append(ci)
|
||||
#
|
||||
return c
|
||||
|
||||
ctlpoints = make_ctlpoints()
|
||||
|
||||
trimknots = [0., 0., 0., 1., 1., 2., 2., 3., 3., 4., 4., 4.]
|
||||
|
||||
def make_trimpoints():
|
||||
c = []
|
||||
c.append((1.0, 0.0, 1.0))
|
||||
c.append((1.0, 1.0, 1.0))
|
||||
c.append((0.0, 2.0, 2.0))
|
||||
c.append((-1.0, 1.0, 1.0))
|
||||
c.append((-1.0, 0.0, 1.0))
|
||||
c.append((-1.0, -1.0, 1.0))
|
||||
c.append((0.0, -2.0, 2.0))
|
||||
c.append((1.0, -1.0, 1.0) )
|
||||
c.append((1.0, 0.0, 1.0))
|
||||
return c
|
||||
|
||||
trimpoints = make_trimpoints()
|
||||
|
||||
def main():
|
||||
init_windows()
|
||||
setup_queue()
|
||||
make_lights()
|
||||
init_view()
|
||||
#
|
||||
set_scene()
|
||||
setnurbsproperty( N_ERRORCHECKING, 1.0 )
|
||||
setnurbsproperty( N_PIXEL_TOLERANCE, 50.0 )
|
||||
trim_flag = 0
|
||||
draw_trim_surface(trim_flag)
|
||||
#
|
||||
while 1:
|
||||
while qtest():
|
||||
dev, val = qread()
|
||||
if dev == ESCKEY:
|
||||
return
|
||||
elif dev == WINQUIT:
|
||||
dglclose(-1) # this for DGL only
|
||||
return
|
||||
elif dev == REDRAW:
|
||||
reshapeviewport()
|
||||
set_scene()
|
||||
draw_trim_surface(trim_flag)
|
||||
elif dev == LEFTMOUSE:
|
||||
if val:
|
||||
trim_flag = (not trim_flag)
|
||||
set_scene()
|
||||
draw_trim_surface(trim_flag)
|
||||
|
||||
def init_windows():
|
||||
foreground()
|
||||
#prefposition(0, 500, 0, 500)
|
||||
wid = winopen('nurbs')
|
||||
wintitle('NURBS Surface')
|
||||
doublebuffer()
|
||||
RGBmode()
|
||||
gconfig()
|
||||
lsetdepth(0x000, 0x7fffff)
|
||||
zbuffer( TRUE )
|
||||
|
||||
def setup_queue():
|
||||
qdevice(ESCKEY)
|
||||
qdevice(REDRAW)
|
||||
qdevice(RIGHTMOUSE)
|
||||
qdevice(WINQUIT)
|
||||
qdevice(LEFTMOUSE) #trimming
|
||||
|
||||
def init_view():
|
||||
mmode(MPROJECTION)
|
||||
ortho( -4., 4., -4., 4., -4., 4. )
|
||||
#
|
||||
mmode(MVIEWING)
|
||||
loadmatrix(idmat)
|
||||
#
|
||||
lmbind(MATERIAL, 1)
|
||||
|
||||
def set_scene():
|
||||
lmbind(MATERIAL, 0)
|
||||
RGBcolor(150,150,150)
|
||||
lmbind(MATERIAL, 1)
|
||||
clear()
|
||||
zclear()
|
||||
#
|
||||
rotate( 100, 'y' )
|
||||
rotate( 100, 'z' )
|
||||
|
||||
def draw_trim_surface(trim_flag):
|
||||
bgnsurface()
|
||||
nurbssurface(surfknots, surfknots, ctlpoints, ORDER, ORDER, N_XYZ)
|
||||
if trim_flag:
|
||||
bgntrim()
|
||||
nurbscurve(trimknots, trimpoints, ORDER-1, N_STW)
|
||||
endtrim()
|
||||
endsurface()
|
||||
swapbuffers()
|
||||
|
||||
def make_lights():
|
||||
lmdef(DEFLMODEL,1,[])
|
||||
lmdef(DEFLIGHT,1,[])
|
||||
#
|
||||
# define material #1
|
||||
#
|
||||
a = []
|
||||
a = a + [EMISSION, 0.0, 0.0, 0.0]
|
||||
a = a + [AMBIENT, 0.1, 0.1, 0.1]
|
||||
a = a + [DIFFUSE, 0.6, 0.3, 0.3]
|
||||
a = a + [SPECULAR, 0.0, 0.6, 0.0]
|
||||
a = a + [SHININESS, 2.0]
|
||||
a = a + [LMNULL]
|
||||
lmdef(DEFMATERIAL, 1, a)
|
||||
#
|
||||
# turn on lighting
|
||||
#
|
||||
lmbind(LIGHT0, 1)
|
||||
lmbind(LMODEL, 1)
|
||||
|
||||
main()
|
|
@ -1,168 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# zrgb (Requires Z buffer.)
|
||||
#
|
||||
# This program demostrates zbuffering 3 intersecting RGB polygons while
|
||||
# in doublebuffer mode where, movement of the mouse with the LEFTMOUSE
|
||||
# button depressed will, rotate the 3 polygons. This is done by compound
|
||||
# rotations allowing continuous screen-oriented rotations.
|
||||
#
|
||||
# Press the "Esc" key to exit.
|
||||
|
||||
from gl import *
|
||||
from GL import *
|
||||
from DEVICE import *
|
||||
|
||||
|
||||
idmat=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
|
||||
|
||||
def main() :
|
||||
#
|
||||
# old and new mouse position
|
||||
#
|
||||
#
|
||||
mode = 0
|
||||
omx = 0
|
||||
mx = 0
|
||||
omy = 0
|
||||
my = 0
|
||||
#
|
||||
objmat=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
|
||||
#
|
||||
initialize ()
|
||||
#
|
||||
draw_scene (objmat)
|
||||
#
|
||||
while (1) :
|
||||
#
|
||||
dev, val = qread()
|
||||
#
|
||||
if dev == ESCKEY :
|
||||
if val :
|
||||
break
|
||||
# exit when key is going up, not down
|
||||
# this avoids the scenario where a window
|
||||
# underneath this program's window
|
||||
# would otherwise "eat up" the up-
|
||||
# event of the Esc key being released
|
||||
return
|
||||
#
|
||||
elif dev == REDRAW :
|
||||
reshapeviewport()
|
||||
draw_scene(objmat)
|
||||
#
|
||||
elif dev == LEFTMOUSE:
|
||||
omx = mx
|
||||
omy = my
|
||||
if val :
|
||||
mode = 1
|
||||
else :
|
||||
mode = 0
|
||||
elif dev == MOUSEX :
|
||||
omx = mx
|
||||
mx = val
|
||||
#print omx, mx
|
||||
objmat = update_scene(objmat,mx,my,omx,omy,mode)
|
||||
#
|
||||
elif dev == MOUSEY :
|
||||
omy = my
|
||||
my = val
|
||||
#print omy, my
|
||||
objmat = update_scene(objmat,mx,my,omx,omy,mode)
|
||||
#
|
||||
|
||||
|
||||
def initialize () :
|
||||
#
|
||||
foreground ()
|
||||
keepaspect(5, 4)
|
||||
w = winopen('Zbuffered RGB')
|
||||
#
|
||||
doublebuffer()
|
||||
RGBmode()
|
||||
gconfig()
|
||||
zbuffer(1)
|
||||
lsetdepth(0x0, 0x7FFFFF)
|
||||
#
|
||||
qdevice(ESCKEY)
|
||||
qdevice(LEFTMOUSE)
|
||||
qdevice(MOUSEX)
|
||||
qdevice(MOUSEY)
|
||||
|
||||
def update_scene (mat, mx, my, omx, omy, mode) :
|
||||
#
|
||||
if mode == 1 :
|
||||
mat = orient(mat, mx, my, omx, omy)
|
||||
draw_scene(mat)
|
||||
return mat
|
||||
|
||||
def orient (mat, mx, my, omx, omy) :
|
||||
#
|
||||
#
|
||||
pushmatrix()
|
||||
loadmatrix(idmat)
|
||||
#
|
||||
if mx - omx : rot (float (mx - omx), 'y')
|
||||
if omy - my : rot (float (omy - my), 'x')
|
||||
#
|
||||
multmatrix(mat)
|
||||
mat = getmatrix()
|
||||
#
|
||||
popmatrix()
|
||||
#
|
||||
return mat
|
||||
|
||||
def draw_scene (mat) :
|
||||
RGBcolor(40, 100, 200)
|
||||
clear()
|
||||
zclear()
|
||||
#
|
||||
perspective(400, 1.25, 30.0, 60.0)
|
||||
translate(0.0, 0.0, -40.0)
|
||||
multmatrix(mat)
|
||||
#
|
||||
# skews original view to show all polygons
|
||||
#
|
||||
rotate(-580, 'y')
|
||||
draw_polys()
|
||||
#
|
||||
swapbuffers()
|
||||
|
||||
polygon1 = [(-10.0,-10.0,0.0),(10.0,-10.0,0.0),(-10.0,10.0,0.0)]
|
||||
|
||||
polygon2 = [(0.0,-10.0,-10.0),(0.0,-10.0,10.0),(0.0,5.0,-10.0)]
|
||||
|
||||
polygon3 = [(-10.0,6.0,4.0),(-10.0,3.0,4.0),(4.0,-9.0,-10.0),(4.0,-6.0,-10.0)]
|
||||
|
||||
def draw_polys():
|
||||
bgnpolygon()
|
||||
cpack(0x0)
|
||||
v3f(polygon1[0])
|
||||
cpack(0x007F7F7F)
|
||||
v3f(polygon1[1])
|
||||
cpack(0x00FFFFFF)
|
||||
v3f(polygon1[2])
|
||||
endpolygon()
|
||||
#
|
||||
bgnpolygon()
|
||||
cpack(0x0000FFFF)
|
||||
v3f(polygon2[0])
|
||||
cpack(0x007FFF00)
|
||||
v3f(polygon2[1])
|
||||
cpack(0x00FF0000)
|
||||
v3f(polygon2[2])
|
||||
endpolygon()
|
||||
#
|
||||
bgnpolygon()
|
||||
cpack(0x0000FFFF)
|
||||
v3f(polygon3[0])
|
||||
cpack(0x00FF00FF)
|
||||
v3f(polygon3[1])
|
||||
cpack(0x00FF0000)
|
||||
v3f(polygon3[2])
|
||||
cpack(0x00FF00FF)
|
||||
v3f(polygon3[3])
|
||||
endpolygon()
|
||||
|
||||
|
||||
main ()
|
|
@ -1 +0,0 @@
|
|||
VeditForm.fdc
|
|
@ -1,99 +0,0 @@
|
|||
# Live video input from display class.
|
||||
|
||||
import gl
|
||||
import GL
|
||||
|
||||
# The live video input class.
|
||||
# Only instantiate this if have_video is true!
|
||||
|
||||
class DisplayVideoIn:
|
||||
|
||||
# Initialize an instance. Arguments:
|
||||
# vw, vh: size of the video window data to be captured.
|
||||
# position defaults to 0, 0 but can be set later
|
||||
def __init__(self, pktmax, vw, vh, type):
|
||||
self.pktmax = pktmax
|
||||
self.realwidth, self.realheight = vw, vh
|
||||
if type <> 'rgb':
|
||||
raise 'Incorrent video data type', type
|
||||
self.type = type
|
||||
self.width = vw
|
||||
self.height = vh
|
||||
#
|
||||
# Open dummy window
|
||||
#
|
||||
gl.foreground()
|
||||
gl.noport()
|
||||
self.wid = gl.winopen('DisplayVideoIn')
|
||||
|
||||
self.x0 = 0
|
||||
self.x1 = self.x0 + self.width - 1
|
||||
self.y0 = 0
|
||||
self.y1 = self.y0 + self.height - 1
|
||||
# Compute # full lines per packet
|
||||
self.lpp = pktmax / self.linewidth()
|
||||
if self.lpp <= 0:
|
||||
raise 'No lines in packet', self.linewidth()
|
||||
self.pktsize = self.lpp*self.linewidth()
|
||||
self.data = None
|
||||
self.old_data = None
|
||||
self.dataoffset = 0
|
||||
self.lpos = 0
|
||||
self.hints = 0
|
||||
|
||||
# Change the size of the video being displayed.
|
||||
|
||||
def resizevideo(self, vw, vh):
|
||||
self.width = vw
|
||||
self.height = vh
|
||||
self.x1 = self.x0 + self.width - 1
|
||||
self.y1 = self.y0 + self.height - 1
|
||||
|
||||
def positionvideo(self, x, y):
|
||||
self.x0 = x
|
||||
self.y0 = y
|
||||
self.x1 = self.x0 + self.width - 1
|
||||
self.y1 = self.y0 + self.height - 1
|
||||
|
||||
# Remove an instance.
|
||||
# This turns off continuous capture.
|
||||
|
||||
def close(self):
|
||||
gl.winclose(self.wid)
|
||||
|
||||
# Get the length in bytes of a video line
|
||||
def linewidth(self):
|
||||
return self.width*4
|
||||
|
||||
# Get the next video packet.
|
||||
# This returns (lpos, data) where:
|
||||
# - lpos is the line position
|
||||
# - data is a piece of data
|
||||
# The dimensions of data are:
|
||||
# - pixel depth = 1 byte
|
||||
# - scan line width = self.width (the vw argument to __init__())
|
||||
# - number of scan lines = self.lpp (PKTMAX / vw)
|
||||
|
||||
def getnextpacket(self):
|
||||
if not self.data or self.dataoffset >= len(self.data):
|
||||
self.old_data = self.data
|
||||
self.data = gl.readdisplay(self.x0, self.y0, \
|
||||
self.x1, self.y1, self.hints)
|
||||
self.dataoffset = 0
|
||||
self.lpos = 0
|
||||
data = self.data[self.dataoffset:self.dataoffset+self.pktsize]
|
||||
while self.old_data and \
|
||||
self.dataoffset+self.pktsize < len(self.data):
|
||||
odata = self.old_data[self.dataoffset: \
|
||||
self.dataoffset+self.pktsize]
|
||||
if odata <> data:
|
||||
break
|
||||
print 'skip', self.lpos
|
||||
self.lpos = self.lpos + self.lpp
|
||||
self.dataoffset = self.dataoffset + self.pktsize
|
||||
data = self.data[self.dataoffset:\
|
||||
self.dataoffset+self.pktsize]
|
||||
lpos = self.lpos
|
||||
self.dataoffset = self.dataoffset + self.pktsize
|
||||
self.lpos = self.lpos + self.lpp
|
||||
return lpos, data
|
|
@ -1,188 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Send live video UDP packets.
|
||||
# Usage: Vsend [-b] [-h height] [-p port] [-s size] [-t ttl] [-w width]
|
||||
# [host] ..
|
||||
|
||||
import sys
|
||||
import time
|
||||
import struct
|
||||
import string
|
||||
import math
|
||||
from socket import *
|
||||
from SOCKET import *
|
||||
import gl, GL, DEVICE
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import DisplayVideoIn
|
||||
import LiveVideoOut
|
||||
import SV
|
||||
import getopt
|
||||
from IN import *
|
||||
|
||||
from senddefs import *
|
||||
|
||||
def usage(msg):
|
||||
print msg
|
||||
print 'usage: Vsend [-b] [-h height] [-p port] [-s size] [-t ttl] [-c type] [-m]',
|
||||
print '[-w width] [host] ...'
|
||||
print '-b : broadcast on local net'
|
||||
print '-h height : window height (default ' + `DEFHEIGHT` + ')'
|
||||
print '-p port : port to use (default ' + `DEFPORT` + ')'
|
||||
print '-t ttl : time-to-live (multicast only; default 1)'
|
||||
print '-s size : max packet size (default ' + `DEFPKTMAX` + ')'
|
||||
print '-S size : use this packet size/window size'
|
||||
print '-w width : window width (default ' + `DEFWIDTH` + ')'
|
||||
print '-v : print packet rate'
|
||||
print '-x xpos : set x position'
|
||||
print '-y ypos : set y position'
|
||||
print '[host] ...: host(s) to send to (default multicast to ' + \
|
||||
DEFMCAST + ')'
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def main():
|
||||
sys.stdout = sys.stderr
|
||||
|
||||
hosts = []
|
||||
port = DEFPORT
|
||||
ttl = -1
|
||||
pktmax = DEFPKTMAX
|
||||
width = DEFWIDTH
|
||||
height = DEFHEIGHT
|
||||
vtype = 'rgb'
|
||||
verbose = 0
|
||||
xpos = ypos = 0
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'bh:p:s:S:t:w:vx:y:')
|
||||
except getopt.error, msg:
|
||||
usage(msg)
|
||||
|
||||
try:
|
||||
for opt, optarg in opts:
|
||||
if opt == '-p':
|
||||
port = string.atoi(optarg)
|
||||
if opt == '-b':
|
||||
host = '<broadcast>'
|
||||
if opt == '-t':
|
||||
ttl = string.atoi(optarg)
|
||||
if opt == '-S':
|
||||
pktmax = string.atoi(optarg)
|
||||
vidmax = SV.PAL_XMAX*SV.PAL_YMAX
|
||||
if vidmax <= pktmax:
|
||||
width = SV.PAL_XMAX
|
||||
height = SV.PAL_YMAX
|
||||
pktmax = vidmax
|
||||
else:
|
||||
factor = float(vidmax)/float(pktmax)
|
||||
factor = math.sqrt(factor)
|
||||
width = int(SV.PAL_XMAX/factor)-7
|
||||
height = int(SV.PAL_YMAX/factor)-5
|
||||
print 'video:',width,'x',height,
|
||||
print 'pktsize',width*height,'..',
|
||||
print pktmax
|
||||
if opt == '-s':
|
||||
pktmax = string.atoi(optarg)
|
||||
if opt == '-w':
|
||||
width = string.atoi(optarg)
|
||||
if opt == '-h':
|
||||
height = string.atoi(optarg)
|
||||
if opt == '-c':
|
||||
vtype = optarg
|
||||
if opt == '-v':
|
||||
verbose = 1
|
||||
if opt == '-x':
|
||||
xpos = string.atoi(optarg)
|
||||
if opt == '-y':
|
||||
ypos = string.atoi(optarg)
|
||||
except string.atoi_error, msg:
|
||||
usage('bad integer: ' + msg)
|
||||
|
||||
for host in args:
|
||||
hosts.append(gethostbyname(host))
|
||||
|
||||
if not hosts:
|
||||
hosts.append(gethostbyname(DEFMCAST))
|
||||
|
||||
gl.foreground()
|
||||
gl.prefsize(width, height)
|
||||
gl.stepunit(8, 6)
|
||||
wid = gl.winopen('Vsend')
|
||||
gl.keepaspect(width, height)
|
||||
gl.stepunit(8, 6)
|
||||
gl.maxsize(SV.PAL_XMAX, SV.PAL_YMAX)
|
||||
gl.winconstraints()
|
||||
gl.qdevice(DEVICE.ESCKEY)
|
||||
gl.qdevice(DEVICE.WINSHUT)
|
||||
gl.qdevice(DEVICE.WINQUIT)
|
||||
gl.qdevice(DEVICE.WINFREEZE)
|
||||
gl.qdevice(DEVICE.WINTHAW)
|
||||
width, height = gl.getsize()
|
||||
|
||||
lvo = LiveVideoOut.LiveVideoOut(wid, width, height, vtype)
|
||||
|
||||
lvi = DisplayVideoIn.DisplayVideoIn(pktmax, width, height, vtype)
|
||||
|
||||
if xpos or ypos:
|
||||
lvi.positionvideo(xpos, ypos)
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
||||
if ttl >= 0:
|
||||
s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, chr(ttl))
|
||||
|
||||
frozen = 0
|
||||
|
||||
lasttime = int(time.time())
|
||||
nframe = 0
|
||||
while 1:
|
||||
|
||||
if gl.qtest():
|
||||
dev, val = gl.qread()
|
||||
if dev in (DEVICE.ESCKEY, \
|
||||
DEVICE.WINSHUT, DEVICE.WINQUIT):
|
||||
break
|
||||
if dev == DEVICE.WINFREEZE:
|
||||
frozen = 1
|
||||
if dev == DEVICE.WINTHAW:
|
||||
frozen = 0
|
||||
if dev == DEVICE.REDRAW:
|
||||
w, h = gl.getsize()
|
||||
x, y = gl.getorigin()
|
||||
if (w, h) <> (width, height):
|
||||
width, height = w, h
|
||||
lvi.resizevideo(width, height)
|
||||
lvo.resizevideo(width, height)
|
||||
|
||||
rv = lvi.getnextpacket()
|
||||
if not rv:
|
||||
time.sleep(0.010)
|
||||
continue
|
||||
|
||||
pos, data = rv
|
||||
print pos, len(data) # DBG
|
||||
|
||||
if not frozen:
|
||||
lvo.putnextpacket(pos, data)
|
||||
|
||||
hdr = struct.pack('hhh', pos, width, height)
|
||||
for host in hosts:
|
||||
try:
|
||||
# print len(hdr+data) # DBG
|
||||
s.sendto(hdr + data, (host, port))
|
||||
except error, msg: # really socket.error
|
||||
if msg[0] <> 121: # no buffer space available
|
||||
raise error, msg # re-raise it
|
||||
print 'Warning:', msg[1]
|
||||
if pos == 0 and verbose:
|
||||
nframe = nframe+1
|
||||
if int(time.time()) <> lasttime:
|
||||
print nframe / (time.time()-lasttime), 'fps'
|
||||
nframe = 0
|
||||
lasttime = int(time.time())
|
||||
|
||||
lvi.close()
|
||||
lvo.close()
|
||||
|
||||
|
||||
main()
|
|
@ -1,139 +0,0 @@
|
|||
# Live video input class.
|
||||
# Note that importing this module attempts to initialize video.
|
||||
|
||||
|
||||
# Check if video is available.
|
||||
# There are three reasons for failure here:
|
||||
# (1) this version of Python may not have the sv or imageop modules;
|
||||
# (2) this machine may not have a video board;
|
||||
# (3) initializing the video board may fail for another reason.
|
||||
# The global variable have_video is set to true iff we reall do have video.
|
||||
|
||||
try:
|
||||
import sv
|
||||
import SV
|
||||
import imageop
|
||||
try:
|
||||
v = sv.OpenVideo()
|
||||
have_video = 1
|
||||
except sv.error:
|
||||
have_video = 0
|
||||
except ImportError:
|
||||
have_video = 0
|
||||
|
||||
|
||||
# The live video input class.
|
||||
# Only instantiate this if have_video is true!
|
||||
|
||||
class LiveVideoIn:
|
||||
|
||||
# Initialize an instance. Arguments:
|
||||
# vw, vh: size of the video window data to be captured.
|
||||
# For some reason, vw MUST be a multiple of 4.
|
||||
# Note that the data has to be cropped unless vw and vh are
|
||||
# just right for the video board (vw:vh == 4:3 and vh even).
|
||||
|
||||
def __init__(self, pktmax, vw, vh, type):
|
||||
if not have_video:
|
||||
raise RuntimeError, 'no video available'
|
||||
if vw % 4 != 0:
|
||||
raise ValueError, 'vw must be a multiple of 4'
|
||||
self.pktmax = pktmax
|
||||
realvw = vh*SV.PAL_XMAX/SV.PAL_YMAX
|
||||
if realvw < vw:
|
||||
realvw = vw
|
||||
self.realwidth, self.realheight = v.QuerySize(realvw, vh)
|
||||
if not type in ('rgb8', 'grey', 'mono', 'grey2', 'grey4'):
|
||||
raise 'Incorrent video data type', type
|
||||
self.type = type
|
||||
if type in ('grey', 'grey4', 'grey2', 'mono'):
|
||||
v.SetParam([SV.COLOR, SV.MONO, SV.INPUT_BYPASS, 1])
|
||||
else:
|
||||
v.SetParam([SV.COLOR, SV.DEFAULT_COLOR, \
|
||||
SV.INPUT_BYPASS, 0])
|
||||
# Initialize capture
|
||||
(mode, self.realwidth, self.realheight, qsize, rate) = \
|
||||
v.InitContinuousCapture(SV.RGB8_FRAMES, \
|
||||
self.realwidth, self.realheight, 1, 2)
|
||||
self.width = vw
|
||||
self.height = vh
|
||||
self.x0 = (self.realwidth-self.width)/2
|
||||
self.x1 = self.x0 + self.width - 1
|
||||
self.y0 = (self.realheight-self.height)/2
|
||||
self.y1 = self.y0 + self.height - 1
|
||||
# Compute # full lines per packet
|
||||
self.lpp = pktmax / self.linewidth()
|
||||
self.pktsize = self.lpp*self.linewidth()
|
||||
self.data = None
|
||||
self.dataoffset = 0
|
||||
self.lpos = 0
|
||||
self.justright = (self.realwidth == self.width and \
|
||||
self.realheight == self.height)
|
||||
## if not self.justright:
|
||||
## print 'Want:', self.width, 'x', self.height,
|
||||
## print '; grab:', self.realwidth, 'x', self.realheight
|
||||
|
||||
# Change the size of the video being displayed.
|
||||
|
||||
def resizevideo(self, vw, vh):
|
||||
self.close()
|
||||
self.__init__(self.pktmax, vw, vh, self.type)
|
||||
|
||||
# Remove an instance.
|
||||
# This turns off continuous capture.
|
||||
|
||||
def close(self):
|
||||
v.EndContinuousCapture()
|
||||
|
||||
# Get the length in bytes of a video line
|
||||
def linewidth(self):
|
||||
if self.type == 'mono':
|
||||
return (self.width+7)/8
|
||||
elif self.type == 'grey2':
|
||||
return (self.width+3)/4
|
||||
elif self.type == 'grey4':
|
||||
return (self.width+1)/2
|
||||
else:
|
||||
return self.width
|
||||
|
||||
# Get the next video packet.
|
||||
# This returns (lpos, data) where:
|
||||
# - lpos is the line position
|
||||
# - data is a piece of data
|
||||
# The dimensions of data are:
|
||||
# - pixel depth = 1 byte
|
||||
# - scan line width = self.width (the vw argument to __init__())
|
||||
# - number of scan lines = self.lpp (PKTMAX / vw)
|
||||
|
||||
def getnextpacket(self):
|
||||
if not self.data or self.dataoffset >= len(self.data):
|
||||
try:
|
||||
cd, id = v.GetCaptureData()
|
||||
except sv.error:
|
||||
return None
|
||||
data = cd.InterleaveFields(1)
|
||||
cd.UnlockCaptureData()
|
||||
if self.justright:
|
||||
self.data = data
|
||||
else:
|
||||
self.data = imageop.crop(data, 1, \
|
||||
self.realwidth, \
|
||||
self.realheight, \
|
||||
self.x0, self.y0, \
|
||||
self.x1, self.y1)
|
||||
self.lpos = 0
|
||||
self.dataoffset = 0
|
||||
if self.type == 'mono':
|
||||
self.data = imageop.dither2mono(self.data, \
|
||||
self.width, self.height)
|
||||
elif self.type == 'grey2':
|
||||
self.data = imageop.dither2grey2(self.data, \
|
||||
self.width, self.height)
|
||||
elif self.type == 'grey4':
|
||||
self.data = imageop.grey2grey4(self.data, \
|
||||
self.width, self.height)
|
||||
data = self.data[self.dataoffset:self.dataoffset+self.pktsize]
|
||||
lpos = self.lpos
|
||||
self.dataoffset = self.dataoffset + self.pktsize
|
||||
self.lpos = self.lpos + self.lpp
|
||||
return lpos, data
|
|
@ -1,130 +0,0 @@
|
|||
# Live video output (display video on the screen, presumably from the net)
|
||||
|
||||
import gl
|
||||
from VFile import Displayer
|
||||
|
||||
|
||||
# Video output (displayer) class.
|
||||
|
||||
class LiveVideoOut:
|
||||
|
||||
# Call this to initialize things. Arguments:
|
||||
# wid: the window id where the video is to be displayed (centered)
|
||||
# vw, vh: size of the video image to be displayed
|
||||
|
||||
def __init__(self, wid, vw, vh, type):
|
||||
##print 'Init', wid, xywh
|
||||
##print 'video', vw, vw
|
||||
self.vw = vw
|
||||
self.vh = vh
|
||||
self.disp = Displayer()
|
||||
if not type in ('rgb', 'rgb8', 'grey', 'mono', 'grey2', \
|
||||
'grey4'):
|
||||
raise 'Incorrent live video output type', type
|
||||
if type == 'rgb':
|
||||
info = (type, vw, vh, 0, 32, 0, 0, 0, 0)
|
||||
else:
|
||||
info = (type, vw, vh, 1, 8, 0, 0, 0, 0)
|
||||
self.disp.setinfo(info)
|
||||
self.wid = wid
|
||||
oldwid = gl.winget()
|
||||
gl.winset(wid)
|
||||
self.disp.initcolormap()
|
||||
self.reshapewindow()
|
||||
gl.winset(oldwid)
|
||||
|
||||
# Call this in response to every REDRAW event for the window
|
||||
# or if the window size has changed for other reasons.
|
||||
|
||||
def reshapewindow(self):
|
||||
oldwid = gl.winget()
|
||||
gl.winset(self.wid)
|
||||
gl.reshapeviewport()
|
||||
w, h = gl.getsize()
|
||||
self.disp.xorigin = (w-self.vw)/2
|
||||
self.disp.yorigin = (h-self.vh)/2
|
||||
self.disp.clear()
|
||||
gl.winset(oldwid)
|
||||
|
||||
# Call this to change the size of the video images being displayed.
|
||||
# Implies reshapewindow().
|
||||
|
||||
def resizevideo(self, vw, vh):
|
||||
self.vw, self.vh = vw, vh
|
||||
self.disp.setsize(vw, vh)
|
||||
self.reshapewindow()
|
||||
|
||||
# Return the number of bytes in one video line
|
||||
def linewidth(self):
|
||||
if self.disp.format == 'rgb':
|
||||
return self.vw*4
|
||||
if self.disp.format == 'mono':
|
||||
return (self.vw+7)/8
|
||||
elif self.disp.format == 'grey2':
|
||||
return (self.vw+3)/4
|
||||
elif self.disp.format == 'grey4':
|
||||
return (self.vw+1)/2
|
||||
else:
|
||||
return self.vw
|
||||
|
||||
# Call this to display the next video packet. Arguments:
|
||||
# pos: line number where the packet begins
|
||||
# data: image data of the packet
|
||||
# (these correspond directly to the return values from
|
||||
# LiveVideoIn.getnextpacket()).
|
||||
|
||||
def putnextpacket(self, pos, data):
|
||||
nline = len(data)/self.linewidth()
|
||||
if nline*self.linewidth() <> len(data):
|
||||
print 'Incorrect-sized video fragment ignored'
|
||||
return
|
||||
oldwid = gl.winget()
|
||||
gl.winset(self.wid)
|
||||
self.disp.showpartframe(data, None, (0, pos, self.vw, nline))
|
||||
gl.winset(oldwid)
|
||||
|
||||
# Call this to close the window.
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
# Call this to set optional mirroring of video
|
||||
def setmirror(self, mirrored):
|
||||
f, w, h, pf, c0, c1, c2, o, cp = self.disp.getinfo()
|
||||
if type(pf) == type(()):
|
||||
xpf, ypf = pf
|
||||
else:
|
||||
xpf = ypf = pf
|
||||
xpf = abs(xpf)
|
||||
if mirrored:
|
||||
xpf = -xpf
|
||||
info = (f, w, h, (xpf, ypf), c0, c1, c2, o, cp)
|
||||
self.disp.setinfo(info)
|
||||
self.disp.initcolormap()
|
||||
self.disp.clear()
|
||||
|
||||
#
|
||||
# This derived class has one difference with the base class: the video is
|
||||
# not displayed until an entire image has been gotten
|
||||
#
|
||||
class LiveVideoOutSlow(LiveVideoOut):
|
||||
|
||||
# Reshapewindow - Realloc buffer.
|
||||
# (is also called by __init__() indirectly)
|
||||
|
||||
def reshapewindow(self):
|
||||
LiveVideoOut.reshapewindow(self)
|
||||
self.buffer = '\0'*self.linewidth()*self.vh
|
||||
self.isbuffered = []
|
||||
|
||||
# putnextpacket - buffer incoming data until a complete
|
||||
# image has been received
|
||||
|
||||
def putnextpacket(self, pos, data):
|
||||
if pos in self.isbuffered or pos == 0:
|
||||
LiveVideoOut.putnextpacket(self, 0, self.buffer)
|
||||
self.isbuffered = []
|
||||
self.isbuffered.append(pos)
|
||||
bpos = pos * self.linewidth()
|
||||
epos = bpos + len(data)
|
||||
self.buffer = self.buffer[:bpos] + data + self.buffer[epos:]
|
|
@ -1,148 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Copy a video file, interactively, frame-by-frame.
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
from gl import *
|
||||
from DEVICE import *
|
||||
import VFile
|
||||
import VGrabber
|
||||
import string
|
||||
import imageop
|
||||
|
||||
def report(time, iframe):
|
||||
print 'Frame', iframe, ': t =', time
|
||||
|
||||
def usage():
|
||||
sys.stderr.write('usage: Vcopy [-t type] [-m threshold] [-a] infile outfile\n')
|
||||
sys.stderr.write('-t Convert to other type\n')
|
||||
sys.stderr.write('-a Automatic\n')
|
||||
sys.stderr.write('-m Convert grey to mono with threshold\n')
|
||||
sys.stderr.write('-d Convert grey to mono with dithering\n')
|
||||
sys.exit(2)
|
||||
|
||||
def help():
|
||||
print 'Command summary:'
|
||||
print 'n get next image from input'
|
||||
print 'w write current image to output'
|
||||
|
||||
class GrabbingVoutFile(VFile.VoutFile, VGrabber.VGrabber):
|
||||
pass
|
||||
|
||||
def main():
|
||||
foreground()
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 't:am:d')
|
||||
except getopt.error, msg:
|
||||
print msg
|
||||
usage()
|
||||
if len(args) <> 2:
|
||||
usage()
|
||||
[ifile, ofile] = args
|
||||
print 'open film ', ifile
|
||||
ifilm = VFile.VinFile(ifile)
|
||||
print 'open output ', ofile
|
||||
ofilm = GrabbingVoutFile(ofile)
|
||||
|
||||
ofilm.setinfo(ifilm.getinfo())
|
||||
|
||||
use_grabber = 0
|
||||
continuous = 0
|
||||
tomono = 0
|
||||
tomonodither = 0
|
||||
for o, a in opts:
|
||||
if o == '-t':
|
||||
ofilm.format = a
|
||||
use_grabber = 1
|
||||
if o == '-a':
|
||||
continuous = 1
|
||||
if o == '-m':
|
||||
if ifilm.format <> 'grey':
|
||||
print '-m only supported for greyscale'
|
||||
sys.exit(1)
|
||||
tomono = 1
|
||||
treshold = string.atoi(a)
|
||||
ofilm.format = 'mono'
|
||||
if o == '-d':
|
||||
if ifilm.format <> 'grey':
|
||||
print '-m only supported for greyscale'
|
||||
sys.exit(1)
|
||||
tomonodither = 1
|
||||
ofilm.format = 'mono'
|
||||
|
||||
ofilm.writeheader()
|
||||
#
|
||||
prefsize(ifilm.width, ifilm.height)
|
||||
w = winopen(ifile)
|
||||
qdevice(KEYBD)
|
||||
qdevice(ESCKEY)
|
||||
qdevice(WINQUIT)
|
||||
qdevice(WINSHUT)
|
||||
print 'qdevice calls done'
|
||||
#
|
||||
help()
|
||||
#
|
||||
time, data, cdata = ifilm.getnextframe()
|
||||
ifilm.showframe(data, cdata)
|
||||
iframe = 1
|
||||
report(time, iframe)
|
||||
#
|
||||
while 1:
|
||||
if continuous:
|
||||
dev = KEYBD
|
||||
else:
|
||||
dev, val = qread()
|
||||
if dev in (ESCKEY, WINQUIT, WINSHUT):
|
||||
break
|
||||
if dev == REDRAW:
|
||||
reshapeviewport()
|
||||
elif dev == KEYBD:
|
||||
if continuous:
|
||||
c = '0'
|
||||
else:
|
||||
c = chr(val)
|
||||
#XXX Debug
|
||||
if c == 'R':
|
||||
c3i(255,0,0)
|
||||
clear()
|
||||
if c == 'G':
|
||||
c3i(0,255,0)
|
||||
clear()
|
||||
if c == 'B':
|
||||
c3i(0,0,255)
|
||||
clear()
|
||||
if c == 'w' or continuous:
|
||||
if use_grabber:
|
||||
try:
|
||||
data, cdata = ofilm.grabframe()
|
||||
except VFile.Error, msg:
|
||||
print msg
|
||||
break
|
||||
if tomono:
|
||||
data = imageop.grey2mono(data, \
|
||||
ifilm.width, ifilm.height, \
|
||||
treshold)
|
||||
if tomonodither:
|
||||
data = imageop.dither2mono(data, \
|
||||
ifilm.width, ifilm.height)
|
||||
ofilm.writeframe(time, data, cdata)
|
||||
print 'Frame', iframe, 'written.'
|
||||
if c == 'n' or continuous:
|
||||
try:
|
||||
time,data,cdata = ifilm.getnextframe()
|
||||
ifilm.showframe(data, cdata)
|
||||
iframe = iframe+1
|
||||
report(time, iframe)
|
||||
except EOFError:
|
||||
print 'EOF'
|
||||
if continuous:
|
||||
break
|
||||
ringbell()
|
||||
elif dev == INPUTCHANGE:
|
||||
pass
|
||||
else:
|
||||
print '(dev, val) =', (dev, val)
|
||||
ofilm.close()
|
||||
|
||||
main()
|
|
@ -1,113 +0,0 @@
|
|||
CMIF video tools
|
||||
================
|
||||
|
||||
This directory contains Python and C programs to manipulate files
|
||||
containing digitized video in the "CMIF video format".
|
||||
|
||||
An introduction to using the basic tools is in the file "video.doc".
|
||||
|
||||
A description of the video file format is in the file "cmif-film.ms"
|
||||
(troff/nroff -ms input).
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
We started this in October 1991, when we had a large framegrabber
|
||||
board on loan from SGI for a few weeks: we developed a movie recording
|
||||
program and added numerous features, including still frame capture and
|
||||
synchronous sound recording using a second machine (the machine
|
||||
holding the framegrabber board didn't have audio).
|
||||
|
||||
During the following months, when we started using and processing the
|
||||
recorded film fragments, the "CMIF video format" was revised several
|
||||
times, and we eventually created an object-oriented interface for
|
||||
reading and writing various incarnations of these files, called VFile.
|
||||
(This module is also used by our flagship application, the CMIF
|
||||
editor, not in this directory but in /ufs/guido/mm/.)
|
||||
|
||||
When we got our own Indigo entry-level video board (in June 1992) and
|
||||
a version of the Irix video library that supported capturing PAL
|
||||
format (in August 1992), Sjoerd added an interface to the video
|
||||
library to Python (sv) and Guido wrote Vrec.py (based upon a still
|
||||
frame grabber by Sjoerd, in turn based upon SGI demo code in C) to
|
||||
record a movie using it. Vrec was soon followed by modernized
|
||||
versions of the other programs (Vinfo, Vplay, Vtime) and an
|
||||
interactive editor (Vedit). Finally, VFile was rewritten for more
|
||||
modularity, functionality and robustness, and various other tools were
|
||||
added as needed. Also, new options were added to existing tools, and
|
||||
several new video file formats were added.
|
||||
|
||||
Guido van Rossum
|
||||
Jack Jansen
|
||||
Sjoerd Mullender
|
||||
|
||||
|
||||
Overview of files
|
||||
-----------------
|
||||
|
||||
cmif-film.ms description of the CMIF video file format (more than a
|
||||
little out of date -- read the source for VFile for
|
||||
more info about new file formats)
|
||||
|
||||
|
||||
These are programs with a command line interface:
|
||||
|
||||
Vrec.py record video movies using the Indigo video library and
|
||||
board
|
||||
|
||||
Vplay.py play video movies
|
||||
|
||||
Vinfo.py show statistics on movies
|
||||
|
||||
Vtime.py Copy a video file, manipulating the time codes (e.g.
|
||||
faster/slower, or regenerate time codes, or drop
|
||||
frames too close apart)
|
||||
|
||||
Vcopy.py Universal video file copying tool. Can manipulate the
|
||||
time codes, change the type, size, and packfactor.
|
||||
Subsumes Vtime.py.
|
||||
|
||||
Vmkjpeg.py compress an rgb or grey video file to jpeg[grey] format
|
||||
|
||||
Vunjpeg.py expand a jpeg[grey] video file to rgb or grey format
|
||||
|
||||
Vfix.py truncate the scan line width of a video file to
|
||||
a multiple of 4 ('grey' images only)
|
||||
|
||||
Vedit.py interactive video editing program (uses the FORMS library)
|
||||
|
||||
Vsend.py unicast or multicast live video as UDP packets
|
||||
|
||||
Vreceive.py receive transmissions from Vsend
|
||||
|
||||
Vaddcache.py add a "cached index" to a video file, for faster playing
|
||||
|
||||
Vrecb.py like Vrec.py but uses "burst capture" -- somewhat specialized
|
||||
|
||||
Dsend.py like Vsend.py but sends screen snapshots (to Vreceive.py)
|
||||
|
||||
DisplayVideoIn.py Like LiveVideoIn.py but reads screen snapshots
|
||||
|
||||
rgb2video.py combine a sequence of rgb image files into a CMIF video file
|
||||
|
||||
video2rgb.py split a CMIF video file into a sequence of rgb image files
|
||||
|
||||
|
||||
These modules and files are used by the above programs:
|
||||
|
||||
VFile.py classes that read and write CMIF video files
|
||||
|
||||
Viewer.py two viewer classes used by Vedit
|
||||
|
||||
LiveVideoIn.py live video input class, used by Vsend
|
||||
|
||||
LiveVideoOut.py live video output class, used by Vsend and Vreceive
|
||||
|
||||
imgconv.py Image conversion subroutines for rgb2video.py
|
||||
|
||||
senddefs.py Defaults shared by Vsend and Vreceice
|
||||
|
||||
watchcursor.py Generally useful module to define a watch cursor in GL
|
||||
|
||||
VeditForm.fd FORMS' fdesign definition for Vedit's form
|
|
@ -1,534 +0,0 @@
|
|||
import fcntl
|
||||
import IOCTL
|
||||
from IOCTL import *
|
||||
import sys
|
||||
import struct
|
||||
import select
|
||||
import posix
|
||||
import time
|
||||
|
||||
DEVICE='/dev/ttyd2'
|
||||
|
||||
class UnixFile:
|
||||
def open(self, name, mode):
|
||||
self.fd = posix.open(name, mode)
|
||||
return self
|
||||
|
||||
def read(self, len):
|
||||
return posix.read(self.fd, len)
|
||||
|
||||
def write(self, data):
|
||||
dummy = posix.write(self.fd, data)
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def fileno(self):
|
||||
return self.fd
|
||||
|
||||
def close(self):
|
||||
dummy = posix.close(self.fd)
|
||||
|
||||
def packttyargs(*args):
|
||||
if type(args) <> type(()):
|
||||
raise 'Incorrect argtype for packttyargs'
|
||||
if type(args[0]) == type(1):
|
||||
iflag, oflag, cflag, lflag, line, chars = args
|
||||
elif type(args[0]) == type(()):
|
||||
if len(args) <> 1:
|
||||
raise 'Only 1 argument expected'
|
||||
iflag, oflag, cflag, lflag, line, chars = args[0]
|
||||
elif type(args[0]) == type([]):
|
||||
if len(args) <> 1:
|
||||
raise 'Only 1 argument expected'
|
||||
[iflag, oflag, cflag, lflag, line, chars] = args[0]
|
||||
str = struct.pack('hhhhb', iflag, oflag, cflag, lflag, line)
|
||||
for c in chars:
|
||||
str = str + c
|
||||
return str
|
||||
|
||||
def nullttyargs():
|
||||
chars = ['\0']*IOCTL.NCCS
|
||||
return packttyargs(0, 0, 0, 0, 0, chars)
|
||||
|
||||
def unpackttyargs(str):
|
||||
args = str[:-IOCTL.NCCS]
|
||||
rawchars = str[-IOCTL.NCCS:]
|
||||
chars = []
|
||||
for c in rawchars:
|
||||
chars.append(c)
|
||||
iflag, oflag, cflag, lflag, line = struct.unpack('hhhhb', args)
|
||||
return (iflag, oflag, cflag, lflag, line, chars)
|
||||
|
||||
def initline(name):
|
||||
fp = UnixFile().open(name, 2)
|
||||
ofp = fp
|
||||
fd = fp.fileno()
|
||||
rv = fcntl.ioctl(fd, IOCTL.TCGETA, nullttyargs())
|
||||
iflag, oflag, cflag, lflag, line, chars = unpackttyargs(rv)
|
||||
iflag = iflag & ~(INPCK|ISTRIP|INLCR|IUCLC|IXON|IXOFF)
|
||||
oflag = oflag & ~OPOST
|
||||
cflag = B9600|CS8|CREAD|CLOCAL
|
||||
lflag = lflag & ~(ISIG|ICANON|ECHO|TOSTOP)
|
||||
chars[VMIN] = chr(1)
|
||||
chars[VTIME] = chr(0)
|
||||
arg = packttyargs(iflag, oflag, cflag, lflag, line, chars)
|
||||
dummy = fcntl.ioctl(fd, IOCTL.TCSETA, arg)
|
||||
return fp, ofp
|
||||
|
||||
#
|
||||
#
|
||||
error = 'VCR.error'
|
||||
|
||||
# Commands/replies:
|
||||
COMPLETION = '\x01'
|
||||
ACK ='\x0a'
|
||||
NAK ='\x0b'
|
||||
|
||||
NUMBER_N = 0x30
|
||||
ENTER = '\x40'
|
||||
|
||||
EXP_7= '\xde'
|
||||
EXP_8= '\xdf'
|
||||
|
||||
CL ='\x56'
|
||||
CTRL_ENABLE = EXP_8 + '\xc6'
|
||||
SEARCH_DATA = EXP_8 + '\x93'
|
||||
ADDR_SENSE = '\x60'
|
||||
|
||||
PLAY ='\x3a'
|
||||
STOP ='\x3f'
|
||||
EJECT='\x2a'
|
||||
FF ='\xab'
|
||||
REW ='\xac'
|
||||
STILL='\x4f'
|
||||
STEP_FWD ='\x2b' # Was: '\xad'
|
||||
FM_SELECT=EXP_8 + '\xc8'
|
||||
FM_STILL=EXP_8 + '\xcd'
|
||||
PREVIEW=EXP_7 + '\x9d'
|
||||
REVIEW=EXP_7 + '\x9e'
|
||||
DM_OFF=EXP_8 + '\xc9'
|
||||
DM_SET=EXP_8 + '\xc4'
|
||||
FWD_SHUTTLE='\xb5'
|
||||
REV_SHUTTLE='\xb6'
|
||||
EM_SELECT=EXP_8 + '\xc0'
|
||||
N_FRAME_REC=EXP_8 + '\x92'
|
||||
SEARCH_PREROLL=EXP_8 + '\x90'
|
||||
EDIT_PB_STANDBY=EXP_8 + '\x96'
|
||||
EDIT_PLAY=EXP_8 + '\x98'
|
||||
AUTO_EDIT=EXP_7 + '\x9c'
|
||||
|
||||
IN_ENTRY=EXP_7 + '\x90'
|
||||
IN_ENTRY_RESET=EXP_7 + '\x91'
|
||||
IN_ENTRY_SET=EXP_7 + '\x98'
|
||||
IN_ENTRY_INC=EXP_7 + '\x94'
|
||||
IN_ENTRY_DEC=EXP_7 + '\x95'
|
||||
IN_ENTRY_SENSE=EXP_7 + '\x9a'
|
||||
|
||||
OUT_ENTRY=EXP_7 + '\x92'
|
||||
OUT_ENTRY_RESET=EXP_7 + '\x93'
|
||||
OUT_ENTRY_SET=EXP_7 + '\x99'
|
||||
OUT_ENTRY_INC=EXP_7 + '\x96'
|
||||
OUT_ENTRY_DEC=EXP_7 + '\x98'
|
||||
OUT_ENTRY_SENSE=EXP_7 + '\x9b'
|
||||
|
||||
MUTE_AUDIO = '\x24'
|
||||
MUTE_AUDIO_OFF = '\x25'
|
||||
MUTE_VIDEO = '\x26'
|
||||
MUTE_VIDEO_OFF = '\x27'
|
||||
MUTE_AV = EXP_7 + '\xc6'
|
||||
MUTE_AV_OFF = EXP_7 + '\xc7'
|
||||
|
||||
DEBUG=0
|
||||
|
||||
class VCR:
|
||||
def __init__(self):
|
||||
self.ifp, self.ofp = initline(DEVICE)
|
||||
self.busy_cmd = None
|
||||
self.async = 0
|
||||
self.cb = None
|
||||
self.cb_arg = None
|
||||
|
||||
def _check(self):
|
||||
if self.busy_cmd:
|
||||
raise error, 'Another command active: '+self.busy_cmd
|
||||
|
||||
def _endlongcmd(self, name):
|
||||
if not self.async:
|
||||
self.waitready()
|
||||
return 1
|
||||
self.busy_cmd = name
|
||||
return 'VCR BUSY'
|
||||
|
||||
def fileno(self):
|
||||
return self.ifp.fileno()
|
||||
|
||||
def setasync(self, async):
|
||||
self.async = async
|
||||
|
||||
def setcallback(self, cb, arg):
|
||||
self.setasync(1)
|
||||
self.cb = cb
|
||||
self.cb_arg = arg
|
||||
|
||||
def poll(self):
|
||||
if not self.async:
|
||||
raise error, 'Can only call poll() in async mode'
|
||||
if not self.busy_cmd:
|
||||
return
|
||||
if self.testready():
|
||||
if self.cb:
|
||||
apply(self.cb, (self.cb_arg,))
|
||||
|
||||
def _cmd(self, cmd):
|
||||
if DEBUG:
|
||||
print '>>>',`cmd`
|
||||
self.ofp.write(cmd)
|
||||
self.ofp.flush()
|
||||
|
||||
def _waitdata(self, len, tout):
|
||||
rep = ''
|
||||
while len > 0:
|
||||
if tout == None:
|
||||
ready, d1, d2 = select.select( \
|
||||
[self.ifp], [], [])
|
||||
else:
|
||||
ready, d1, d2 = select.select( \
|
||||
[self.ifp], [], [], tout)
|
||||
if ready == []:
|
||||
## if rep:
|
||||
## print 'FLUSHED:', `rep`
|
||||
return None
|
||||
data = self.ifp.read(1)
|
||||
if DEBUG:
|
||||
print '<<<',`data`
|
||||
if data == NAK:
|
||||
return NAK
|
||||
rep = rep + data
|
||||
len = len - 1
|
||||
return rep
|
||||
|
||||
def _reply(self, len):
|
||||
data = self._waitdata(len, 10)
|
||||
if data == None:
|
||||
raise error, 'Lost contact with VCR'
|
||||
return data
|
||||
|
||||
def _getnumber(self, len):
|
||||
data = self._reply(len)
|
||||
number = 0
|
||||
for c in data:
|
||||
digit = ord(c) - NUMBER_N
|
||||
if digit < 0 or digit > 9:
|
||||
raise error, 'Non-digit in number'+`c`
|
||||
number = number*10 + digit
|
||||
return number
|
||||
|
||||
def _iflush(self):
|
||||
dummy = self._waitdata(10000, 0)
|
||||
## if dummy:
|
||||
## print 'IFLUSH:', dummy
|
||||
|
||||
def simplecmd(self,cmd):
|
||||
self._iflush()
|
||||
for ch in cmd:
|
||||
self._cmd(ch)
|
||||
rep = self._reply(1)
|
||||
if rep == NAK:
|
||||
return 0
|
||||
elif rep <> ACK:
|
||||
raise error, 'Unexpected reply:' + `rep`
|
||||
return 1
|
||||
|
||||
def replycmd(self, cmd):
|
||||
if not self.simplecmd(cmd[:-1]):
|
||||
return 0
|
||||
self._cmd(cmd[-1])
|
||||
|
||||
def _number(self, number, digits):
|
||||
if number < 0:
|
||||
raise error, 'Unexpected negative number:'+ `number`
|
||||
maxnum = pow(10, digits)
|
||||
if number > maxnum:
|
||||
raise error, 'Number too big'
|
||||
while maxnum > 1:
|
||||
number = number % maxnum
|
||||
maxnum = maxnum / 10
|
||||
digit = number / maxnum
|
||||
ok = self.simplecmd(chr(NUMBER_N + digit))
|
||||
if not ok:
|
||||
raise error, 'Error while transmitting number'
|
||||
|
||||
def initvcr(self, *optarg):
|
||||
timeout = None
|
||||
if optarg <> ():
|
||||
timeout = optarg[0]
|
||||
starttime = time.time()
|
||||
self.busy_cmd = None
|
||||
self._iflush()
|
||||
while 1:
|
||||
## print 'SENDCL'
|
||||
self._cmd(CL)
|
||||
rep = self._waitdata(1, 2)
|
||||
## print `rep`
|
||||
if rep in ( None, CL, NAK ):
|
||||
if timeout:
|
||||
if time.time() - starttime > timeout:
|
||||
raise error, \
|
||||
'No reply from VCR'
|
||||
continue
|
||||
break
|
||||
if rep <> ACK:
|
||||
raise error, 'Unexpected reply:' + `rep`
|
||||
dummy = self.simplecmd(CTRL_ENABLE)
|
||||
|
||||
def waitready(self):
|
||||
rep = self._waitdata(1, None)
|
||||
if rep == None:
|
||||
raise error, 'Unexpected None reply from waitdata'
|
||||
if rep not in (COMPLETION, ACK):
|
||||
self._iflush()
|
||||
raise error, 'Unexpected waitready reply:' + `rep`
|
||||
self.busy_cmd = None
|
||||
|
||||
def testready(self):
|
||||
rep = self._waitdata(1, 0)
|
||||
if rep == None:
|
||||
return 0
|
||||
if rep not in (COMPLETION, ACK):
|
||||
self._iflush()
|
||||
raise error, 'Unexpected waitready reply:' + `rep`
|
||||
self.busy_cmd = None
|
||||
return 1
|
||||
|
||||
def play(self): return self.simplecmd(PLAY)
|
||||
def stop(self): return self.simplecmd(STOP)
|
||||
def ff(self): return self.simplecmd(FF)
|
||||
def rew(self): return self.simplecmd(REW)
|
||||
def eject(self):return self.simplecmd(EJECT)
|
||||
def still(self):return self.simplecmd(STILL)
|
||||
def step(self): return self.simplecmd(STEP_FWD)
|
||||
|
||||
def goto(self, (h, m, s, f)):
|
||||
if not self.simplecmd(SEARCH_DATA):
|
||||
return 0
|
||||
self._number(h, 2)
|
||||
self._number(m, 2)
|
||||
self._number(s, 2)
|
||||
self._number(f, 2)
|
||||
if not self.simplecmd(ENTER):
|
||||
return 0
|
||||
return self._endlongcmd('goto')
|
||||
|
||||
# XXXX TC_SENSE doesn't seem to work
|
||||
def faulty_where(self):
|
||||
self._check()
|
||||
self._cmd(TC_SENSE)
|
||||
h = self._getnumber(2)
|
||||
m = self._getnumber(2)
|
||||
s = self._getnumber(2)
|
||||
f = self._getnumber(2)
|
||||
return (h, m, s, f)
|
||||
|
||||
def where(self):
|
||||
return self.addr2tc(self.sense())
|
||||
|
||||
def sense(self):
|
||||
self._check()
|
||||
self._cmd(ADDR_SENSE)
|
||||
num = self._getnumber(5)
|
||||
return num
|
||||
|
||||
def addr2tc(self, num):
|
||||
f = num % 25
|
||||
num = num / 25
|
||||
s = num % 60
|
||||
num = num / 60
|
||||
m = num % 60
|
||||
h = num / 60
|
||||
return (h, m, s, f)
|
||||
|
||||
def tc2addr(self, (h, m, s, f)):
|
||||
return ((h*60 + m)*60 + s)*25 + f
|
||||
|
||||
def fmmode(self, mode):
|
||||
self._check()
|
||||
if mode == 'off':
|
||||
arg = 0
|
||||
elif mode == 'buffer':
|
||||
arg = 1
|
||||
elif mode == 'dnr':
|
||||
arg = 2
|
||||
else:
|
||||
raise error, 'fmmode arg should be off, buffer or dnr'
|
||||
if not self.simplecmd(FM_SELECT):
|
||||
return 0
|
||||
self._number(arg, 1)
|
||||
if not self.simplecmd(ENTER):
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def mute(self, mode, value):
|
||||
self._check()
|
||||
if mode == 'audio':
|
||||
cmds = (MUTE_AUDIO_OFF, MUTE_AUDIO)
|
||||
elif mode == 'video':
|
||||
cmds = (MUTE_VIDEO_OFF, MUTE_VIDEO)
|
||||
elif mode == 'av':
|
||||
cmds = (MUTE_AV_OFF, MUTE_AV)
|
||||
else:
|
||||
raise error, 'mute type should be audio, video or av'
|
||||
cmd = cmds[value]
|
||||
return self.simplecmd(cmd)
|
||||
|
||||
def editmode(self, mode):
|
||||
self._check()
|
||||
if mode == 'off':
|
||||
a0 = a1 = a2 = 0
|
||||
elif mode == 'format':
|
||||
a0 = 4
|
||||
a1 = 7
|
||||
a2 = 4
|
||||
elif mode == 'asmbl':
|
||||
a0 = 1
|
||||
a1 = 7
|
||||
a2 = 4
|
||||
elif mode == 'insert-video':
|
||||
a0 = 2
|
||||
a1 = 4
|
||||
a2 = 0
|
||||
else:
|
||||
raise 'editmode should be off,format,asmbl or insert-video'
|
||||
if not self.simplecmd(EM_SELECT):
|
||||
return 0
|
||||
self._number(a0, 1)
|
||||
self._number(a1, 1)
|
||||
self._number(a2, 1)
|
||||
if not self.simplecmd(ENTER):
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def autoedit(self):
|
||||
self._check()
|
||||
return self._endlongcmd(AUTO_EDIT)
|
||||
|
||||
def nframerec(self, num):
|
||||
if not self.simplecmd(N_FRAME_REC):
|
||||
return 0
|
||||
self._number(num, 4)
|
||||
if not self.simplecmd(ENTER):
|
||||
return 0
|
||||
return self._endlongcmd('nframerec')
|
||||
|
||||
def fmstill(self):
|
||||
if not self.simplecmd(FM_STILL):
|
||||
return 0
|
||||
return self._endlongcmd('fmstill')
|
||||
|
||||
def preview(self):
|
||||
if not self.simplecmd(PREVIEW):
|
||||
return 0
|
||||
return self._endlongcmd('preview')
|
||||
|
||||
def review(self):
|
||||
if not self.simplecmd(REVIEW):
|
||||
return 0
|
||||
return self._endlongcmd('review')
|
||||
|
||||
def search_preroll(self):
|
||||
if not self.simplecmd(SEARCH_PREROLL):
|
||||
return 0
|
||||
return self._endlongcmd('search_preroll')
|
||||
|
||||
def edit_pb_standby(self):
|
||||
if not self.simplecmd(EDIT_PB_STANDBY):
|
||||
return 0
|
||||
return self._endlongcmd('edit_pb_standby')
|
||||
|
||||
def edit_play(self):
|
||||
if not self.simplecmd(EDIT_PLAY):
|
||||
return 0
|
||||
return self._endlongcmd('edit_play')
|
||||
|
||||
def dmcontrol(self, mode):
|
||||
self._check()
|
||||
if mode == 'off':
|
||||
return self.simplecmd(DM_OFF)
|
||||
if mode == 'multi freeze':
|
||||
num = 1000
|
||||
elif mode == 'zoom freeze':
|
||||
num = 2000
|
||||
elif mode == 'digital slow':
|
||||
num = 3000
|
||||
elif mode == 'freeze':
|
||||
num = 4011
|
||||
else:
|
||||
raise error, 'unknown dmcontrol argument: ' + `mode`
|
||||
if not self.simplecmd(DM_SET):
|
||||
return 0
|
||||
self._number(num, 4)
|
||||
if not self.simplecmd(ENTER):
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def fwdshuttle(self, num):
|
||||
if not self.simplecmd(FWD_SHUTTLE):
|
||||
return 0
|
||||
self._number(num, 1)
|
||||
return 1
|
||||
|
||||
def revshuttle(self, num):
|
||||
if not self.simplecmd(REV_SHUTTLE):
|
||||
return 0
|
||||
self._number(num, 1)
|
||||
return 1
|
||||
|
||||
def getentry(self, which):
|
||||
self._check()
|
||||
if which == 'in':
|
||||
cmd = IN_ENTRY_SENSE
|
||||
elif which == 'out':
|
||||
cmd = OUT_ENTRY_SENSE
|
||||
self.replycmd(cmd)
|
||||
h = self._getnumber(2)
|
||||
m = self._getnumber(2)
|
||||
s = self._getnumber(2)
|
||||
f = self._getnumber(2)
|
||||
return (h, m, s, f)
|
||||
|
||||
def inentry(self, arg):
|
||||
return self.ioentry(arg, (IN_ENTRY, IN_ENTRY_RESET, \
|
||||
IN_ENTRY_SET, IN_ENTRY_INC, IN_ENTRY_DEC))
|
||||
|
||||
def outentry(self, arg):
|
||||
return self.ioentry(arg, (OUT_ENTRY, OUT_ENTRY_RESET, \
|
||||
OUT_ENTRY_SET, OUT_ENTRY_INC, OUT_ENTRY_DEC))
|
||||
|
||||
def ioentry(self, arg, (Load, Clear, Set, Inc, Dec)):
|
||||
self._check()
|
||||
if type(arg) == type(()):
|
||||
h, m, s, f = arg
|
||||
if not self.simplecmd(Set):
|
||||
return 0
|
||||
self._number(h,2)
|
||||
self._number(m,2)
|
||||
self._number(s,2)
|
||||
self._number(f,2)
|
||||
if not self.simplecmd(ENTER):
|
||||
return 0
|
||||
return 1
|
||||
elif arg == 'reset':
|
||||
cmd = Clear
|
||||
elif arg == 'load':
|
||||
cmd = Load
|
||||
elif arg == '+':
|
||||
cmd = Inc
|
||||
elif arg == '-':
|
||||
cmd = Dec
|
||||
else:
|
||||
raise error, 'Arg should be +,-,reset,load or (h,m,s,f)'
|
||||
return self.simplecmd(cmd)
|
||||
|
||||
def cancel(self):
|
||||
d = self.simplecmd(CL)
|
||||
self.busy_cmd = None
|
File diff suppressed because it is too large
Load Diff
|
@ -1,80 +0,0 @@
|
|||
# Class to grab frames from a window.
|
||||
# (This has fewer user-settable parameters than Displayer.)
|
||||
# It is the caller's responsibility to initialize the window and to
|
||||
# ensure that it is current when using grabframe()
|
||||
|
||||
import gl, GL
|
||||
import VFile
|
||||
import GET
|
||||
from VFile import Error
|
||||
|
||||
class VGrabber(VFile.VideoParams):
|
||||
|
||||
# XXX The constructor of VideoParams is just fine, for now
|
||||
|
||||
# Grab a frame.
|
||||
# Return (data, chromdata) just like getnextframe().
|
||||
|
||||
def grabframe(self):
|
||||
grabber = choose_grabber(self.format)
|
||||
return grabber(self.width, self.height, self.packfactor)
|
||||
|
||||
|
||||
# Choose one of the grabber functions below based upon a color system name
|
||||
|
||||
def choose_grabber(format):
|
||||
try:
|
||||
return eval('grab_' + format)
|
||||
except:
|
||||
raise Error, 'Unknown color system: ' + `format`
|
||||
|
||||
|
||||
# Routines to grab data, per color system (only a few really supported).
|
||||
# (These functions are used via eval with a constructed argument!)
|
||||
|
||||
def grab_rgb(w, h, pf):
|
||||
if gl.getdisplaymode() <> GET.DMRGB:
|
||||
raise Error, 'Sorry, can only grab rgb in single-buf rgbmode'
|
||||
if pf <> (1, 1):
|
||||
raise Error, 'Sorry, only grab rgb with packfactor (1,1)'
|
||||
return gl.lrectread(0, 0, w-1, h-1), None
|
||||
|
||||
def grab_rgb8(w, h, pf):
|
||||
if gl.getdisplaymode() <> GET.DMRGB:
|
||||
raise Error, 'Sorry, can only grab rgb8 in single-buf rgbmode'
|
||||
if pf <> (1, 1):
|
||||
raise Error, 'Sorry, can only grab rgb8 with packfactor (1,1)'
|
||||
if not VFile.is_entry_indigo():
|
||||
raise Error, 'Sorry, can only grab rgb8 on entry level Indigo'
|
||||
# XXX Dirty Dirty here.
|
||||
# XXX Set buffer to cmap mode, grab image and set it back.
|
||||
gl.cmode()
|
||||
gl.gconfig()
|
||||
gl.pixmode(GL.PM_SIZE, 8)
|
||||
data = gl.lrectread(0, 0, w-1, h-1)
|
||||
data = data[:w*h] # BUG FIX for python lrectread
|
||||
gl.RGBmode()
|
||||
gl.gconfig()
|
||||
gl.pixmode(GL.PM_SIZE, 32)
|
||||
return data, None
|
||||
|
||||
def grab_grey(w, h, pf):
|
||||
raise Error, 'Sorry, grabbing grey not implemented'
|
||||
|
||||
def grab_yiq(w, h, pf):
|
||||
raise Error, 'Sorry, grabbing yiq not implemented'
|
||||
|
||||
def grab_hls(w, h, pf):
|
||||
raise Error, 'Sorry, grabbing hls not implemented'
|
||||
|
||||
def grab_hsv(w, h, pf):
|
||||
raise Error, 'Sorry, grabbing hsv not implemented'
|
||||
|
||||
def grab_jpeg(w, h, pf):
|
||||
data, dummy = grab_rgb(w, h, pf)
|
||||
import jpeg
|
||||
data = jpeg.compress(data, w, h, 4)
|
||||
return data, None
|
||||
|
||||
def grab_jpeggrey(w, h, pf):
|
||||
raise Error, 'sorry, grabbing jpeggrey not implemented'
|
|
@ -1,80 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Add a cache to each of the files given as command line arguments
|
||||
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# Vaddcache [file] ...
|
||||
|
||||
|
||||
# Options:
|
||||
#
|
||||
# file ... : file(s) to modify; default film.video
|
||||
|
||||
|
||||
import sys
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import VFile
|
||||
import getopt
|
||||
|
||||
|
||||
# Global options
|
||||
|
||||
# None
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
opts, args = getopt.getopt(sys.argv[1:], '')
|
||||
if not args:
|
||||
args = ['film.video']
|
||||
sts = 0
|
||||
for filename in args:
|
||||
if process(filename):
|
||||
sts = 1
|
||||
sys.exit(sts)
|
||||
|
||||
|
||||
# Process one file
|
||||
|
||||
def process(filename):
|
||||
try:
|
||||
fp = open(filename, 'r+')
|
||||
vin = VFile.RandomVinFile(fp)
|
||||
vin.filename = 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 file\n')
|
||||
return 1
|
||||
|
||||
try:
|
||||
vin.readcache()
|
||||
hascache = 1
|
||||
except VFile.Error:
|
||||
hascache = 0
|
||||
|
||||
if hascache:
|
||||
sys.stderr.write(filename + ': already has a cache\n')
|
||||
vin.close()
|
||||
return 1
|
||||
|
||||
vin.printinfo()
|
||||
vin.warmcache()
|
||||
vin.writecache()
|
||||
vin.close()
|
||||
return 0
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
|
@ -1,962 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Video bag of tricks: record video(+audio) in various formats and modes
|
||||
|
||||
# XXX To do:
|
||||
# - audio
|
||||
# - improve user interface
|
||||
# - help button?
|
||||
# - command line options to set initial settings
|
||||
# - save settings in a file
|
||||
# - ...?
|
||||
|
||||
import sys
|
||||
import time
|
||||
import getopt
|
||||
import string
|
||||
import os
|
||||
sts = os.system('makemap') # Must be before "import fl" to work
|
||||
import sgi
|
||||
import gl
|
||||
import GL
|
||||
import DEVICE
|
||||
import fl
|
||||
import FL
|
||||
import flp
|
||||
import watchcursor
|
||||
import sv
|
||||
import SV
|
||||
import VFile
|
||||
import VGrabber
|
||||
import imageop
|
||||
sys.path.append('/ufs/jack/src/av/vcr')
|
||||
import VCR
|
||||
try:
|
||||
import cl
|
||||
except ImportError:
|
||||
cl = None
|
||||
|
||||
ARROW = 0
|
||||
WATCH = 1
|
||||
watchcursor.defwatch(WATCH)
|
||||
|
||||
def main():
|
||||
## fl.set_graphics_mode(0, 1)
|
||||
vb = VideoBagOfTricks()
|
||||
while 1:
|
||||
dummy = fl.do_forms()
|
||||
[dummy]
|
||||
|
||||
StopCapture = 'StopCapture'
|
||||
|
||||
VideoFormatLabels = ['Video off', 'rgb8', 'grey8', 'grey4', 'grey2', \
|
||||
'grey2 dith', 'mono dith', 'mono thresh', 'rgb24', 'rgb24-jpeg', \
|
||||
'compress']
|
||||
VideoFormats = ['', 'rgb8', 'grey', 'grey4', 'grey2', \
|
||||
'grey2', 'mono', 'mono', 'rgb', 'jpeg', 'compress']
|
||||
|
||||
VideoModeLabels = ['Continuous', 'Burst', 'Single frame', 'VCR sync']
|
||||
[VM_CONT, VM_BURST, VM_SINGLE, VM_VCR] = range(1, 5)
|
||||
|
||||
AudioFormatLabels = ['Audio off', \
|
||||
'16 bit mono', '16 bit stereo', '8 bit mono', '8 bit stereo']
|
||||
[A_OFF, A_16_MONO, A_16_STEREO, A_8_MONO, A_8_STEREO] = range(1, 6)
|
||||
|
||||
VcrSpeedLabels = ['normal', '1/3', '1/5', '1/10', '1/30', 'single-step']
|
||||
VcrSpeeds = [None, 5, 4, 3, 2, 1, 0]
|
||||
|
||||
RgbSizeLabels = ['full', 'quarter', 'sixteenth']
|
||||
|
||||
# init file stuff:
|
||||
if os.environ.has_key('HOME'):
|
||||
HOME=os.environ['HOME']
|
||||
else:
|
||||
HOME='.'
|
||||
VB_INIT_FILE=HOME + '/.Vb_init'
|
||||
|
||||
VB_INIT_KEYS=['vfile', 'vmode', 'mono_thresh', 'vformat', 'comp_scheme', \
|
||||
'rgb24_size', 'afile', 'aformat']
|
||||
|
||||
class VideoBagOfTricks:
|
||||
|
||||
# Init/close stuff
|
||||
|
||||
def __init__(self):
|
||||
self.window = None
|
||||
formdef = flp.parse_form('VbForm', 'form')
|
||||
flp.create_full_form(self, formdef)
|
||||
self.setdefaults()
|
||||
if self.vmode <> VM_CONT:
|
||||
self.g_cont.hide_object()
|
||||
if self.vmode <> VM_BURST:
|
||||
self.g_burst.hide_object()
|
||||
if self.vmode <> VM_SINGLE:
|
||||
self.g_single.hide_object()
|
||||
if self.vmode <> VM_VCR:
|
||||
self.g_vcr.hide_object()
|
||||
if self.vformat <> 'compress':
|
||||
self.g_compress.hide_object()
|
||||
|
||||
self.openvideo()
|
||||
self.makewindow()
|
||||
self.bindvideo()
|
||||
if self.use_24:
|
||||
self.optfullsizewindow()
|
||||
self.showform()
|
||||
fl.set_event_call_back(self.do_event)
|
||||
|
||||
def close(self):
|
||||
self.close_video()
|
||||
self.close_audio()
|
||||
self.savedefaults()
|
||||
raise SystemExit, 0
|
||||
|
||||
def showform(self):
|
||||
# Get position of video window
|
||||
gl.winset(self.window)
|
||||
x, y = gl.getorigin()
|
||||
width, height = gl.getsize()
|
||||
# Calculate position of form window
|
||||
x1 = x + width + 10
|
||||
x2 = x1 + int(self.form.w) - 1
|
||||
y2 = y + height - 1
|
||||
y1 = y2 - int(self.form.h) + 1
|
||||
# Position and show form window
|
||||
gl.prefposition(x1, x2, y1, y2)
|
||||
self.form.show_form(FL.PLACE_FREE, FL.TRUE, 'Vb Control')
|
||||
|
||||
def getdefaultdefaults(self):
|
||||
# Video defaults
|
||||
self.vfile = 'film.video'
|
||||
self.vmode = VM_CONT
|
||||
self.mono_thresh = 128
|
||||
self.vformat = 'rgb8'
|
||||
self.comp_scheme = 'Uncompressed'
|
||||
self.rgb24_size = 1
|
||||
# Missing: drop, rate, maxmem, nframes, rate, vcrspeed
|
||||
# Audio defaults:
|
||||
self.afile = 'film.aiff'
|
||||
self.aformat = A_OFF
|
||||
|
||||
def getdefaults(self):
|
||||
self.getdefaultdefaults()
|
||||
# XXXX Read defaults file and override.
|
||||
try:
|
||||
fp = open(VB_INIT_FILE, 'r')
|
||||
except IOError:
|
||||
print 'Vb: no init file'
|
||||
self.initcont = {}
|
||||
return
|
||||
data = fp.read(1000000)
|
||||
try:
|
||||
self.initcont = eval(data)
|
||||
except:
|
||||
print 'Vb: Ill-formatted init file'
|
||||
self.initcont = {}
|
||||
for k in self.initcont.keys():
|
||||
if hasattr(self, k):
|
||||
setattr(self, k, self.initcont[k])
|
||||
|
||||
def savedefaults(self):
|
||||
newdb = {}
|
||||
for k in VB_INIT_KEYS:
|
||||
newdb[k] = getattr(self, k)
|
||||
if newdb <> self.initcont:
|
||||
try:
|
||||
fp = open(VB_INIT_FILE, 'w')
|
||||
except IOError:
|
||||
print 'Vb: Cannot create', VB_INIT_FILE
|
||||
return
|
||||
fp.write(`newdb`)
|
||||
fp.close()
|
||||
|
||||
def setdefaults(self):
|
||||
self.getdefaults()
|
||||
self.vcr = None
|
||||
self.vout = None
|
||||
self.capturing = 0
|
||||
self.c_vformat.clear_choice()
|
||||
for label in VideoFormatLabels:
|
||||
self.c_vformat.addto_choice(label)
|
||||
self.c_vformat.set_choice(1 + VideoFormats.index(self.vformat))
|
||||
self.c_vmode.clear_choice()
|
||||
for label in VideoModeLabels:
|
||||
self.c_vmode.addto_choice(label)
|
||||
self.c_vmode.set_choice(self.vmode)
|
||||
self.get_vformat()
|
||||
self.b_drop.set_button(1)
|
||||
self.in_rate.set_input('2')
|
||||
self.in_maxmem.set_input('1.0')
|
||||
self.in_nframes.set_input('0')
|
||||
self.in_nframes_vcr.set_input('1')
|
||||
self.in_rate_vcr.set_input('1')
|
||||
self.c_vcrspeed.clear_choice()
|
||||
for label in VcrSpeedLabels:
|
||||
self.c_vcrspeed.addto_choice(label)
|
||||
self.c_vcrspeed.set_choice(4)
|
||||
self.c_rgb24_size.clear_choice()
|
||||
for label in RgbSizeLabels:
|
||||
self.c_rgb24_size.addto_choice(label)
|
||||
self.c_rgb24_size.set_choice(self.rgb24_size)
|
||||
if cl:
|
||||
algs = cl.QueryAlgorithms(cl.VIDEO)
|
||||
self.all_comp_schemes = []
|
||||
for i in range(0, len(algs), 2):
|
||||
if algs[i+1] in (cl.COMPRESSOR, cl.CODEC):
|
||||
self.all_comp_schemes.append(algs[i])
|
||||
self.c_cformat.clear_choice()
|
||||
for label in self.all_comp_schemes:
|
||||
self.c_cformat.addto_choice(label)
|
||||
i = self.all_comp_schemes.index(self.comp_scheme)
|
||||
self.c_cformat.set_choice(i+1)
|
||||
# Audio defaults
|
||||
self.aout = None
|
||||
self.aport = None
|
||||
self.c_aformat.clear_choice()
|
||||
for label in AudioFormatLabels:
|
||||
self.c_aformat.addto_choice(label)
|
||||
self.c_aformat.set_choice(self.aformat)
|
||||
self.get_aformat()
|
||||
|
||||
def openvideo(self):
|
||||
try:
|
||||
self.video = sv.OpenVideo()
|
||||
except sv.error, msg:
|
||||
print 'Error opening video:', msg
|
||||
self.video = None
|
||||
param = [SV.BROADCAST, SV.PAL]
|
||||
if self.video: self.video.GetParam(param)
|
||||
if param[1] == SV.PAL:
|
||||
x = SV.PAL_XMAX
|
||||
y = SV.PAL_YMAX
|
||||
elif param[1] == SV.NTSC:
|
||||
x = SV.NTSC_XMAX
|
||||
y = SV.NTSC_YMAX
|
||||
else:
|
||||
print 'Unknown video standard:', param[1]
|
||||
sys.exit(1)
|
||||
self.maxx, self.maxy = x, y
|
||||
self.curx = 256
|
||||
self.cury = 256*3/4
|
||||
|
||||
def makewindow(self):
|
||||
x, y = self.maxx, self.maxy
|
||||
gl.foreground()
|
||||
gl.maxsize(x, y)
|
||||
gl.keepaspect(x, y)
|
||||
gl.stepunit(8, 6)
|
||||
width = self.curx
|
||||
height = self.cury
|
||||
if width and height:
|
||||
# Place the window at (150, 150) from top left
|
||||
# (the video board likes this location...)
|
||||
x1 = 150
|
||||
x2 = x1+width-1
|
||||
SCRHEIGHT = 768
|
||||
y2 = SCRHEIGHT-1-150
|
||||
y1 = y2-height+1
|
||||
gl.prefposition(x1, x2, y1, y2)
|
||||
self.window = gl.winopen('Vb video')
|
||||
self.settitle()
|
||||
if width:
|
||||
gl.maxsize(x, y)
|
||||
gl.keepaspect(x, y)
|
||||
gl.stepunit(8, 6)
|
||||
gl.winconstraints()
|
||||
gl.qdevice(DEVICE.LEFTMOUSE)
|
||||
gl.qdevice(DEVICE.WINQUIT)
|
||||
gl.qdevice(DEVICE.WINSHUT)
|
||||
|
||||
def optfullsizewindow(self):
|
||||
if not self.window:
|
||||
return
|
||||
gl.winset(self.window)
|
||||
if self.use_24:
|
||||
x, y = self.maxx, self.maxy
|
||||
else:
|
||||
x, y = self.curx, self.cury
|
||||
left, bottom = gl.getorigin()
|
||||
width, height = gl.getsize()
|
||||
bottom = bottom+height-y
|
||||
gl.prefposition(left, left+x-1, bottom, bottom+y-1)
|
||||
gl.winconstraints()
|
||||
if not self.use_24:
|
||||
gl.keepaspect(x, y)
|
||||
gl.stepunit(8, 6)
|
||||
gl.maxsize(self.maxx, self.maxy)
|
||||
gl.winconstraints()
|
||||
self.bindvideo()
|
||||
|
||||
def bindvideo(self):
|
||||
if not self.video: return
|
||||
x, y = gl.getsize()
|
||||
if not self.use_24:
|
||||
self.curx, self.cury = x, y
|
||||
self.video.SetSize(x, y)
|
||||
drop = self.b_drop.get_button()
|
||||
if drop:
|
||||
param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF]
|
||||
else:
|
||||
param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON]
|
||||
if self.rgb:
|
||||
param = param+[SV.COLOR, SV.DEFAULT_COLOR, \
|
||||
SV.DITHER, 1, \
|
||||
SV.INPUT_BYPASS, 0]
|
||||
else:
|
||||
param = param+[SV.COLOR, SV.MONO, SV.DITHER, 0, \
|
||||
SV.INPUT_BYPASS, 1]
|
||||
self.video.BindGLWindow(self.window, SV.IN_REPLACE)
|
||||
self.video.SetParam(param)
|
||||
|
||||
def rebindvideo(self):
|
||||
gl.winset(self.window)
|
||||
self.bindvideo()
|
||||
|
||||
def reset(self):
|
||||
self.close_video()
|
||||
self.close_audio()
|
||||
if self.vcr:
|
||||
try:
|
||||
ok = self.vcr.still()
|
||||
except VCR.error:
|
||||
pass
|
||||
self.vcr = None
|
||||
self.b_capture.set_button(0)
|
||||
|
||||
# Event handler (catches resize of video window)
|
||||
|
||||
def do_event(self, dev, val):
|
||||
#print 'Event:', dev, val
|
||||
if dev in (DEVICE.WINSHUT, DEVICE.WINQUIT):
|
||||
self.close()
|
||||
if dev == DEVICE.REDRAW and val == self.window:
|
||||
self.rebindvideo()
|
||||
self.settitle()
|
||||
|
||||
# Video controls: format, mode, file
|
||||
|
||||
def cb_vformat(self, *args):
|
||||
self.reset()
|
||||
self.get_vformat()
|
||||
if self.mono_use_thresh:
|
||||
s = `self.mono_thresh`
|
||||
s = fl.show_input('Please enter mono threshold', s)
|
||||
if s:
|
||||
try:
|
||||
self.mono_thresh = string.atoi(s)
|
||||
except string.atoi_error:
|
||||
fl.show_message('Bad input, using', \
|
||||
`self.mono_thresh`, '')
|
||||
self.rebindvideo()
|
||||
|
||||
def cb_cformat(self, *args):
|
||||
i = self.c_cformat.get_choice()
|
||||
self.comp_scheme = self.all_comp_schemes[i-1]
|
||||
|
||||
|
||||
def cb_vmode(self, *args):
|
||||
if self.vcr:
|
||||
self.vcr = None
|
||||
self.vmode = self.c_vmode.get_choice()
|
||||
self.form.freeze_form()
|
||||
self.g_cont.hide_object()
|
||||
self.g_burst.hide_object()
|
||||
self.g_single.hide_object()
|
||||
self.g_vcr.hide_object()
|
||||
if self.vmode == VM_CONT:
|
||||
self.g_cont.show_object()
|
||||
elif self.vmode == VM_BURST:
|
||||
self.g_burst.show_object()
|
||||
elif self.vmode == VM_SINGLE:
|
||||
self.g_single.show_object()
|
||||
elif self.vmode == VM_VCR:
|
||||
self.g_vcr.show_object()
|
||||
self.form.unfreeze_form()
|
||||
|
||||
def cb_vfile(self, *args):
|
||||
filename = self.vfile
|
||||
hd, tl = os.path.split(filename)
|
||||
filename = fl.file_selector('Video save file:', hd, '', tl)
|
||||
if filename:
|
||||
self.reset()
|
||||
hd, tl = os.path.split(filename)
|
||||
if hd == os.getcwd():
|
||||
filename = tl
|
||||
self.vfile = filename
|
||||
|
||||
# Video mode specific video controls
|
||||
|
||||
def cb_rate(self, *args):
|
||||
pass
|
||||
|
||||
def cb_drop(self, *args):
|
||||
self.rebindvideo()
|
||||
|
||||
def cb_maxmem(self, *args):
|
||||
pass
|
||||
|
||||
def cb_nframes(self, *args):
|
||||
pass
|
||||
|
||||
def cb_fps(self, *args):
|
||||
pass
|
||||
|
||||
def cb_nframes_vcr(self, *args):
|
||||
pass
|
||||
|
||||
def cb_rate_vcr(self, *args):
|
||||
pass
|
||||
|
||||
def cb_vcrspeed(self, *args):
|
||||
pass
|
||||
|
||||
def cb_rgb24_size(self, *args):
|
||||
i = self.c_rgb24_size.get_choice()
|
||||
if i:
|
||||
self.rgb24_size = i
|
||||
|
||||
# Audio controls: format, file
|
||||
|
||||
def cb_aformat(self, *args):
|
||||
self.get_aformat()
|
||||
|
||||
def cb_afile(self, *args):
|
||||
filename = self.afile
|
||||
hd, tl = os.path.split(filename)
|
||||
filename = fl.file_selector('Audio save file:', hd, '', tl)
|
||||
if filename:
|
||||
self.reset()
|
||||
hd, tl = os.path.split(filename)
|
||||
if hd == os.getcwd():
|
||||
filename = tl
|
||||
self.afile = filename
|
||||
|
||||
# General controls: capture, reset, play, quit
|
||||
|
||||
def cb_capture(self, *args):
|
||||
if self.capturing:
|
||||
raise StopCapture
|
||||
if not self.b_capture.get_button():
|
||||
return
|
||||
if not self.video or not self.vformat:
|
||||
gl.ringbell()
|
||||
return
|
||||
if self.vmode == VM_CONT:
|
||||
self.cont_capture()
|
||||
elif self.vmode == VM_BURST:
|
||||
self.burst_capture()
|
||||
elif self.vmode == VM_SINGLE:
|
||||
self.single_capture(None, None)
|
||||
elif self.vmode == VM_VCR:
|
||||
self.vcr_capture()
|
||||
|
||||
def cb_reset(self, *args):
|
||||
self.reset()
|
||||
|
||||
def cb_play(self, *args):
|
||||
self.reset()
|
||||
sts = os.system('Vplay -q ' + self.vfile + ' &')
|
||||
|
||||
def cb_quit(self, *args):
|
||||
self.close()
|
||||
|
||||
# Capture routines
|
||||
|
||||
def burst_capture(self):
|
||||
self.setwatch()
|
||||
gl.winset(self.window)
|
||||
x, y = gl.getsize()
|
||||
if self.use_24:
|
||||
fl.show_message('Sorry, no 24 bit continuous capture yet', '', '')
|
||||
return
|
||||
vformat = SV.RGB8_FRAMES
|
||||
nframes = self.getint(self.in_nframes, 0)
|
||||
if nframes == 0:
|
||||
maxmem = self.getint(self.in_maxmem, 1.0)
|
||||
memsize = int(maxmem * 1024 * 1024)
|
||||
nframes = self.calcnframes(memsize)
|
||||
info = (vformat, x, y, nframes, 1)
|
||||
try:
|
||||
info2, data, bitvec = self.video.CaptureBurst(info)
|
||||
except sv.error, msg:
|
||||
self.b_capture.set_button(0)
|
||||
self.setarrow()
|
||||
fl.show_message('Capture error:', str(msg), '')
|
||||
return
|
||||
if info <> info2: print info, '<>', info2
|
||||
self.save_burst(info2, data, bitvec)
|
||||
self.setarrow()
|
||||
|
||||
def calcnframes(self, memsize):
|
||||
gl.winset(self.window)
|
||||
x, y = gl.getsize()
|
||||
pixels = x*y
|
||||
pixels = pixels/2 # XXX always assume fields
|
||||
if self.mono or self.grey:
|
||||
n = memsize/pixels
|
||||
else:
|
||||
n = memsize/(4*pixels)
|
||||
return max(1, n)
|
||||
|
||||
def save_burst(self, info, data, bitvec):
|
||||
(vformat, x, y, nframes, rate) = info
|
||||
self.open_if_closed()
|
||||
fieldsize = x*y/2
|
||||
nskipped = 0
|
||||
realframeno = 0
|
||||
tpf = 1000 / 50.0 # XXX
|
||||
for frameno in range(0, nframes*2):
|
||||
if frameno <> 0 and \
|
||||
bitvec[frameno] == bitvec[frameno-1]:
|
||||
nskipped = nskipped + 1
|
||||
continue
|
||||
#
|
||||
# Save field.
|
||||
# XXX Works only for fields and top-to-bottom
|
||||
#
|
||||
start = frameno*fieldsize
|
||||
field = data[start:start+fieldsize]
|
||||
realframeno = realframeno + 1
|
||||
fn = int(realframeno*tpf)
|
||||
if not self.write_frame(fn, field):
|
||||
break
|
||||
|
||||
def cont_capture(self):
|
||||
saved_label = self.b_capture.label
|
||||
self.b_capture.label = 'Stop\n' + saved_label
|
||||
self.open_if_closed()
|
||||
self.init_cont()
|
||||
fps = 59.64 # Fields per second
|
||||
# XXX (fps of Indigo monitor, not of PAL or NTSC!)
|
||||
tpf = 1000.0 / fps # Time per field in msec
|
||||
self.capturing = 1
|
||||
self.start_audio()
|
||||
while 1:
|
||||
try:
|
||||
void = fl.check_forms()
|
||||
except StopCapture:
|
||||
break
|
||||
try:
|
||||
cd, id = self.video.GetCaptureData()
|
||||
except sv.error:
|
||||
sgi.nap(1)
|
||||
continue
|
||||
id = id + 2*self.rate
|
||||
data = cd.InterleaveFields(1)
|
||||
cd.UnlockCaptureData()
|
||||
t = id*tpf
|
||||
if not self.write_frame(t, data):
|
||||
break
|
||||
self.stop_audio()
|
||||
self.capturing = 0
|
||||
self.end_cont()
|
||||
if self.aout:
|
||||
# If recording audio, can't capture multiple sequences
|
||||
self.reset()
|
||||
self.b_capture.label = saved_label
|
||||
|
||||
def single_capture(self, stepfunc, timecode):
|
||||
self.open_if_closed()
|
||||
self.init_cont()
|
||||
while 1:
|
||||
try:
|
||||
cd, id = self.video.GetCaptureData()
|
||||
break
|
||||
except sv.error:
|
||||
pass
|
||||
sgi.nap(1)
|
||||
if stepfunc: # This might step the video
|
||||
d=stepfunc() # to the next frame
|
||||
if not self.use_24:
|
||||
data = cd.InterleaveFields(1)
|
||||
else:
|
||||
x, y = self.vout.getsize()
|
||||
if self.use_compress:
|
||||
if self.rgb24_size == 1:
|
||||
data = cd.YUVtoYUV422DC(0)
|
||||
elif self.rgb24_size == 2:
|
||||
data = cd.YUVtoYUV422DC_quarter(1)
|
||||
x = x/2
|
||||
y = y/2
|
||||
elif self.rgb24_size == 3:
|
||||
data = cd.YUVtoYUV422DC_sixteenth(1)
|
||||
x = x/4
|
||||
y = y/4
|
||||
else:
|
||||
data = cd.YUVtoRGB(1)
|
||||
if self.maxx*self.maxy*4 <> len(data):
|
||||
print 'maxx,maxy,exp,got=', self.maxx,
|
||||
print self.maxy,self.maxx*self.maxy*4,
|
||||
print len(data)
|
||||
fl.showmessage('Wrong sized data')
|
||||
return 0
|
||||
if self.rgb24_size <> 1:
|
||||
data = imageop.scale(data, 4, \
|
||||
self.maxx, self.maxy, x, y)
|
||||
if self.use_jpeg:
|
||||
import jpeg
|
||||
data = jpeg.compress(data, x, y, 4)
|
||||
if self.use_compress:
|
||||
data = self.compressor.Compress(1, data)
|
||||
cd.UnlockCaptureData()
|
||||
self.end_cont()
|
||||
if timecode == None:
|
||||
timecode = (self.nframes+1) * (1000/25)
|
||||
return self.write_frame(timecode, data)
|
||||
|
||||
def vcr_capture(self):
|
||||
if not self.vcr:
|
||||
try:
|
||||
print 'Connecting to VCR ...'
|
||||
self.vcr = VCR.VCR()
|
||||
print 'Waiting for VCR to come online ...'
|
||||
self.vcr.initvcr()
|
||||
print 'Preparing VCR ...'
|
||||
if not (self.vcr.fmmode('dnr') and \
|
||||
self.vcr.dmcontrol('digital slow')):
|
||||
self.vcr_error('digital slow failed')
|
||||
return
|
||||
print 'VCR OK.'
|
||||
except VCR.error, msg:
|
||||
self.vcr = None
|
||||
self.vcr_error(msg)
|
||||
return
|
||||
if not self.vcr.still():
|
||||
self.vcr_error('still failed')
|
||||
return
|
||||
self.open_if_closed()
|
||||
rate = self.getint(self.in_rate_vcr, 1)
|
||||
rate = max(rate, 1)
|
||||
vcrspeed = self.c_vcrspeed.get_choice()
|
||||
vcrspeed = VcrSpeeds[vcrspeed]
|
||||
if vcrspeed == 0:
|
||||
stepfunc = self.vcr.step
|
||||
else:
|
||||
stepfunc = None
|
||||
self.speed_factor = rate
|
||||
addr = start_addr = self.vcr.sense()
|
||||
if not self.single_capture(None, 0):
|
||||
return
|
||||
print 'captured %02d:%02d:%02d:%02d' % self.vcr.addr2tc(addr)
|
||||
count = self.getint(self.in_nframes_vcr, 1) - 1
|
||||
if count <= 0:
|
||||
while rate > 0:
|
||||
if not self.vcr.step():
|
||||
self.vcr_error('step failed')
|
||||
here = self.vcr.sense()
|
||||
if here > addr:
|
||||
rate = rate - (here - addr)
|
||||
addr = here
|
||||
return
|
||||
if not self.vcr.fwdshuttle(vcrspeed):
|
||||
self.vcr_error('fwd shuttle failed')
|
||||
return
|
||||
cycle = 0
|
||||
while count > 0:
|
||||
try:
|
||||
here = self.vcr.sense()
|
||||
except VCR.error, msg:
|
||||
self.vcr_error(msg)
|
||||
break
|
||||
if here <> addr:
|
||||
if here <> addr+1:
|
||||
print 'Missed', here-addr-1,
|
||||
print 'frame' + 's'*(here-addr-1 <> 1)
|
||||
cycle = (cycle+1) % rate
|
||||
if cycle == 0:
|
||||
tc = (here-start_addr)*40
|
||||
if not self.single_capture(stepfunc, \
|
||||
tc):
|
||||
break
|
||||
print 'captured %02d:%02d:%02d:%02d' \
|
||||
% self.vcr.addr2tc(here)
|
||||
count = count -1
|
||||
addr = here
|
||||
if self.vcr and not self.vcr.still():
|
||||
self.vcr_error('still failed')
|
||||
|
||||
def vcr_error(self, msg):
|
||||
self.reset()
|
||||
fl.show_message('VCR error:', str(msg), '')
|
||||
|
||||
# Init/end continuous capture mode
|
||||
|
||||
def init_cont(self):
|
||||
qsize = 1
|
||||
if self.vmode == VM_CONT:
|
||||
self.rate = self.getint(self.in_rate, 2)
|
||||
else:
|
||||
self.rate = 2
|
||||
x, y = self.vout.getsize()
|
||||
if self.use_24:
|
||||
info = (SV.YUV411_FRAMES, x, y, qsize, self.rate)
|
||||
else:
|
||||
info = (SV.RGB8_FRAMES, x, y, qsize, self.rate)
|
||||
info2 = self.video.InitContinuousCapture(info)
|
||||
if info2 <> info:
|
||||
# XXX This is really only debug info
|
||||
print 'Info mismatch: requested', info, 'got', info2
|
||||
|
||||
def end_cont(self):
|
||||
self.video.EndContinuousCapture()
|
||||
|
||||
# Misc stuff
|
||||
|
||||
def settitle(self):
|
||||
gl.winset(self.window)
|
||||
x, y = gl.getsize()
|
||||
title = 'Vb ' + self.vfile + ' (%dx%d)' % (x, y)
|
||||
gl.wintitle(title)
|
||||
|
||||
def get_vformat(self):
|
||||
i = self.c_vformat.get_choice()
|
||||
label = VideoFormatLabels[i-1]
|
||||
format = VideoFormats[i-1]
|
||||
if format == 'compress' and cl == None:
|
||||
fl.show_message('Sorry, no compression library support')
|
||||
format = ''
|
||||
label = 'Video off'
|
||||
self.vformat = format
|
||||
if self.vformat == '':
|
||||
self.form.freeze_form()
|
||||
self.g_video.hide_object()
|
||||
self.g_cont.hide_object()
|
||||
self.g_burst.hide_object()
|
||||
self.g_single.hide_object()
|
||||
self.form.unfreeze_form()
|
||||
else:
|
||||
self.g_video.show_object()
|
||||
if self.vmode == VM_CONT:
|
||||
self.g_cont.show_object()
|
||||
elif self.vmode == VM_BURST:
|
||||
self.g_burst.show_object()
|
||||
elif self.vmode == VM_SINGLE:
|
||||
self.g_single.show_object()
|
||||
#
|
||||
self.rgb = (format[:3] == 'rgb' or format == 'compress')
|
||||
self.mono = (format == 'mono')
|
||||
self.grey = (format[:4] == 'grey')
|
||||
self.use_24 = (format in ('rgb', 'jpeg', 'compress'))
|
||||
if self.use_24:
|
||||
self.g_rgb24.show_object()
|
||||
else:
|
||||
self.g_rgb24.hide_object()
|
||||
self.use_jpeg = (format == 'jpeg')
|
||||
self.mono_use_thresh = (label == 'mono thresh')
|
||||
self.use_compress = (format == 'compress')
|
||||
if self.use_compress:
|
||||
self.g_compress.show_object()
|
||||
else:
|
||||
self.g_compress.hide_object()
|
||||
s = format[4:]
|
||||
if self.grey and s:
|
||||
self.greybits = string.atoi(s)
|
||||
else:
|
||||
self.greybits = 8
|
||||
if label == 'grey2 dith':
|
||||
self.greybits = -2
|
||||
#
|
||||
convertor = None
|
||||
if self.grey:
|
||||
if self.greybits == 2:
|
||||
convertor = imageop.grey2grey2
|
||||
elif self.greybits == 4:
|
||||
convertor = imageop.grey2grey4
|
||||
elif self.greybits == -2:
|
||||
convertor = imageop.dither2grey2
|
||||
self.convertor = convertor
|
||||
self.optfullsizewindow()
|
||||
|
||||
def get_aformat(self):
|
||||
self.reset()
|
||||
self.aformat = self.c_aformat.get_choice()
|
||||
if self.aformat == A_OFF:
|
||||
self.g_audio.hide_object()
|
||||
else:
|
||||
self.g_audio.show_object()
|
||||
|
||||
def init_compressor(self, w, h):
|
||||
self.compressor = None
|
||||
scheme = cl.QuerySchemeFromName(cl.VIDEO, self.comp_scheme)
|
||||
self.compressor = cl.OpenCompressor(scheme)
|
||||
parambuf = [cl.IMAGE_WIDTH, w, \
|
||||
cl.IMAGE_HEIGHT, h, \
|
||||
cl.ORIGINAL_FORMAT, cl.YUV422DC]
|
||||
self.compressor.SetParams(parambuf)
|
||||
return self.compressor.Compress(0, '')
|
||||
|
||||
def open_if_closed(self):
|
||||
if not self.vout:
|
||||
self.open_video()
|
||||
if not self.aout:
|
||||
self.open_audio()
|
||||
|
||||
# File I/O handling
|
||||
|
||||
def open_video(self):
|
||||
self.close_video()
|
||||
gl.winset(self.window)
|
||||
x, y = gl.getsize()
|
||||
if self.use_24:
|
||||
if self.rgb24_size == 2:
|
||||
x, y = x/2, y/2
|
||||
elif self.rgb24_size == 3:
|
||||
x, y = x/4, y/4
|
||||
vout = VFile.VoutFile(self.vfile)
|
||||
vout.setformat(self.vformat)
|
||||
if self.vformat == 'compress':
|
||||
cheader = self.init_compressor(x, y)
|
||||
vout.setcompressheader(cheader)
|
||||
vout.setsize(x, y)
|
||||
if self.vmode == VM_BURST:
|
||||
vout.setpf((1, -2))
|
||||
vout.writeheader()
|
||||
self.vout = vout
|
||||
self.nframes = 0
|
||||
self.speed_factor = 1
|
||||
self.t_nframes.label = `self.nframes`
|
||||
|
||||
def write_frame(self, t, data):
|
||||
t = t * self.speed_factor
|
||||
if not self.vout:
|
||||
gl.ringbell()
|
||||
return 0
|
||||
if self.convertor:
|
||||
data = self.convertor(data, len(data), 1)
|
||||
elif self.mono:
|
||||
if self.mono_use_thresh:
|
||||
data = imageop.grey2mono(data, \
|
||||
len(data), 1,\
|
||||
self.mono_thresh)
|
||||
else:
|
||||
data = imageop.dither2mono(data, \
|
||||
len(data), 1)
|
||||
try:
|
||||
self.vout.writeframe(int(t), data, None)
|
||||
except IOError, msg:
|
||||
self.reset()
|
||||
if msg == (0, 'Error 0'):
|
||||
msg = 'disk full??'
|
||||
fl.show_message('IOError', str(msg), '')
|
||||
return 0
|
||||
self.nframes = self.nframes + 1
|
||||
self.t_nframes.label = `self.nframes`
|
||||
return 1
|
||||
|
||||
def close_video(self):
|
||||
if not self.vout:
|
||||
return
|
||||
self.nframes = 0
|
||||
self.t_nframes.label = ''
|
||||
try:
|
||||
self.vout.close()
|
||||
except IOError, msg:
|
||||
if msg == (0, 'Error 0'):
|
||||
msg = 'disk full??'
|
||||
fl.show_message('IOError', str(msg), '')
|
||||
self.vout = None
|
||||
self.compressor = None
|
||||
|
||||
# Watch cursor handling
|
||||
|
||||
def setwatch(self):
|
||||
gl.winset(self.form.window)
|
||||
gl.setcursor(WATCH, 0, 0)
|
||||
gl.winset(self.window)
|
||||
gl.setcursor(WATCH, 0, 0)
|
||||
|
||||
def setarrow(self):
|
||||
gl.winset(self.form.window)
|
||||
gl.setcursor(ARROW, 0, 0)
|
||||
gl.winset(self.window)
|
||||
gl.setcursor(ARROW, 0, 0)
|
||||
|
||||
# Numeric field handling
|
||||
|
||||
def getint(self, field, default):
|
||||
try:
|
||||
value = string.atoi(field.get_input())
|
||||
except string.atoi_error:
|
||||
value = default
|
||||
field.set_input(`value`)
|
||||
return value
|
||||
|
||||
def getfloat(self, field, default):
|
||||
try:
|
||||
value = float(eval(field.get_input()))
|
||||
except:
|
||||
value = float(default)
|
||||
field.set_input(`value`)
|
||||
return value
|
||||
|
||||
# Audio stuff
|
||||
|
||||
def open_audio(self):
|
||||
if self.aformat == A_OFF:
|
||||
return
|
||||
import aifc
|
||||
import al
|
||||
import AL
|
||||
import thread
|
||||
self.close_audio()
|
||||
params = [AL.INPUT_RATE, 0]
|
||||
al.getparams(AL.DEFAULT_DEVICE, params)
|
||||
rate = params[1]
|
||||
self.aout = aifc.open(self.afile, 'w')
|
||||
if self.aformat in (A_16_STEREO, A_8_STEREO):
|
||||
nch = AL.STEREO
|
||||
else:
|
||||
nch = AL.MONO
|
||||
if self.aformat in (A_16_STEREO, A_16_MONO):
|
||||
width = AL.SAMPLE_16
|
||||
else:
|
||||
width = AL.SAMPLE_8
|
||||
self.aout.setnchannels(nch)
|
||||
self.aout.setsampwidth(width)
|
||||
self.aout.setframerate(rate)
|
||||
c = al.newconfig()
|
||||
c.setqueuesize(8000)
|
||||
c.setchannels(nch)
|
||||
c.setwidth(width)
|
||||
self.aport = al.openport('Vb audio record', 'r', c)
|
||||
self.audio_stop = 0
|
||||
self.audio_ok = 0
|
||||
self.audio_busy = 1
|
||||
thread.start_new_thread(self.record_audio, ())
|
||||
|
||||
def start_audio(self):
|
||||
if self.aformat == A_OFF:
|
||||
return
|
||||
self.audio_ok = 1
|
||||
|
||||
def record_audio(self, *args):
|
||||
# This function runs in a separate thread
|
||||
# Currently no semaphores are used
|
||||
while not self.audio_stop:
|
||||
data = self.aport.readsamps(4000)
|
||||
if self.audio_ok:
|
||||
self.aout.writeframes(data)
|
||||
data = None
|
||||
self.audio_busy = 0
|
||||
|
||||
def stop_audio(self):
|
||||
self.audio_ok = 0
|
||||
|
||||
def close_audio(self):
|
||||
if self.aout:
|
||||
self.audio_ok = 0
|
||||
self.audio_stop = 1
|
||||
while self.audio_busy:
|
||||
time.sleep(0.1)
|
||||
self.aout.close()
|
||||
self.aout = None
|
||||
if self.aport:
|
||||
self.aport.closeport()
|
||||
self.aport = None
|
||||
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
||||
sys.exit(1)
|
|
@ -1,615 +0,0 @@
|
|||
Magic: 12321
|
||||
|
||||
Internal Form Definition File
|
||||
(do not change)
|
||||
|
||||
Number of forms: 1
|
||||
|
||||
=============== FORM ===============
|
||||
Name: form
|
||||
Width: 450.000000
|
||||
Height: 260.000000
|
||||
Number of Objects: 40
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 450.000000 260.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 5
|
||||
box: 330.000000 150.000000 110.000015 60.000004
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 1
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Capture
|
||||
name: b_capture
|
||||
callback: cb_capture
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 330.000000 10.000000 110.000008 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Quit
|
||||
name: b_quit
|
||||
callback: cb_quit
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 330.000000 50.000000 110.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Playback
|
||||
name: b_play
|
||||
callback: cb_play
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 42
|
||||
type: 0
|
||||
box: 80.000000 220.000000 120.000000 30.000000
|
||||
boxtype: 5
|
||||
colors: 7 0
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Format:
|
||||
name: c_vformat
|
||||
callback: cb_vformat
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 330.000000 220.000000 110.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Reset
|
||||
name: b_reset
|
||||
callback: cb_reset
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 42
|
||||
type: 0
|
||||
box: 80.000000 50.000000 120.000000 30.000000
|
||||
boxtype: 5
|
||||
colors: 7 0
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Format:
|
||||
name: c_aformat
|
||||
callback: cb_aformat
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 1668246586 540019308
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_audio
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 10.000000 190.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Set audio file...
|
||||
name: b_afile
|
||||
callback: cb_afile
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 876099360 892416522
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 1147496041 1852404841
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_video
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 42
|
||||
type: 0
|
||||
box: 80.000000 180.000000 120.000000 30.000000
|
||||
boxtype: 5
|
||||
colors: 7 0
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Mode:
|
||||
name: c_vmode
|
||||
callback: cb_vmode
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 90.000000 190.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Set video file...
|
||||
name: b_vfile
|
||||
callback: cb_vfile
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 544171552 1331849829
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_single
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 31
|
||||
type: 2
|
||||
box: 220.000000 150.000000 100.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 13 5
|
||||
alignment: 0
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Frames/sec
|
||||
name: in_fps
|
||||
callback: cb_fps
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_burst
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 31
|
||||
type: 1
|
||||
box: 220.000000 150.000000 100.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 13 5
|
||||
alignment: 0
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Max Mbytes:
|
||||
name: in_maxmem
|
||||
callback: cb_maxmem
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 31
|
||||
type: 2
|
||||
box: 220.000000 90.000000 100.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 13 5
|
||||
alignment: 0
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Nr. of frames:
|
||||
name: in_nframes
|
||||
callback: cb_nframes
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_cont
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 31
|
||||
type: 2
|
||||
box: 250.000000 150.000000 40.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 13 5
|
||||
alignment: 0
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Capture rate:
|
||||
name: in_rate
|
||||
callback: cb_rate
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 220.000000 150.000000 30.000000 30.000000
|
||||
boxtype: 0
|
||||
colors: 47 47
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: 1/
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 290.000000 150.000000 30.000000 30.000000
|
||||
boxtype: 0
|
||||
colors: 47 47
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: fr
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 13
|
||||
type: 0
|
||||
box: 220.000000 90.000000 100.000000 30.000000
|
||||
boxtype: 0
|
||||
colors: 7 3
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Fielddrop
|
||||
name: b_drop
|
||||
callback: cb_drop
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 330.000000 90.000000 110.000000 30.000002
|
||||
boxtype: 2
|
||||
colors: 47 47
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: t_nframes
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 330.000000 120.000000 110.000000 30.000000
|
||||
boxtype: 0
|
||||
colors: 47 47
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Frames done:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 640 235
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_vcr
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 31
|
||||
type: 2
|
||||
box: 220.000000 90.000000 100.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 13 5
|
||||
alignment: 0
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: # frames wtd:
|
||||
name: in_nframes_vcr
|
||||
callback: cb_nframes_vcr
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 31
|
||||
type: 2
|
||||
box: 220.000000 150.000000 100.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 13 5
|
||||
alignment: 0
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Sample rate:
|
||||
name: in_rate_vcr
|
||||
callback: cb_rate_vcr
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 42
|
||||
type: 0
|
||||
box: 220.000000 10.000000 100.000000 30.000000
|
||||
boxtype: 5
|
||||
colors: 7 0
|
||||
alignment: 0
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: VCR speed:
|
||||
name: c_vcrspeed
|
||||
callback: cb_vcrspeed
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 640 235
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 58720287 33751040
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_rgb24
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 42
|
||||
type: 0
|
||||
box: 260.000000 220.000000 60.000000 30.000000
|
||||
boxtype: 5
|
||||
colors: 7 0
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Size:
|
||||
name: c_rgb24_size
|
||||
callback: cb_rgb24_size
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 10000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 10.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: g_compress
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 42
|
||||
type: 0
|
||||
box: 80.000000 140.000000 120.000000 30.000000
|
||||
boxtype: 5
|
||||
colors: 7 0
|
||||
alignment: 2
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Scheme:
|
||||
name: c_cformat
|
||||
callback: cb_cformat
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 20000
|
||||
type: 0
|
||||
box: 0.000000 0.000000 0.000000 0.000000
|
||||
boxtype: 0
|
||||
colors: 0 0
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 10.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
==============================
|
||||
create_the_forms
|
|
@ -1,291 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Universal (non-interactive) CMIF video file copier.
|
||||
|
||||
|
||||
# Possibilities:
|
||||
#
|
||||
# - Manipulate the time base:
|
||||
# = resample at a fixed rate
|
||||
# = divide the time codes by a speed factor (to make it go faster/slower)
|
||||
# = drop frames that are less than n msec apart (to accommodate slow players)
|
||||
# - Convert to a different format
|
||||
# - Magnify (scale) the image
|
||||
|
||||
|
||||
# Usage function (keep this up-to-date if you change the program!)
|
||||
|
||||
def usage():
|
||||
print 'Usage: Vcopy [options] [infile [outfile]]'
|
||||
print
|
||||
print 'Options:'
|
||||
print
|
||||
print '-t type : new image type (default unchanged)'
|
||||
print
|
||||
print '-M magnify : image magnification factor (default unchanged)'
|
||||
print '-w width : output image width (default height*4/3 if -h used)'
|
||||
print '-h height : output image height (default width*3/4 if -w used)'
|
||||
print
|
||||
print '-p pf : new x and y packfactor (default unchanged)'
|
||||
print '-x xpf : new x packfactor (default unchanged)'
|
||||
print '-y ypf : new y packfactor (default unchanged)'
|
||||
print
|
||||
print '-m delta : drop frames closer than delta msec (default 0)'
|
||||
print '-r delta : regenerate input time base delta msec apart'
|
||||
print '-s speed : speed change factor (default unchanged)'
|
||||
print
|
||||
print 'infile : input file (default film.video)'
|
||||
print 'outfile : output file (default out.video)'
|
||||
|
||||
|
||||
import sys
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
|
||||
import VFile
|
||||
import imgconv
|
||||
import imageop
|
||||
import getopt
|
||||
import string
|
||||
|
||||
|
||||
# Global options
|
||||
|
||||
speed = 1.0
|
||||
mindelta = 0
|
||||
regen = None
|
||||
newpf = None
|
||||
newtype = None
|
||||
magnify = None
|
||||
newwidth = None
|
||||
newheight = None
|
||||
|
||||
|
||||
# Function to turn a string into a float
|
||||
|
||||
atof_error = 'atof_error' # Exception if it fails
|
||||
|
||||
def atof(s):
|
||||
try:
|
||||
return float(eval(s))
|
||||
except:
|
||||
raise atof_error
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
global speed, mindelta, regen, newpf, newtype, \
|
||||
magnify, newwidth, newheight
|
||||
|
||||
# Parse command line
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], \
|
||||
'M:h:m:p:r:s:t:w:x:y:')
|
||||
except getopt.error, msg:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Error:', msg, '\n'
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
xpf = ypf = None
|
||||
|
||||
# Interpret options
|
||||
try:
|
||||
for opt, arg in opts:
|
||||
if opt == '-M': magnify = atof(arg)
|
||||
if opt == '-h': height = string.atoi(arg)
|
||||
if opt == '-m': mindelta = string.atoi(arg)
|
||||
if opt == '-p': xpf = ypf = string.atoi(arg)
|
||||
if opt == '-r': regen = string.atoi(arg)
|
||||
if opt == '-s': speed = atof(arg)
|
||||
if opt == '-t': newtype = arg
|
||||
if opt == '-w': newwidth = string.atoi(arg)
|
||||
if opt == '-x': xpf = string.atoi(arg)
|
||||
if opt == '-y': ypf = string.atoi(arg)
|
||||
except string.atoi_error:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Option', opt, 'requires integer argument'
|
||||
sys.exit(2)
|
||||
except atof_error:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Option', opt, 'requires float argument'
|
||||
sys.exit(2)
|
||||
|
||||
if xpf or ypf:
|
||||
newpf = (xpf, ypf)
|
||||
|
||||
if newwidth or newheight:
|
||||
if magnify:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Options -w or -h are incompatible with -M'
|
||||
sys.exit(2)
|
||||
if not newheight:
|
||||
newheight = newwidth * 3 / 4
|
||||
elif not newwidth:
|
||||
newwidth = newheight * 4 / 3
|
||||
|
||||
# Check filename arguments
|
||||
if len(args) < 1:
|
||||
args.append('film.video')
|
||||
if len(args) < 2:
|
||||
args.append('out.video')
|
||||
if len(args) > 2:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
if args[0] == args[1]:
|
||||
sys.stderr.write('Input file can\'t be output file\n')
|
||||
sys.exit(2)
|
||||
|
||||
# Do the right thing
|
||||
sts = process(args[0], args[1])
|
||||
|
||||
# Exit
|
||||
sys.exit(sts)
|
||||
|
||||
|
||||
# Copy one file to another
|
||||
|
||||
def process(infilename, outfilename):
|
||||
global newwidth, newheight, newpf
|
||||
|
||||
try:
|
||||
vin = VFile.BasicVinFile(infilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
except VFile.Error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
return 1
|
||||
except EOFError:
|
||||
sys.stderr.write(infilename + ': EOF in video file\n')
|
||||
return 1
|
||||
|
||||
try:
|
||||
vout = VFile.BasicVoutFile(outfilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
|
||||
print '=== input file ==='
|
||||
vin.printinfo()
|
||||
|
||||
vout.setinfo(vin.getinfo())
|
||||
|
||||
scale = 0
|
||||
flip = 0
|
||||
decompress = 0
|
||||
|
||||
vinfmt = vin.format
|
||||
if vinfmt == 'compress':
|
||||
if not newtype or newtype == 'compress':
|
||||
# compressed->compressed: copy compression header
|
||||
vout.setcompressheader(vin.getcompressheader())
|
||||
else:
|
||||
# compressed->something else: go via rgb-24
|
||||
decompress = 1
|
||||
vinfmt = 'rgb'
|
||||
elif newtype == 'compress':
|
||||
# something else->compressed: not implemented
|
||||
sys.stderr.write('Sorry, conversion to compressed not yet implemented\n')
|
||||
return 1
|
||||
if newtype:
|
||||
vout.setformat(newtype)
|
||||
try:
|
||||
convert = imgconv.getconverter(vinfmt, vout.format)
|
||||
except imgconv.error, msg:
|
||||
sys.stderr.write(str(msg) + '\n')
|
||||
return 1
|
||||
|
||||
if newpf:
|
||||
xpf, ypf = newpf
|
||||
if not xpf: xpf = vin.xpf
|
||||
if not ypf: ypf = vout.ypf
|
||||
newpf = (xpf, ypf)
|
||||
vout.setpf(newpf)
|
||||
|
||||
if newwidth and newheight:
|
||||
scale = 1
|
||||
|
||||
if vin.upside_down <> vout.upside_down or \
|
||||
vin.mirror_image <> vout.mirror_image:
|
||||
flip = 1
|
||||
|
||||
inwidth, inheight = vin.getsize()
|
||||
inwidth = inwidth / vin.xpf
|
||||
inheight = inheight / vin.ypf
|
||||
|
||||
if magnify:
|
||||
newwidth = int(vout.width * magnify)
|
||||
newheight = int(vout.height * magnify)
|
||||
scale = 1
|
||||
|
||||
if scale:
|
||||
vout.setsize(newwidth, newheight)
|
||||
else:
|
||||
newwidth, newheight = vout.getsize()
|
||||
|
||||
if vin.packfactor <> vout.packfactor:
|
||||
scale = 1
|
||||
|
||||
if scale or flip:
|
||||
if vout.bpp not in (8, 32):
|
||||
sys.stderr.write('Can\'t scale or flip this type\n')
|
||||
return 1
|
||||
|
||||
newwidth = newwidth / vout.xpf
|
||||
newheight = newheight / vout.ypf
|
||||
|
||||
print '=== output file ==='
|
||||
vout.printinfo()
|
||||
vout.writeheader()
|
||||
|
||||
told = 0
|
||||
nin = 0
|
||||
nout = 0
|
||||
tin = 0
|
||||
tout = 0
|
||||
|
||||
while 1:
|
||||
try:
|
||||
tin, data, cdata = vin.getnextframe()
|
||||
except EOFError:
|
||||
break
|
||||
if decompress:
|
||||
data = vin.decompress(data)
|
||||
nin = nin + 1
|
||||
if regen:
|
||||
tout = nin * regen
|
||||
else:
|
||||
tout = tin
|
||||
tout = int(tout / speed)
|
||||
if tout - told < mindelta:
|
||||
continue
|
||||
told = tout
|
||||
if newtype:
|
||||
data = convert(data, inwidth, inheight)
|
||||
if scale:
|
||||
data = imageop.scale(data, vout.bpp/8, \
|
||||
inwidth, inheight, newwidth, newheight)
|
||||
if flip:
|
||||
x0, y0 = 0, 0
|
||||
x1, y1 = newwidth-1, newheight-1
|
||||
if vin.upside_down <> vout.upside_down:
|
||||
y1, y0 = y0, y1
|
||||
if vin.mirror_image <> vout.mirror_image:
|
||||
x1, x0 = x0, x1
|
||||
data = imageop.crop(data, vout.bpp/8, \
|
||||
newwidth, newheight, x0, y0, x1, y1)
|
||||
print 'Writing frame', nout
|
||||
vout.writeframe(tout, data, cdata)
|
||||
nout = nout + 1
|
||||
|
||||
vout.close()
|
||||
vin.close()
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
|
@ -1,327 +0,0 @@
|
|||
#
|
||||
# A VCR index.
|
||||
#
|
||||
import os
|
||||
import string
|
||||
|
||||
error='VcrIndex.error'
|
||||
VERSION_STRING='#!VcrIndex 1.1\n'
|
||||
PREV_VERSION_STRING='#!VcrIndex 1.0\n'
|
||||
|
||||
class VcrIndex:
|
||||
def __init__(self, name):
|
||||
self.curmovie = None
|
||||
self.curscene = None
|
||||
self.modified = 0
|
||||
self.filename = name
|
||||
self.basename = os.path.basename(name)
|
||||
self.editable = []
|
||||
if not name:
|
||||
self.movies = {}
|
||||
return
|
||||
try:
|
||||
fp = open(name, 'r')
|
||||
except IOError:
|
||||
self.movies = {}
|
||||
return
|
||||
header = fp.readline()
|
||||
if header == PREV_VERSION_STRING:
|
||||
print 'Converting old-format database...'
|
||||
data = fp.read(100000)
|
||||
self.movies = eval(data)
|
||||
for m in self.movies.keys():
|
||||
d = self.movies[m]
|
||||
newd = {}
|
||||
for s in d.keys():
|
||||
newsd = {}
|
||||
newsd['START'] = d[s]
|
||||
if s == 'START':
|
||||
s = '-ALL-'
|
||||
newd[s] = newsd
|
||||
|
||||
self.movies[m] = newd
|
||||
print 'Done.'
|
||||
return
|
||||
if header <> VERSION_STRING:
|
||||
print 'VcrIndex: incorrect version string:', header
|
||||
self.movies = {}
|
||||
return
|
||||
data = fp.read(100000)
|
||||
self.movies = eval(data)
|
||||
#
|
||||
# Save database to given file (or same file as read from if no
|
||||
# filename given).
|
||||
#
|
||||
def save(self, name):
|
||||
if not name:
|
||||
name = self.filename
|
||||
if not name:
|
||||
raise error, 'No filename given'
|
||||
self.filename = name
|
||||
bupname = name + '~'
|
||||
try:
|
||||
os.unlink(bupname)
|
||||
except os.error:
|
||||
pass
|
||||
try:
|
||||
os.rename(name, bupname)
|
||||
except os.error:
|
||||
pass
|
||||
fp = open(name, 'w')
|
||||
data = str(self.movies)
|
||||
fp.write(VERSION_STRING)
|
||||
fp.write(data)
|
||||
fp.write('\n')
|
||||
fp.close()
|
||||
self.modified = 0
|
||||
#
|
||||
# Get a list of movie names in tape order
|
||||
#
|
||||
def get_movienames(self):
|
||||
names = self.movies.keys()
|
||||
sorted = []
|
||||
for name in names:
|
||||
sorted.append(self.movies[name]['-ALL-']['START'], name)
|
||||
sorted.sort()
|
||||
rv = []
|
||||
for pos, name in sorted:
|
||||
rv.append(name)
|
||||
return rv
|
||||
#
|
||||
# Get a list of scene names in tape order
|
||||
#
|
||||
def get_scenenames(self):
|
||||
if not self.curmovie:
|
||||
return []
|
||||
scenedict = self.movies[self.curmovie]
|
||||
names = scenedict.keys()
|
||||
sorted = []
|
||||
for name in names:
|
||||
sorted.append(scenedict[name], name)
|
||||
sorted.sort()
|
||||
rv = []
|
||||
for pos, name in sorted:
|
||||
rv.append(name)
|
||||
return rv
|
||||
#
|
||||
# Get a list of scene ids (format '00:02:32:12 name') in tape order
|
||||
#
|
||||
def get_sceneids(self):
|
||||
if not self.curmovie:
|
||||
return []
|
||||
scenedict = self.movies[self.curmovie]
|
||||
names = scenedict.keys()
|
||||
sorted = []
|
||||
for name in names:
|
||||
sorted.append(scenedict[name]['START'], name)
|
||||
sorted.sort()
|
||||
rv = []
|
||||
for pos, name in sorted:
|
||||
str = '%02d:%02d:%02d:%02d ' % pos
|
||||
rv.append(str + name)
|
||||
return rv
|
||||
#
|
||||
# Does a movie exist?
|
||||
#
|
||||
def movie_exists(self, name):
|
||||
return self.movies.has_key(name)
|
||||
#
|
||||
# Select a movie.
|
||||
#
|
||||
def movie_select(self, name):
|
||||
if not self.movies.has_key(name):
|
||||
raise error, 'No such movie: '+name
|
||||
self.curmovie = name
|
||||
self.curscene = None
|
||||
#
|
||||
# Get movie dictionary, or raise an error if no current movie.
|
||||
#
|
||||
def _getmoviedict(self):
|
||||
if not self.curmovie:
|
||||
raise error, 'No current movie'
|
||||
return self.movies[self.curmovie]
|
||||
#
|
||||
# Rename a movie.
|
||||
#
|
||||
def movie_rename(self, newname):
|
||||
scenedict = self._getmoviedict()
|
||||
if self.movie_exists(newname):
|
||||
raise error, 'Movie already exists: '+newname
|
||||
del self.movies[self.curmovie]
|
||||
self.movies[newname] = scenedict
|
||||
self.curmovie = newname
|
||||
self.modified = 1
|
||||
#
|
||||
# Copy a movie.
|
||||
#
|
||||
def movie_copy(self, newname):
|
||||
scenedict = self._getmoviedict()
|
||||
if self.movie_exists(newname):
|
||||
raise error, 'Movie already exists: '+newname
|
||||
newdict = {}
|
||||
for k in scenedict.keys():
|
||||
olddata = scenedict[k]
|
||||
newdata = {}
|
||||
for i in olddata.keys():
|
||||
newdata[i] = olddata[i]
|
||||
newdict[k] = newdata
|
||||
self.movies[newname] = newdict
|
||||
self.curmovie = newname
|
||||
self.modified = 1
|
||||
#
|
||||
# Delete a movie.
|
||||
#
|
||||
def movie_delete(self):
|
||||
if not self.curmovie:
|
||||
raise error, 'No current movie'
|
||||
del self.movies[self.curmovie]
|
||||
self.curmovie = None
|
||||
self.curscene = None
|
||||
self.modified = 1
|
||||
#
|
||||
# Create a new movie.
|
||||
#
|
||||
def movie_new(self, name, pos):
|
||||
if self.movie_exists(name):
|
||||
raise error, 'Movie already exists: '+name
|
||||
newdict = {}
|
||||
newsdict = {}
|
||||
newsdict['START'] = pos
|
||||
newdict['-ALL-'] = newsdict
|
||||
self.movies[name] = newdict
|
||||
self.curmovie = name
|
||||
self.curscene = None
|
||||
self.modified = 1
|
||||
#
|
||||
# Does a scene exist?
|
||||
#
|
||||
def scene_exists(self, name):
|
||||
scenedict = self._getmoviedict()
|
||||
return scenedict.has_key(name)
|
||||
#
|
||||
# Select a current scene.
|
||||
#
|
||||
def scene_select(self, name):
|
||||
scenedict = self._getmoviedict()
|
||||
if not scenedict.has_key(name):
|
||||
raise error, 'No such scene: '+name
|
||||
self.curscene = name
|
||||
#
|
||||
# Rename a scene.
|
||||
#
|
||||
def scene_rename(self, newname):
|
||||
scenedict = self._getmoviedict()
|
||||
if not self.curscene:
|
||||
raise error, 'No current scene'
|
||||
if scenedict.has_key(newname):
|
||||
raise error, 'Scene already exists: '+newname
|
||||
if self.curscene == '-ALL-':
|
||||
raise error, 'Cannot rename -ALL-'
|
||||
scenedict[newname] = scenedict[self.curscene]
|
||||
del scenedict[self.curscene]
|
||||
self.curscene = newname
|
||||
self.modified = 1
|
||||
#
|
||||
# Copy a scene.
|
||||
#
|
||||
def scene_copy(self, newname):
|
||||
scenedict = self._getmoviedict()
|
||||
if not self.curscene:
|
||||
raise error, 'No current scene'
|
||||
if scenedict.has_key(newname):
|
||||
raise error, 'Scene already exists: '+newname
|
||||
scenedict[newname] = scenedict[self.curscene]
|
||||
self.curscene = newname
|
||||
self.modified = 1
|
||||
#
|
||||
# Delete a scene.
|
||||
#
|
||||
def scene_delete(self):
|
||||
scenedict = self._getmoviedict()
|
||||
if not self.curscene:
|
||||
raise error, 'No current scene'
|
||||
if self.curscene == '-ALL-':
|
||||
raise error, 'Cannot delete -ALL-'
|
||||
del scenedict[self.curscene]
|
||||
self.curscene = None
|
||||
self.modified = 1
|
||||
#
|
||||
# Add a new scene.
|
||||
#
|
||||
def scene_new(self, newname, pos):
|
||||
scenedict = self._getmoviedict()
|
||||
if scenedict.has_key(newname):
|
||||
raise error, 'Scene already exists: '+newname
|
||||
newdict = {}
|
||||
newdict['START'] = pos
|
||||
scenedict[newname] = newdict
|
||||
self.curscene = newname
|
||||
self.modified = 1
|
||||
#
|
||||
# Get scene data.
|
||||
#
|
||||
def _getscenedata(self):
|
||||
scenedict = self._getmoviedict()
|
||||
if not self.curscene:
|
||||
raise error, 'No current scene'
|
||||
return scenedict[self.curscene]
|
||||
#
|
||||
# Data manipulation routines.
|
||||
#
|
||||
def pos_get(self):
|
||||
return self._getscenedata()['START']
|
||||
#
|
||||
def pos_set(self, pos):
|
||||
data = self._getscenedata()
|
||||
data['START'] = pos
|
||||
self.modified = 1
|
||||
#
|
||||
def comment_get(self):
|
||||
data = self._getscenedata()
|
||||
if data.has_key('COMMENT'):
|
||||
return data['COMMENT']
|
||||
else:
|
||||
return ''
|
||||
#
|
||||
def comment_set(self, comment):
|
||||
data = self._getscenedata()
|
||||
data['COMMENT'] = comment
|
||||
self.modified = 1
|
||||
#
|
||||
# Get the scene id of the current scene.
|
||||
#
|
||||
def get_cursceneid(self):
|
||||
pos = self._getscenedata()['START']
|
||||
str = '%02d:%02d:%02d:%02d ' % pos
|
||||
return str + self.curscene
|
||||
#
|
||||
# Convert a scene id to a scene name.
|
||||
#
|
||||
def scene_id2name(self, id):
|
||||
pos = string.find(id, ' ')
|
||||
if pos <= 0:
|
||||
raise error, 'Not a scene id: '+id
|
||||
return id[pos+1:]
|
||||
#
|
||||
# Select a scene given a position.
|
||||
#
|
||||
def pos_select(self, pos):
|
||||
prevmovie = None
|
||||
movies = self.get_movienames()
|
||||
for movie in movies:
|
||||
mpos = self.movies[movie]['-ALL-']['START']
|
||||
if mpos > pos:
|
||||
break
|
||||
prevmovie = movie
|
||||
if not prevmovie:
|
||||
raise error, 'Scene before BOT'
|
||||
|
||||
self.movie_select(prevmovie)
|
||||
scenes = self.get_scenenames()
|
||||
scenedict = self._getmoviedict()
|
||||
prevscene = 'START'
|
||||
for scene in scenes:
|
||||
if scenedict[scene]['START'] > pos:
|
||||
break
|
||||
prevscene = scene
|
||||
self.scene_select(prevscene)
|
|
@ -1,301 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Edit CMIF movies interactively -- copy one or more files to an output file
|
||||
|
||||
|
||||
# XXX To do:
|
||||
#
|
||||
# - convert between formats (grey, rgb, rgb8, ...)
|
||||
# - change size
|
||||
# - cut out a given area of the image
|
||||
# - change time base (a la Vtime)
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import gl, GL, DEVICE
|
||||
import fl, FL
|
||||
import flp
|
||||
import Viewer
|
||||
import getopt
|
||||
import string
|
||||
import watchcursor
|
||||
|
||||
ARROW = 0
|
||||
WATCH = 1
|
||||
watchcursor.defwatch(WATCH)
|
||||
|
||||
|
||||
def main():
|
||||
qsize = 40
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'q:')
|
||||
for o, a in opts:
|
||||
if o == '-q':
|
||||
qsize = string.atoi(a)
|
||||
ed = Editor(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)
|
||||
|
||||
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 busy(self):
|
||||
gl.winset(self.form.window)
|
||||
gl.setcursor(WATCH, 0, 0)
|
||||
|
||||
def ready(self):
|
||||
gl.winset(self.form.window)
|
||||
gl.setcursor(ARROW, 0, 0)
|
||||
|
||||
|
||||
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('Begin of input file')
|
||||
self.ishow()
|
||||
|
||||
def cb_in_slider(self, *args):
|
||||
if not self.icheck(): return
|
||||
left, pos, right = self.vin.qinfo()
|
||||
i = int(self.in_slider.get_slider_value())
|
||||
i = max(i, left)
|
||||
i = min(i, right)
|
||||
if i == pos: return
|
||||
if not self.vin.seek(i):
|
||||
self.err('Input seek failed')
|
||||
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 not data:
|
||||
self.err('End of input file')
|
||||
self.ishow()
|
||||
return
|
||||
if self.vout.getinfo() <> self.vin.getinfo():
|
||||
print 'Copying info...'
|
||||
self.vout.setinfo(self.vin.getinfo())
|
||||
if self.vin.format == 'compress':
|
||||
self.vout.setcompressheader(\
|
||||
self.vin.getcompressheader())
|
||||
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('Begin of input file')
|
||||
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, *args):
|
||||
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_slider(self, *args):
|
||||
if not self.ocheck(): return
|
||||
i = int(self.out_slider.get_slider_value())
|
||||
left, pos, right = self.vout.qinfo()
|
||||
i = int(self.out_slider.get_slider_value())
|
||||
i = max(i, left)
|
||||
i = min(i, right)
|
||||
if i == pos: return
|
||||
if not self.vout.seek(i):
|
||||
self.err('Output seek failed')
|
||||
self.oshow()
|
||||
|
||||
def cb_out_trunc(self, *arcs):
|
||||
if not self.ocheck(): return
|
||||
self.vout.trunc()
|
||||
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(filename, title)
|
||||
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.busy()
|
||||
self.msg('Closing input file...')
|
||||
self.vin.close()
|
||||
self.ready()
|
||||
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(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.busy()
|
||||
self.msg('Closing output file...')
|
||||
self.vout.close()
|
||||
self.ready()
|
||||
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, pos, right = v.qinfo()
|
||||
getattr(self, io + '_info1').label = `left`
|
||||
getattr(self, io + '_info2').label = `pos`
|
||||
getattr(self, io + '_info3').label = `right`
|
||||
sl = getattr(self, io + '_slider')
|
||||
self.form.freeze_form()
|
||||
sl.set_slider_bounds(left, right)
|
||||
sl.set_slider_value(pos)
|
||||
self.form.unfreeze_form()
|
||||
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
|
@ -1,435 +0,0 @@
|
|||
Magic: 12321
|
||||
|
||||
Internal Form Definition File
|
||||
(do not change)
|
||||
|
||||
Number of forms: 1
|
||||
|
||||
=============== FORM ===============
|
||||
Name: form
|
||||
Width: 510.000000
|
||||
Height: 350.000000
|
||||
Number of Objects: 28
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 510.000000 350.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 6
|
||||
box: 10.000000 130.000000 240.000000 209.999985
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 6
|
||||
box: 260.000000 130.000000 240.000000 209.999985
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 10.000000 10.000000 430.000000 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: CMIF Video Editor, by Guido van Rossum
|
||||
name: msg_area
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 4
|
||||
box: 200.000000 90.000000 120.000000 30.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: 210.000000 220.000000 30.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: @>
|
||||
name:
|
||||
callback: cb_in_skip
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 20.000000 140.000000 220.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Rewind
|
||||
name:
|
||||
callback: cb_in_rewind
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 270.000000 140.000000 100.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Reset
|
||||
name:
|
||||
callback: cb_out_rewind
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 20.000000 260.000000 160.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: New input file...
|
||||
name:
|
||||
callback: cb_in_new
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 330.000000 260.000000 160.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: New output file...
|
||||
name:
|
||||
callback: cb_out_new
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 20.000000 300.000000 220.000000 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: (none)
|
||||
name: in_file
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 270.000000 300.000000 220.000000 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: (none)
|
||||
name: out_file
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 450.000000 10.000000 50.000000 30.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: 270.000000 220.000000 30.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: @<
|
||||
name:
|
||||
callback: cb_out_back
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 4
|
||||
box: 20.000000 220.000000 30.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: @<
|
||||
name:
|
||||
callback: cb_in_back
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 4
|
||||
box: 460.000000 220.000000 30.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: @>
|
||||
name:
|
||||
callback: cb_out_skip
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 4
|
||||
box: 200.000000 50.000000 120.000000 30.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: 190.000000 260.000000 50.000000 30.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: 270.000000 260.000000 50.000000 30.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: 21
|
||||
type: 1
|
||||
box: 60.000000 220.000000 140.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 47 47
|
||||
alignment: 1
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: in_slider
|
||||
callback: cb_in_slider
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 21
|
||||
type: 1
|
||||
box: 310.000000 220.000000 140.000000 30.000000
|
||||
boxtype: 2
|
||||
colors: 47 47
|
||||
alignment: 1
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: out_slider
|
||||
callback: cb_out_slider
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 20.000000 180.000000 30.000000 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 8.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: in_info1
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 100.000000 180.000000 60.000004 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: in_info2
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 210.000000 180.000000 30.000000 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 8.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: in_info3
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 270.000000 180.000000 30.000000 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 8.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: out_info1
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 350.000000 180.000000 60.000004 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: out_info2
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 2
|
||||
type: 0
|
||||
box: 460.000000 180.000000 30.000000 30.000000
|
||||
boxtype: 6
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 8.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name: out_info3
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 390.000000 140.000000 100.000000 30.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Truncate
|
||||
name:
|
||||
callback: cb_out_trunc
|
||||
argument: 0
|
||||
|
||||
==============================
|
||||
create_the_forms
|
|
@ -1,90 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Copy a video file, fixing the line width to be a multiple of 4
|
||||
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# Vfix [infile [outfile]]
|
||||
|
||||
|
||||
# Options:
|
||||
#
|
||||
# infile : input file (default film.video)
|
||||
# outfile : output file (default out.video)
|
||||
|
||||
|
||||
import sys
|
||||
import imageop
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import VFile
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
if len(args) < 1:
|
||||
args.append('film.video')
|
||||
if len(args) < 2:
|
||||
args.append('out.video')
|
||||
if len(args) > 2:
|
||||
sys.stderr.write('usage: Vfix [infile [outfile]]\n')
|
||||
sys.exit(2)
|
||||
sts = process(args[0], args[1])
|
||||
sys.exit(sts)
|
||||
|
||||
|
||||
# Copy one file to another
|
||||
|
||||
def process(infilename, outfilename):
|
||||
try:
|
||||
vin = VFile.BasicVinFile(infilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
except VFile.Error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
return 1
|
||||
except EOFError:
|
||||
sys.stderr.write(infilename + ': EOF in video file\n')
|
||||
return 1
|
||||
|
||||
try:
|
||||
vout = VFile.BasicVoutFile(outfilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
|
||||
info = vin.getinfo()
|
||||
if info[0] <> 'grey':
|
||||
sys.stderr.write('Vfix: input not in grey format\n')
|
||||
return 1
|
||||
vout.setinfo(info)
|
||||
inwidth, height = vin.getsize()
|
||||
pf = vin.packfactor
|
||||
if (inwidth/pf)%4 == 0:
|
||||
sys.stderr.write('Vfix: fix not necessary\n')
|
||||
return 1
|
||||
outwidth = (inwidth/pf/4)*4*pf
|
||||
print 'inwidth =', inwidth, 'outwidth =', outwidth
|
||||
vout.setsize(outwidth, height)
|
||||
vout.writeheader()
|
||||
n = 0
|
||||
try:
|
||||
while 1:
|
||||
t, data, cdata = vin.getnextframe()
|
||||
n = n + 1
|
||||
sys.stderr.write('Frame ' + `n` + '...')
|
||||
data = imageop.crop(data, 1, inwidth/pf, height/pf, \
|
||||
0, 0, outwidth/pf-1, height/pf-1)
|
||||
vout.writeframe(t, data, None)
|
||||
sys.stderr.write('\n')
|
||||
except EOFError:
|
||||
pass
|
||||
return 0
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
main()
|
|
@ -1,2 +0,0 @@
|
|||
import sys, posixpath
|
||||
exec('import ' + posixpath.basename(sys.argv[0]) + '\n')
|
|
@ -1,255 +0,0 @@
|
|||
import gl, GL
|
||||
import VFile
|
||||
import os
|
||||
|
||||
|
||||
class InputViewer:
|
||||
|
||||
def __init__(self, filename, title, *args):
|
||||
try:
|
||||
self.vin = VFile.VinFile(filename)
|
||||
except (EOFError, VFile.Error):
|
||||
raise IOError, 'bad video input file'
|
||||
self.vin.warmcache()
|
||||
if not title:
|
||||
title = os.path.split(filename)[1]
|
||||
self.filename = filename
|
||||
self.title = title
|
||||
self.qsize = len(self.vin.index)
|
||||
gl.foreground()
|
||||
gl.prefsize(self.vin.width, self.vin.height)
|
||||
self.wid = -1
|
||||
self.reset()
|
||||
|
||||
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.qindex = 0
|
||||
|
||||
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()
|
||||
gl.winset(self.wid)
|
||||
if self.qindex >= self.qsize:
|
||||
self.vin.clear()
|
||||
return
|
||||
dt, d, cd = self.vin.getrandomframe(self.qindex)
|
||||
self.vin.showframe(d, cd)
|
||||
|
||||
def redraw(self, wid):
|
||||
if wid == self.wid >= 0:
|
||||
gl.winset(self.wid)
|
||||
gl.reshapeviewport()
|
||||
self.vin.clear()
|
||||
self.show()
|
||||
|
||||
def get(self):
|
||||
if self.qindex >= self.qsize:
|
||||
return None
|
||||
if self.qindex > 0:
|
||||
prevt, ds, cs = \
|
||||
self.vin.getrandomframeheader(self.qindex-1)
|
||||
else:
|
||||
prevt = 0
|
||||
t, data, cdata = self.vin.getrandomframe(self.qindex)
|
||||
self.qindex = self.qindex + 1
|
||||
return t-prevt, data, cdata
|
||||
|
||||
def backup(self):
|
||||
if self.qindex == 0:
|
||||
return 0
|
||||
self.qindex = self.qindex - 1
|
||||
return 1
|
||||
|
||||
def seek(self, i):
|
||||
if not 0 <= i <= self.qsize:
|
||||
return 0
|
||||
self.qindex = i
|
||||
return 1
|
||||
|
||||
def tell(self):
|
||||
return self.qindex
|
||||
|
||||
def qsizes(self):
|
||||
return self.qindex, self.qsize - self.qindex
|
||||
|
||||
def qinfo(self):
|
||||
return 0, self.qindex, self.qsize
|
||||
|
||||
|
||||
class OutputViewer:
|
||||
|
||||
def __init__(self, filename, title, qsize):
|
||||
try:
|
||||
self.vout = VFile.VoutFile(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()
|
||||
|
||||
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(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:
|
||||
self.vout.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.vout.clear()
|
||||
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 seek(self, i):
|
||||
i = i - self.written
|
||||
if not 0 <= i <= len(self.queue) + len(self.spares):
|
||||
return 0
|
||||
while i < len(self.queue):
|
||||
if not self.backup():
|
||||
return 0
|
||||
while i > len(self.queue):
|
||||
if not self.forward():
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def trunc(self):
|
||||
del self.spares[:]
|
||||
|
||||
def tell(self):
|
||||
return self.written + len(self.queue)
|
||||
|
||||
def qsizes(self):
|
||||
return len(self.queue), len(self.spares)
|
||||
|
||||
def qinfo(self):
|
||||
first = self.written
|
||||
pos = first + len(self.queue)
|
||||
last = pos + len(self.spares)
|
||||
return first, pos, last
|
||||
|
||||
|
||||
def test():
|
||||
import sys
|
||||
a = InputViewer(sys.argv[1], '')
|
||||
b = OutputViewer(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()
|
|
@ -1,174 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Print some info about a CMIF movie file
|
||||
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# Vinfo [-d] [-q] [-s] [-t] [file] ...
|
||||
|
||||
|
||||
# Options:
|
||||
#
|
||||
# -d : print deltas between frames instead of frame times
|
||||
# -q : quick: don't read the frames
|
||||
# -s : don't print times (but do count frames and print the total)
|
||||
# -t : terse (one line/file, implies -s)
|
||||
# file ... : file(s) to inspect; default film.video
|
||||
|
||||
|
||||
import sys
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import VFile
|
||||
import getopt
|
||||
import string
|
||||
|
||||
|
||||
# Global options
|
||||
|
||||
short = 0
|
||||
quick = 0
|
||||
delta = 0
|
||||
terse = 0
|
||||
maxwidth = 10
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
global short, quick, delta, terse, maxwidth
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'dqst')
|
||||
except getopt.error, msg:
|
||||
sys.stdout = sys.stderr
|
||||
print msg
|
||||
print 'usage: Vinfo [-d] [-q] [-s] [-t] [file] ...'
|
||||
sys.exit(2)
|
||||
for opt, arg in opts:
|
||||
if opt == '-q':
|
||||
quick = 1
|
||||
if opt == '-d':
|
||||
delta = 1
|
||||
if opt == '-s':
|
||||
short = 1
|
||||
if opt == '-t':
|
||||
terse = short = 1
|
||||
if not args:
|
||||
args = ['film.video']
|
||||
for filename in args:
|
||||
maxwidth = max(maxwidth, len(filename))
|
||||
sts = 0
|
||||
for filename in args:
|
||||
if process(filename):
|
||||
sts = 1
|
||||
sys.exit(sts)
|
||||
|
||||
|
||||
# Process one file
|
||||
|
||||
def process(filename):
|
||||
try:
|
||||
vin = VFile.RandomVinFile(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 file\n')
|
||||
return 1
|
||||
|
||||
if terse:
|
||||
print string.ljust(filename, maxwidth),
|
||||
kbytes = (VFile.getfilesize(filename) + 1023) / 1024
|
||||
print string.rjust(`kbytes`, 5) + 'K',
|
||||
print ' ', string.ljust(`vin.version`, 5),
|
||||
print string.ljust(vin.format, 8),
|
||||
print string.rjust(`vin.width`, 4),
|
||||
print string.rjust(`vin.height`, 4),
|
||||
if type(vin.packfactor) == type(()):
|
||||
xpf, ypf = vin.packfactor
|
||||
s = string.rjust(`xpf`, 2) + ',' + \
|
||||
string.rjust(`ypf`, 2)
|
||||
else:
|
||||
s = string.rjust(`vin.packfactor`, 2)
|
||||
if type(vin.packfactor) == type(0) and \
|
||||
vin.format not in ('rgb', 'jpeg') and \
|
||||
(vin.width/vin.packfactor) % 4 <> 0:
|
||||
s = s + '! '
|
||||
else:
|
||||
s = s + ' '
|
||||
print s,
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
vin.printinfo()
|
||||
|
||||
if quick:
|
||||
if terse:
|
||||
print
|
||||
vin.close()
|
||||
return 0
|
||||
|
||||
try:
|
||||
vin.readcache()
|
||||
if not terse:
|
||||
print '[Using cached index]'
|
||||
except VFile.Error:
|
||||
if not terse:
|
||||
print '[Constructing index on the fly]'
|
||||
|
||||
if not short:
|
||||
if delta:
|
||||
print 'Frame time deltas:',
|
||||
else:
|
||||
print 'Frame times:',
|
||||
|
||||
n = 0
|
||||
t = 0
|
||||
told = 0
|
||||
datasize = 0
|
||||
while 1:
|
||||
try:
|
||||
t, ds, cs = vin.getnextframeheader()
|
||||
vin.skipnextframedata(ds, cs)
|
||||
except EOFError:
|
||||
break
|
||||
datasize = datasize + ds
|
||||
if cs: datasize = datasize + cs
|
||||
if not short:
|
||||
if n%8 == 0:
|
||||
sys.stdout.write('\n')
|
||||
if delta:
|
||||
sys.stdout.write('\t' + `t - told`)
|
||||
told = t
|
||||
else:
|
||||
sys.stdout.write('\t' + `t`)
|
||||
n = n+1
|
||||
|
||||
if not short: print
|
||||
|
||||
if terse:
|
||||
print string.rjust(`n`, 6),
|
||||
if t: print string.rjust(`int(n*10000.0/t)*0.1`, 5),
|
||||
print
|
||||
else:
|
||||
print 'Total', n, 'frames in', t*0.001, 'sec.',
|
||||
if t: print '-- average', int(n*10000.0/t)*0.1, 'frames/sec',
|
||||
print
|
||||
print 'Total data', 0.1 * int(datasize / 102.4), 'Kbytes',
|
||||
if t:
|
||||
print '-- average',
|
||||
print 0.1 * int(datasize / 0.1024 / t), 'Kbytes/sec',
|
||||
print
|
||||
|
||||
vin.close()
|
||||
return 0
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
|
@ -1,92 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Compress an rgb or grey video file to jpeg format
|
||||
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# Vmkjpeg [infile [outfile]]
|
||||
|
||||
|
||||
# Options:
|
||||
#
|
||||
# infile : input file (default film.video)
|
||||
# outfile : output file (default out.video)
|
||||
|
||||
|
||||
import sys
|
||||
import jpeg
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import VFile
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
if len(args) < 1:
|
||||
args.append('film.video')
|
||||
if len(args) < 2:
|
||||
args.append('out.video')
|
||||
if len(args) > 2:
|
||||
sys.stderr.write('usage: Vmkjpeg [infile [outfile]]\n')
|
||||
sys.exit(2)
|
||||
sts = process(args[0], args[1])
|
||||
sys.exit(sts)
|
||||
|
||||
|
||||
# Copy one file to another
|
||||
|
||||
def process(infilename, outfilename):
|
||||
try:
|
||||
vin = VFile.BasicVinFile(infilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
except VFile.Error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
return 1
|
||||
except EOFError:
|
||||
sys.stderr.write(infilename + ': EOF in video file\n')
|
||||
return 1
|
||||
|
||||
try:
|
||||
vout = VFile.BasicVoutFile(outfilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
|
||||
info = vin.getinfo()
|
||||
if info[0] == 'rgb':
|
||||
width, height = vin.getsize()
|
||||
bytes = 4
|
||||
format = 'jpeg'
|
||||
elif info[0] == 'grey':
|
||||
width, height = vin.getsize()
|
||||
pf = vin.packfactor
|
||||
width, height = width / pf, height / pf
|
||||
bytes = 1
|
||||
format = 'jpeggrey'
|
||||
else:
|
||||
sys.stderr.write('Vmkjpeg: input not in rgb or grey format\n')
|
||||
return 1
|
||||
info = (format,) + info[1:]
|
||||
vout.setinfo(info)
|
||||
vout.writeheader()
|
||||
n = 0
|
||||
try:
|
||||
while 1:
|
||||
t, data, cdata = vin.getnextframe()
|
||||
n = n + 1
|
||||
sys.stderr.write('Frame ' + `n` + '...')
|
||||
data = jpeg.compress(data, width, height, bytes)
|
||||
vout.writeframe(t, data, None)
|
||||
sys.stderr.write('\n')
|
||||
except EOFError:
|
||||
pass
|
||||
return 0
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
main()
|
|
@ -1,355 +0,0 @@
|
|||
#! /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]'
|
|
@ -1,413 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
#! /ufs/guido/bin/sgi/python-405
|
||||
|
||||
# Capture a CMIF movie using the Indigo video library and board
|
||||
|
||||
# The CMIF video file format is documented in cmif-film.ms.
|
||||
# Audio data is recorded in AIFF format, using the input sampling
|
||||
# rate, source and volume set by the audio panel, in mono, 8
|
||||
# bits/sample.
|
||||
|
||||
|
||||
# Usage and help functions (keep this up-to-date if you change the program!)
|
||||
|
||||
def usage():
|
||||
print 'Usage: Vrec [options] [moviefile [audiofile]]'
|
||||
print
|
||||
print 'Options:'
|
||||
print '-a : record audio as well'
|
||||
print '-q queuesize : set the capture queue size (default 2)'
|
||||
print '-r rate : capture 1 out of every "rate" frames', \
|
||||
'(default and min 2)'
|
||||
print '-w width : initial window width', \
|
||||
'(default 256, use 0 for interactive placement)'
|
||||
print '-n : Don\'t write to file, only timing info'
|
||||
print '-d : drop fields if needed'
|
||||
print '-g bits : greyscale (2, 4 or 8 bits)'
|
||||
print '-G : 2-bit greyscale dithered'
|
||||
print '-m : monochrome dithered'
|
||||
print '-M value : monochrome thresholded with value'
|
||||
print '-f : Capture fields (in stead of frames)'
|
||||
print '-P frames : preallocate space for "frames" frames'
|
||||
print 'moviefile : here goes the movie data (default film.video)'
|
||||
print 'audiofile : with -a, here goes the audio data', \
|
||||
'(default film.aiff)'
|
||||
|
||||
def help():
|
||||
print 'Press the left mouse button to start recording, release it to'
|
||||
print 'end recording. You can record as many times as you wish, but'
|
||||
print 'each recording overwrites the output file(s) -- only the last'
|
||||
print 'recording is kept.'
|
||||
print
|
||||
print 'Press ESC or use the window manager Quit or Close window option'
|
||||
print 'to quit. If you quit before recording anything, the output'
|
||||
print 'file(s) are not touched.'
|
||||
|
||||
|
||||
# Imported modules
|
||||
|
||||
import sys
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import sv, SV
|
||||
import VFile
|
||||
import gl, GL, DEVICE
|
||||
import al, AL
|
||||
import time
|
||||
import posix
|
||||
import getopt
|
||||
import string
|
||||
import imageop
|
||||
import sgi
|
||||
|
||||
|
||||
# Main program
|
||||
|
||||
def main():
|
||||
format = SV.RGB8_FRAMES
|
||||
qsize = 2
|
||||
audio = 0
|
||||
rate = 2
|
||||
width = 0
|
||||
norecord = 0
|
||||
drop = 0
|
||||
mono = 0
|
||||
grey = 0
|
||||
greybits = 0
|
||||
monotreshold = -1
|
||||
fields = 0
|
||||
preallocspace = 0
|
||||
|
||||
# Parse command line
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'aq:r:w:ndg:mM:GfP:')
|
||||
except getopt.error, msg:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Error:', msg, '\n'
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
# Interpret options
|
||||
try:
|
||||
for opt, arg in opts:
|
||||
if opt == '-a':
|
||||
audio = 1
|
||||
elif opt == '-q':
|
||||
qsize = string.atoi(arg)
|
||||
elif opt == '-r':
|
||||
rate = string.atoi(arg)
|
||||
if rate < 2:
|
||||
sys.stderr.write( \
|
||||
'-r rate must be >= 2\n')
|
||||
sys.exit(2)
|
||||
elif opt == '-w':
|
||||
width = string.atoi(arg)
|
||||
elif opt == '-n':
|
||||
norecord = 1
|
||||
elif opt == '-d':
|
||||
drop = 1
|
||||
elif opt == '-g':
|
||||
grey = 1
|
||||
greybits = string.atoi(arg)
|
||||
if not greybits in (2, 4, 8):
|
||||
sys.stderr.write( \
|
||||
'Only 2, 4 or 8 bit greyscale supported\n')
|
||||
sys.exit(2)
|
||||
elif opt == '-G':
|
||||
grey = 1
|
||||
greybits = -2
|
||||
elif opt == '-m':
|
||||
mono = 1
|
||||
elif opt == '-M':
|
||||
mono = 1
|
||||
monotreshold = string.atoi(arg)
|
||||
elif opt == '-f':
|
||||
fields = 1
|
||||
elif opt == '-P':
|
||||
preallocspace = string.atoi(arg)
|
||||
except string.atoi_error:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Option', opt, 'requires integer argument'
|
||||
sys.exit(2)
|
||||
|
||||
# Check excess arguments
|
||||
# If norecord is on, refuse filename arguments
|
||||
if norecord:
|
||||
if args:
|
||||
sys.stdout = sys.stderr
|
||||
print 'With -n, no filename arguments are used\n'
|
||||
usage()
|
||||
sys.exit(2)
|
||||
elif args[2:]:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Too many filename arguments\n'
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
# Process file arguments
|
||||
if args:
|
||||
filename = args[0]
|
||||
else:
|
||||
filename = 'film.video'
|
||||
|
||||
if args[1:] and not audio:
|
||||
sys.stderr.write('-a turned on by appearance of 2nd file\n')
|
||||
audio = 1
|
||||
|
||||
if audio:
|
||||
if args[1:]:
|
||||
audiofilename = args[1]
|
||||
else:
|
||||
audiofilename = 'film.aiff'
|
||||
else:
|
||||
audiofilename = None
|
||||
|
||||
if norecord:
|
||||
filename = audiofilename = ''
|
||||
|
||||
# Open video
|
||||
v = sv.OpenVideo()
|
||||
# Determine maximum window size based on signal standard
|
||||
param = [SV.BROADCAST, 0]
|
||||
v.GetParam(param)
|
||||
if param[1] == SV.PAL:
|
||||
x = SV.PAL_XMAX
|
||||
y = SV.PAL_YMAX
|
||||
elif param[1] == SV.NTSC:
|
||||
x = SV.NTSC_XMAX
|
||||
y = SV.NTSC_YMAX
|
||||
else:
|
||||
print 'Unknown video standard', param[1]
|
||||
sys.exit(1)
|
||||
|
||||
gl.foreground()
|
||||
gl.maxsize(x, y)
|
||||
gl.keepaspect(x, y)
|
||||
gl.stepunit(8, 6)
|
||||
if width:
|
||||
height = width*3/4
|
||||
x1 = 150
|
||||
x2 = x1 + width-1
|
||||
y2 = 768-150
|
||||
y1 = y2-height+1
|
||||
gl.prefposition(x1, x2, y1, y2)
|
||||
win = gl.winopen(filename)
|
||||
if width:
|
||||
gl.maxsize(x, y)
|
||||
gl.keepaspect(x, y)
|
||||
gl.stepunit(8, 6)
|
||||
gl.winconstraints()
|
||||
x, y = gl.getsize()
|
||||
print x, 'x', y
|
||||
|
||||
v.SetSize(x, y)
|
||||
|
||||
if drop:
|
||||
param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF]
|
||||
else:
|
||||
param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON]
|
||||
if mono or grey:
|
||||
param = param+[SV.COLOR, SV.MONO, SV.DITHER, 0, \
|
||||
SV.INPUT_BYPASS, 1]
|
||||
else:
|
||||
param = param+[SV.COLOR, SV.DEFAULT_COLOR, SV.INPUT_BYPASS, 0]
|
||||
|
||||
v.BindGLWindow(win, SV.IN_REPLACE)
|
||||
v.SetParam(param)
|
||||
|
||||
gl.qdevice(DEVICE.LEFTMOUSE)
|
||||
gl.qdevice(DEVICE.WINQUIT)
|
||||
gl.qdevice(DEVICE.WINSHUT)
|
||||
gl.qdevice(DEVICE.ESCKEY)
|
||||
|
||||
help()
|
||||
|
||||
while 1:
|
||||
dev, val = gl.qread()
|
||||
if dev == DEVICE.LEFTMOUSE:
|
||||
if val == 1:
|
||||
info = format, x, y, qsize, rate
|
||||
record(v, info, filename, audiofilename,\
|
||||
mono, grey, greybits, monotreshold, \
|
||||
fields, preallocspace)
|
||||
elif dev == DEVICE.REDRAW:
|
||||
# Window resize (or move)
|
||||
x, y = gl.getsize()
|
||||
print x, 'x', y
|
||||
v.SetSize(x, y)
|
||||
v.BindGLWindow(win, SV.IN_REPLACE)
|
||||
elif dev in (DEVICE.ESCKEY, DEVICE.WINQUIT, DEVICE.WINSHUT):
|
||||
# Quit
|
||||
v.CloseVideo()
|
||||
gl.winclose(win)
|
||||
break
|
||||
|
||||
|
||||
# Record until the mouse is released (or any other GL event)
|
||||
# XXX audio not yet supported
|
||||
|
||||
def record(v, info, filename, audiofilename, mono, grey, greybits, \
|
||||
monotreshold, fields, preallocspace):
|
||||
import thread
|
||||
format, x, y, qsize, rate = info
|
||||
fps = 59.64 # Fields per second
|
||||
# XXX (Strange: need fps of Indigo monitor, not of PAL or NTSC!)
|
||||
tpf = 1000.0 / fps # Time per field in msec
|
||||
if filename:
|
||||
vout = VFile.VoutFile(filename)
|
||||
if mono:
|
||||
format = 'mono'
|
||||
elif grey and greybits == 8:
|
||||
format = 'grey'
|
||||
elif grey:
|
||||
format = 'grey'+`abs(greybits)`
|
||||
else:
|
||||
format = 'rgb8'
|
||||
vout.setformat(format)
|
||||
vout.setsize(x, y)
|
||||
if fields:
|
||||
vout.setpf((1, -2))
|
||||
vout.writeheader()
|
||||
if preallocspace:
|
||||
print 'Preallocating space...'
|
||||
vout.prealloc(preallocspace)
|
||||
print 'done.'
|
||||
MAXSIZE = 20 # XXX should be a user option
|
||||
import Queue
|
||||
queue = Queue.Queue(MAXSIZE)
|
||||
done = thread.allocate_lock()
|
||||
done.acquire_lock()
|
||||
convertor = None
|
||||
if grey:
|
||||
if greybits == 2:
|
||||
convertor = imageop.grey2grey2
|
||||
elif greybits == 4:
|
||||
convertor = imageop.grey2grey4
|
||||
elif greybits == -2:
|
||||
convertor = imageop.dither2grey2
|
||||
thread.start_new_thread(saveframes, \
|
||||
(vout, queue, done, mono, monotreshold, convertor))
|
||||
if audiofilename:
|
||||
audiodone = thread.allocate_lock()
|
||||
audiodone.acquire_lock()
|
||||
audiostop = []
|
||||
initaudio(audiofilename, audiostop, audiodone)
|
||||
gl.wintitle('(rec) ' + filename)
|
||||
lastid = 0
|
||||
t0 = time.time()
|
||||
count = 0
|
||||
ids = []
|
||||
v.InitContinuousCapture(info)
|
||||
while not gl.qtest():
|
||||
try:
|
||||
cd, id = v.GetCaptureData()
|
||||
except sv.error:
|
||||
#time.sleep(0.010) # XXX is this necessary?
|
||||
sgi.nap(1) # XXX Try by Jack
|
||||
continue
|
||||
ids.append(id)
|
||||
|
||||
id = id + 2*rate
|
||||
## if id <> lastid + 2*rate:
|
||||
## print lastid, id
|
||||
lastid = id
|
||||
count = count+1
|
||||
if fields:
|
||||
data1, data2 = cd.GetFields()
|
||||
cd.UnlockCaptureData()
|
||||
if filename:
|
||||
queue.put((data1, int(id*tpf)))
|
||||
queue.put((data2, int((id+1)*tpf)))
|
||||
else:
|
||||
data = cd.InterleaveFields(1)
|
||||
cd.UnlockCaptureData()
|
||||
if filename:
|
||||
queue.put((data, int(id*tpf)))
|
||||
t1 = time.time()
|
||||
gl.wintitle('(busy) ' + filename)
|
||||
print lastid, 'fields in', round(t1-t0, 3), 'sec',
|
||||
print '--', round(lastid/(t1-t0), 1), 'fields/sec'
|
||||
print 'Captured',count*2, 'fields,',
|
||||
print round(count*2/(t1-t0), 1), 'f/s',
|
||||
if lastid:
|
||||
print '(',
|
||||
print round(count*200.0/lastid), '%, or',
|
||||
print round(count*rate*200.0/lastid), '% of wanted rate )',
|
||||
print
|
||||
if ids:
|
||||
print 'Ids:',
|
||||
t0 = ids[0]
|
||||
del ids[0]
|
||||
for t1 in ids:
|
||||
print t1-t0,
|
||||
t0 = t1
|
||||
print
|
||||
if filename and audiofilename:
|
||||
audiostop.append(None)
|
||||
audiodone.acquire_lock()
|
||||
v.EndContinuousCapture()
|
||||
if filename:
|
||||
queue.put(None) # Sentinel
|
||||
done.acquire_lock()
|
||||
gl.wintitle('(done) ' + filename)
|
||||
|
||||
|
||||
# Thread to save the frames to the file
|
||||
|
||||
def saveframes(vout, queue, done, mono, monotreshold, convertor):
|
||||
while 1:
|
||||
x = queue.get()
|
||||
if not x:
|
||||
break
|
||||
data, t = x
|
||||
if convertor:
|
||||
data = convertor(data, len(data), 1)
|
||||
elif mono and monotreshold >= 0:
|
||||
data = imageop.grey2mono(data, len(data), 1,\
|
||||
monotreshold)
|
||||
elif mono:
|
||||
data = imageop.dither2mono(data, len(data), 1)
|
||||
vout.writeframe(t, data, None)
|
||||
sys.stderr.write('Done writing video\n')
|
||||
vout.close()
|
||||
done.release_lock()
|
||||
|
||||
|
||||
# Initialize audio recording
|
||||
|
||||
AQSIZE = 8000 # XXX should be a user option
|
||||
|
||||
def initaudio(filename, stop, done):
|
||||
import thread, aifc
|
||||
afile = aifc.open(filename, 'w')
|
||||
afile.setnchannels(AL.MONO)
|
||||
afile.setsampwidth(AL.SAMPLE_8)
|
||||
params = [AL.INPUT_RATE, 0]
|
||||
al.getparams(AL.DEFAULT_DEVICE, params)
|
||||
print 'audio sampling rate =', params[1]
|
||||
afile.setframerate(params[1])
|
||||
c = al.newconfig()
|
||||
c.setchannels(AL.MONO)
|
||||
c.setqueuesize(AQSIZE)
|
||||
c.setwidth(AL.SAMPLE_8)
|
||||
aport = al.openport(filename, 'r', c)
|
||||
thread.start_new_thread(audiorecord, (afile, aport, stop, done))
|
||||
|
||||
|
||||
# Thread to record audio samples
|
||||
|
||||
def audiorecord(afile, aport, stop, done):
|
||||
while not stop:
|
||||
data = aport.readsamps(AQSIZE/2)
|
||||
afile.writesampsraw(data)
|
||||
del data
|
||||
afile.close()
|
||||
print 'Done writing audio'
|
||||
done.release_lock()
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
|
@ -1,429 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Capture a CMIF movie using the Indigo video library and board in burst mode
|
||||
|
||||
|
||||
# User interface:
|
||||
#
|
||||
# Start the application. Resize the window to the desired movie size.
|
||||
# Press the left mouse button to start recording, release it to end
|
||||
# recording. You can record as many times as you wish, but each time
|
||||
# you overwrite the output file(s), so only the last recording is
|
||||
# kept.
|
||||
#
|
||||
# Press ESC or select the window manager Quit or Close window option
|
||||
# to quit. If you quit before recording anything, the output file(s)
|
||||
# are not touched.
|
||||
|
||||
|
||||
import sys
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import sv, SV
|
||||
import VFile
|
||||
import gl, GL, DEVICE
|
||||
import al, AL
|
||||
import time
|
||||
import posix
|
||||
import getopt
|
||||
import string
|
||||
import imageop
|
||||
import sgi
|
||||
|
||||
|
||||
# Usage and help functions (keep this up-to-date if you change the program!)
|
||||
|
||||
def usage():
|
||||
print 'Usage: Vrecb [options] [moviefile [audiofile]]'
|
||||
print
|
||||
print 'Options:'
|
||||
print '-a : record audio as well'
|
||||
print '-r rate : capture 1 out of every "rate" frames', \
|
||||
'(default and min 1)'
|
||||
print '-w width : initial window width', \
|
||||
'(default 256, use 0 for interactive placement)'
|
||||
print '-d : drop fields if needed'
|
||||
print '-g bits : greyscale (2, 4 or 8 bits)'
|
||||
print '-G : 2-bit greyscale dithered'
|
||||
print '-m : monochrome dithered'
|
||||
print '-M value : monochrome thresholded with value'
|
||||
print '-f : Capture fields (instead of frames)'
|
||||
print '-n number : Capture this many frames (default 60)'
|
||||
print '-N memsize : Capture frames fitting in this many kbytes'
|
||||
print 'moviefile : here goes the movie data (default film.video)'
|
||||
|
||||
def help():
|
||||
print 'Press the left mouse button to start recording.'
|
||||
print 'Recording time is determined by the -n option.'
|
||||
print 'You can record as many times as you wish, but each'
|
||||
print 'recording overwrites the output file(s) -- only the'
|
||||
print 'last recording is kept.'
|
||||
print
|
||||
print 'Press ESC or use the window manager Quit or Close window option'
|
||||
print 'to quit. If you quit before recording anything, the output'
|
||||
print 'file(s) are not touched.'
|
||||
|
||||
|
||||
# Main program
|
||||
|
||||
def main():
|
||||
format = SV.RGB8_FRAMES
|
||||
audio = 0
|
||||
rate = 1
|
||||
width = 256
|
||||
drop = 0
|
||||
mono = 0
|
||||
grey = 0
|
||||
greybits = 0
|
||||
monotreshold = -1
|
||||
fields = 0
|
||||
number = 0
|
||||
memsize = 0
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'ar:w:dg:mM:Gfn:N:')
|
||||
except getopt.error, msg:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Error:', msg, '\n'
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
try:
|
||||
for opt, arg in opts:
|
||||
if opt == '-a':
|
||||
audio = 1
|
||||
if opt == '-r':
|
||||
rate = string.atoi(arg)
|
||||
if rate < 1:
|
||||
sys.stderr.write('-r rate must be >= 1\n')
|
||||
sys.exit(2)
|
||||
elif opt == '-w':
|
||||
width = string.atoi(arg)
|
||||
elif opt == '-d':
|
||||
drop = 1
|
||||
elif opt == '-g':
|
||||
grey = 1
|
||||
greybits = string.atoi(arg)
|
||||
if not greybits in (2,4,8):
|
||||
sys.stderr.write( \
|
||||
'Only 2, 4 or 8 bit greyscale supported\n')
|
||||
sys.exit(2)
|
||||
elif opt == '-G':
|
||||
grey = 1
|
||||
greybits = -2
|
||||
elif opt == '-m':
|
||||
mono = 1
|
||||
elif opt == '-M':
|
||||
mono = 1
|
||||
monotreshold = string.atoi(arg)
|
||||
elif opt == '-f':
|
||||
fields = 1
|
||||
elif opt == '-n':
|
||||
number = string.atoi(arg)
|
||||
elif opt == '-N':
|
||||
memsize = string.atoi(arg)
|
||||
if 0 < memsize < 1024:
|
||||
memsize = memsize * 1024
|
||||
if 0 < memsize < 1024*1024:
|
||||
memsize = memsize * 1024
|
||||
print 'memsize', memsize
|
||||
except string.atoi_error:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Option', opt, 'requires integer argument'
|
||||
sys.exit(2)
|
||||
|
||||
if number <> 0 and memsize <> 0:
|
||||
sys.stderr.write('-n and -N are mutually exclusive\n')
|
||||
sys.exit(2)
|
||||
if number == 0 and memsize == 0:
|
||||
number = 60
|
||||
|
||||
if not fields:
|
||||
print '-f option assumed until somebody fixes it'
|
||||
fields = 1
|
||||
|
||||
if args[2:]:
|
||||
sys.stderr.write('usage: Vrecb [options] [file [audiofile]]\n')
|
||||
sys.exit(2)
|
||||
|
||||
if args:
|
||||
filename = args[0]
|
||||
else:
|
||||
filename = 'film.video'
|
||||
|
||||
if args[1:] and not audio:
|
||||
sys.stderr.write('-a turned on by appearance of 2nd file\n')
|
||||
audio = 1
|
||||
|
||||
if audio:
|
||||
if args[1:]:
|
||||
audiofilename = args[1]
|
||||
else:
|
||||
audiofilename = 'film.aiff'
|
||||
else:
|
||||
audiofilename = None
|
||||
|
||||
v = sv.OpenVideo()
|
||||
# Determine maximum window size based on signal standard
|
||||
param = [SV.BROADCAST, 0]
|
||||
v.GetParam(param)
|
||||
if param[1] == SV.PAL:
|
||||
x = SV.PAL_XMAX
|
||||
y = SV.PAL_YMAX
|
||||
elif param[1] == SV.NTSC:
|
||||
x = SV.NTSC_XMAX
|
||||
y = SV.NTSC_YMAX
|
||||
else:
|
||||
print 'Unknown video standard', param[1]
|
||||
sys.exit(1)
|
||||
|
||||
gl.foreground()
|
||||
gl.maxsize(x, y)
|
||||
gl.keepaspect(x, y)
|
||||
gl.stepunit(8, 6)
|
||||
if width:
|
||||
height = width*3/4
|
||||
x1 = 150
|
||||
x2 = x1 + width-1
|
||||
y2 = 768-150
|
||||
y1 = y2-height+1
|
||||
gl.prefposition(x1, x2, y1, y2)
|
||||
win = gl.winopen(filename)
|
||||
if width:
|
||||
gl.maxsize(x, y)
|
||||
gl.keepaspect(x, y)
|
||||
gl.stepunit(8, 6)
|
||||
gl.winconstraints()
|
||||
x, y = gl.getsize()
|
||||
print x, 'x', y
|
||||
if memsize:
|
||||
number = calcnumber(x, y, grey or mono, memsize)
|
||||
print number, 'frames'
|
||||
v.SetSize(x, y)
|
||||
|
||||
if drop:
|
||||
param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF]
|
||||
else:
|
||||
param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON]
|
||||
if mono or grey:
|
||||
param = param+[SV.COLOR, SV.MONO, SV.DITHER, 0, \
|
||||
SV.INPUT_BYPASS, 1]
|
||||
else:
|
||||
param = param+[SV.COLOR, SV.DEFAULT_COLOR, SV.INPUT_BYPASS, 0]
|
||||
|
||||
v.BindGLWindow(win, SV.IN_REPLACE)
|
||||
v.SetParam(param)
|
||||
|
||||
gl.qdevice(DEVICE.LEFTMOUSE)
|
||||
gl.qdevice(DEVICE.WINQUIT)
|
||||
gl.qdevice(DEVICE.WINSHUT)
|
||||
gl.qdevice(DEVICE.ESCKEY)
|
||||
|
||||
help()
|
||||
|
||||
while 1:
|
||||
dev, val = gl.qread()
|
||||
if dev == DEVICE.LEFTMOUSE:
|
||||
if val == 1:
|
||||
info = format, x, y, number, rate
|
||||
record(v, info, filename, audiofilename, \
|
||||
mono, grey, \
|
||||
greybits, monotreshold, fields)
|
||||
elif dev == DEVICE.REDRAW:
|
||||
# Window resize (or move)
|
||||
x, y = gl.getsize()
|
||||
print x, 'x', y
|
||||
if memsize:
|
||||
number = calcnumber(x, y, grey or mono, memsize)
|
||||
print number, 'frames'
|
||||
v.SetSize(x, y)
|
||||
v.BindGLWindow(win, SV.IN_REPLACE)
|
||||
elif dev in (DEVICE.ESCKEY, DEVICE.WINQUIT, DEVICE.WINSHUT):
|
||||
# Quit
|
||||
v.CloseVideo()
|
||||
gl.winclose(win)
|
||||
break
|
||||
|
||||
|
||||
def calcnumber(x, y, grey, memsize):
|
||||
pixels = x*y
|
||||
pixels = pixels/2 # XXX always assume fields
|
||||
if grey: n = memsize/pixels
|
||||
else: n = memsize/(4*pixels)
|
||||
return max(1, n)
|
||||
|
||||
|
||||
# Record until the mouse is released (or any other GL event)
|
||||
# XXX audio not yet supported
|
||||
|
||||
def record(v, info, filename, audiofilename, \
|
||||
mono, grey, greybits, monotreshold, fields):
|
||||
import thread
|
||||
format, x, y, number, rate = info
|
||||
fps = 59.64 # Fields per second
|
||||
# XXX (Strange: need fps of Indigo monitor, not of PAL or NTSC!)
|
||||
tpf = 1000.0 / fps # Time per field in msec
|
||||
#
|
||||
# Go grab
|
||||
#
|
||||
if audiofilename:
|
||||
gl.wintitle('(start audio) ' + filename)
|
||||
audiodone = thread.allocate_lock()
|
||||
audiodone.acquire_lock()
|
||||
audiostart = thread.allocate_lock()
|
||||
audiostart.acquire_lock()
|
||||
audiostop = []
|
||||
initaudio(audiofilename, audiostop, audiostart, audiodone)
|
||||
audiostart.acquire_lock()
|
||||
gl.wintitle('(rec) ' + filename)
|
||||
try:
|
||||
ninfo, data, bitvec = v.CaptureBurst(info)
|
||||
except sv.error, arg:
|
||||
print 'CaptureBurst failed:', arg
|
||||
print 'info:', info
|
||||
gl.wintitle(filename)
|
||||
return
|
||||
gl.wintitle('(save) '+ filename)
|
||||
#
|
||||
# Check results
|
||||
#
|
||||
if info <> ninfo:
|
||||
print 'Sorry, format changed.'
|
||||
print 'Wanted:',info
|
||||
print 'Got :',ninfo
|
||||
gl.wintitle(filename)
|
||||
return
|
||||
# print bitvec
|
||||
if x*y*number <> len(data):
|
||||
print 'Funny data length: wanted',x,'*',y,'*', number,'=',\
|
||||
x*y*number,'got',len(data)
|
||||
gl.wintitle(filename)
|
||||
return
|
||||
#
|
||||
# Save
|
||||
#
|
||||
if filename and audiofilename:
|
||||
audiostop.append(None)
|
||||
audiodone.acquire_lock()
|
||||
if filename:
|
||||
#
|
||||
# Construct header and write it
|
||||
#
|
||||
try:
|
||||
vout = VFile.VoutFile(filename)
|
||||
except IOError, msg:
|
||||
print filename, ':', msg
|
||||
sys.exit(1)
|
||||
if mono:
|
||||
vout.format = 'mono'
|
||||
elif grey and greybits == 8:
|
||||
vout.format = 'grey'
|
||||
elif grey:
|
||||
vout.format = 'grey'+`abs(greybits)`
|
||||
else:
|
||||
vout.format = 'rgb8'
|
||||
vout.width = x
|
||||
vout.height = y
|
||||
if fields:
|
||||
vout.packfactor = (1,-2)
|
||||
else:
|
||||
print 'Sorry, can only save fields at the moment'
|
||||
print '(i.e. you *must* use the -f option)'
|
||||
gl.wintitle(filename)
|
||||
return
|
||||
vout.writeheader()
|
||||
#
|
||||
# Compute convertor, if needed
|
||||
#
|
||||
convertor = None
|
||||
if grey:
|
||||
if greybits == 2:
|
||||
convertor = imageop.grey2grey2
|
||||
elif greybits == 4:
|
||||
convertor = imageop.grey2grey4
|
||||
elif greybits == -2:
|
||||
convertor = imageop.dither2grey2
|
||||
fieldsize = x*y/2
|
||||
nskipped = 0
|
||||
realframeno = 0
|
||||
tpf = 1000 / 50.0 #XXXX
|
||||
# Trying to find the pattern in frame skipping
|
||||
okstretch = 0
|
||||
skipstretch = 0
|
||||
for frameno in range(0, number*2):
|
||||
if frameno <> 0 and \
|
||||
bitvec[frameno] == bitvec[frameno-1]:
|
||||
nskipped = nskipped + 1
|
||||
if okstretch:
|
||||
print okstretch, 'ok',
|
||||
okstretch = 0
|
||||
skipstretch = skipstretch + 1
|
||||
continue
|
||||
if skipstretch:
|
||||
print skipstretch, 'skipped'
|
||||
skipstretch = 0
|
||||
okstretch = okstretch + 1
|
||||
#
|
||||
# Save field.
|
||||
# XXXX Works only for fields and top-to-bottom
|
||||
#
|
||||
start = frameno*fieldsize
|
||||
field = data[start:start+fieldsize]
|
||||
if convertor:
|
||||
field = convertor(field, len(field), 1)
|
||||
elif mono and monotreshold >= 0:
|
||||
field = imageop.grey2mono( \
|
||||
field, len(field), 1, monotreshold)
|
||||
elif mono:
|
||||
field = imageop.dither2mono( \
|
||||
field, len(field), 1)
|
||||
realframeno = realframeno + 1
|
||||
vout.writeframe(int(realframeno*tpf), field, None)
|
||||
print okstretch, 'ok',
|
||||
print skipstretch, 'skipped'
|
||||
print 'Skipped', nskipped, 'duplicate frames'
|
||||
vout.close()
|
||||
|
||||
gl.wintitle('(done) ' + filename)
|
||||
# Initialize audio recording
|
||||
|
||||
AQSIZE = 8*8000 # XXX should be a user option
|
||||
|
||||
def initaudio(filename, stop, start, done):
|
||||
import thread, aifc
|
||||
afile = aifc.open(filename, 'w')
|
||||
afile.setnchannels(AL.MONO)
|
||||
afile.setsampwidth(AL.SAMPLE_8)
|
||||
params = [AL.INPUT_RATE, 0]
|
||||
al.getparams(AL.DEFAULT_DEVICE, params)
|
||||
print 'audio sampling rate =', params[1]
|
||||
afile.setframerate(params[1])
|
||||
c = al.newconfig()
|
||||
c.setchannels(AL.MONO)
|
||||
c.setqueuesize(AQSIZE)
|
||||
c.setwidth(AL.SAMPLE_8)
|
||||
aport = al.openport(filename, 'r', c)
|
||||
thread.start_new_thread(audiorecord, (afile, aport, stop, start, done))
|
||||
|
||||
|
||||
# Thread to record audio samples
|
||||
|
||||
def audiorecord(afile, aport, stop, start, done):
|
||||
start.release_lock()
|
||||
leeway = 4
|
||||
while leeway > 0:
|
||||
if stop:
|
||||
leeway = leeway - 1
|
||||
data = aport.readsamps(AQSIZE/8)
|
||||
afile.writesampsraw(data)
|
||||
del data
|
||||
afile.close()
|
||||
print 'Done writing audio'
|
||||
done.release_lock()
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
|
@ -1,135 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Receive live video UDP packets.
|
||||
# Usage: Vreceive [port]
|
||||
|
||||
import sys
|
||||
import struct
|
||||
from socket import * # syscalls and support functions
|
||||
from SOCKET import * # <sys/socket.h>
|
||||
from IN import * # <netinet/in.h>
|
||||
import select
|
||||
import struct
|
||||
import gl, GL, DEVICE
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import LiveVideoOut
|
||||
import regsub
|
||||
import getopt
|
||||
|
||||
from senddefs import *
|
||||
|
||||
|
||||
# Print usage message and exit(2).
|
||||
|
||||
def usage(msg):
|
||||
print msg
|
||||
print 'usage: Vreceive [-m mcastgrp] [-p port] [-c type]'
|
||||
print '-m mcastgrp: multicast group (default ' + `DEFMCAST` + ')'
|
||||
print '-p port : port (default ' + `DEFPORT` + ')'
|
||||
print '-c type : signal type: rgb8, grey or mono (default rgb8)'
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
# Main program: parse options and main loop.
|
||||
|
||||
def main():
|
||||
|
||||
sys.stdout = sys.stderr
|
||||
|
||||
group = DEFMCAST
|
||||
port = DEFPORT
|
||||
width = DEFWIDTH
|
||||
height = DEFHEIGHT
|
||||
vtype = 'rgb8'
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'm:p:c:')
|
||||
except getopt.error, msg:
|
||||
usage(msg)
|
||||
|
||||
try:
|
||||
for opt, optarg in opts:
|
||||
if opt == '-p':
|
||||
port = string.atoi(optarg)
|
||||
if opt == '-m':
|
||||
group = gethostbyname(optarg)
|
||||
if opt == '-c':
|
||||
vtype = optarg
|
||||
except string.atoi_error, msg:
|
||||
usage('bad integer: ' + msg)
|
||||
|
||||
s = opensocket(group, port)
|
||||
|
||||
gl.foreground()
|
||||
gl.prefsize(width, height)
|
||||
wid = gl.winopen('Vreceive')
|
||||
gl.winconstraints()
|
||||
gl.qdevice(DEVICE.ESCKEY)
|
||||
gl.qdevice(DEVICE.WINSHUT)
|
||||
gl.qdevice(DEVICE.WINQUIT)
|
||||
|
||||
lvo = LiveVideoOut.LiveVideoOut(wid, width, height, vtype)
|
||||
|
||||
ifdlist = [gl.qgetfd(), s.fileno()]
|
||||
ofdlist = []
|
||||
xfdlist = []
|
||||
timeout = 1.0
|
||||
selectargs = (ifdlist, ofdlist, xfdlist, timeout)
|
||||
|
||||
while 1:
|
||||
|
||||
if gl.qtest():
|
||||
dev, val = gl.qread()
|
||||
if dev in (DEVICE.ESCKEY, \
|
||||
DEVICE.WINSHUT, DEVICE.WINQUIT):
|
||||
break
|
||||
if dev == DEVICE.REDRAW:
|
||||
lvo.reshapewindow()
|
||||
elif s.avail():
|
||||
data = s.recv(16*1024)
|
||||
pos, w, h = struct.unpack('hhh', data[:6])
|
||||
if (w, h) <> (width, height):
|
||||
x, y = gl.getorigin()
|
||||
y = y + height - h
|
||||
gl.winposition(x, x+w-1, y, y+h-1)
|
||||
width, height = w, h
|
||||
lvo.resizevideo(width, height)
|
||||
lvo.putnextpacket(pos, data[6:])
|
||||
else:
|
||||
x = select.select(selectargs)
|
||||
|
||||
lvo.close()
|
||||
|
||||
|
||||
# Subroutine to create and properly initialize the receiving socket
|
||||
|
||||
def opensocket(group, port):
|
||||
|
||||
# Create the socket
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
|
||||
# Allow multiple copies of this program on one machine
|
||||
s.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1) # (Not strictly needed)
|
||||
|
||||
# Bind the port to it
|
||||
s.bind('', port)
|
||||
|
||||
# Look up the group once
|
||||
group = gethostbyname(group)
|
||||
|
||||
# Construct binary group address
|
||||
group_bytes = eval(regsub.gsub('\.', ',', group))
|
||||
grpaddr = 0
|
||||
for byte in group_bytes: grpaddr = (grpaddr << 8) | byte
|
||||
|
||||
# Construct struct mreq from grpaddr and ifaddr
|
||||
ifaddr = INADDR_ANY
|
||||
mreq = struct.pack('ll', grpaddr, ifaddr)
|
||||
|
||||
# Add group membership
|
||||
s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
|
||||
|
||||
return s
|
||||
|
||||
|
||||
main()
|
|
@ -1,152 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Send live video UDP packets.
|
||||
# Usage: Vsend [-b] [-h height] [-p port] [-s size] [-t ttl] [-w width]
|
||||
# [host] ..
|
||||
|
||||
import sys
|
||||
import time
|
||||
import struct
|
||||
import string
|
||||
from socket import *
|
||||
from SOCKET import *
|
||||
import gl, GL, DEVICE
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import LiveVideoIn
|
||||
import LiveVideoOut
|
||||
import SV
|
||||
import getopt
|
||||
from IN import *
|
||||
|
||||
from senddefs import *
|
||||
|
||||
def usage(msg):
|
||||
print msg
|
||||
print 'usage: Vsend [-b] [-h height] [-p port] [-s size] [-t ttl] [-c type] [-m]',
|
||||
print '[-w width] [host] ...'
|
||||
print '-b : broadcast on local net'
|
||||
print '-h height : window height (default ' + `DEFHEIGHT` + ')'
|
||||
print '-p port : port to use (default ' + `DEFPORT` + ')'
|
||||
print '-t ttl : time-to-live (multicast only; default 1)'
|
||||
print '-s size : max packet size (default ' + `DEFPKTMAX` + ')'
|
||||
print '-w width : window width (default ' + `DEFWIDTH` + ')'
|
||||
print '-c type : Type: rgb8, mono or grey (default rgb8)'
|
||||
print '[host] ...: host(s) to send to (default multicast to ' + \
|
||||
DEFMCAST + ')'
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def main():
|
||||
sys.stdout = sys.stderr
|
||||
|
||||
hosts = []
|
||||
port = DEFPORT
|
||||
ttl = -1
|
||||
pktmax = DEFPKTMAX
|
||||
width = DEFWIDTH
|
||||
height = DEFHEIGHT
|
||||
vtype = 'rgb8'
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'bh:p:s:t:w:c:')
|
||||
except getopt.error, msg:
|
||||
usage(msg)
|
||||
|
||||
try:
|
||||
for opt, optarg in opts:
|
||||
if opt == '-p':
|
||||
port = string.atoi(optarg)
|
||||
if opt == '-b':
|
||||
host = '<broadcast>'
|
||||
if opt == '-t':
|
||||
ttl = string.atoi(optarg)
|
||||
if opt == '-s':
|
||||
pktmax = string.atoi(optarg)
|
||||
if opt == '-w':
|
||||
width = string.atoi(optarg)
|
||||
if opt == '-h':
|
||||
height = string.atoi(optarg)
|
||||
if opt == '-c':
|
||||
vtype = optarg
|
||||
except string.atoi_error, msg:
|
||||
usage('bad integer: ' + msg)
|
||||
|
||||
for host in args:
|
||||
hosts.append(gethostbyname(host))
|
||||
|
||||
if not hosts:
|
||||
hosts.append(gethostbyname(DEFMCAST))
|
||||
|
||||
if not LiveVideoIn.have_video:
|
||||
print 'Sorry, no video available (use python-405)'
|
||||
sys.exit(1)
|
||||
|
||||
gl.foreground()
|
||||
gl.prefsize(width, height)
|
||||
gl.stepunit(8, 6)
|
||||
wid = gl.winopen('Vsend')
|
||||
gl.keepaspect(width, height)
|
||||
gl.stepunit(8, 6)
|
||||
gl.maxsize(SV.PAL_XMAX, SV.PAL_YMAX)
|
||||
gl.winconstraints()
|
||||
gl.qdevice(DEVICE.ESCKEY)
|
||||
gl.qdevice(DEVICE.WINSHUT)
|
||||
gl.qdevice(DEVICE.WINQUIT)
|
||||
gl.qdevice(DEVICE.WINFREEZE)
|
||||
gl.qdevice(DEVICE.WINTHAW)
|
||||
width, height = gl.getsize()
|
||||
|
||||
lvo = LiveVideoOut.LiveVideoOut(wid, width, height, vtype)
|
||||
|
||||
lvi = LiveVideoIn.LiveVideoIn(pktmax, width, height, vtype)
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
||||
if ttl >= 0:
|
||||
s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, chr(ttl))
|
||||
|
||||
frozen = 0
|
||||
|
||||
while 1:
|
||||
|
||||
if gl.qtest():
|
||||
dev, val = gl.qread()
|
||||
if dev in (DEVICE.ESCKEY, \
|
||||
DEVICE.WINSHUT, DEVICE.WINQUIT):
|
||||
break
|
||||
if dev == DEVICE.WINFREEZE:
|
||||
frozen = 1
|
||||
if dev == DEVICE.WINTHAW:
|
||||
frozen = 0
|
||||
if dev == DEVICE.REDRAW:
|
||||
w, h = gl.getsize()
|
||||
x, y = gl.getorigin()
|
||||
if (w, h) <> (width, height):
|
||||
width, height = w, h
|
||||
lvi.resizevideo(width, height)
|
||||
lvo.resizevideo(width, height)
|
||||
|
||||
rv = lvi.getnextpacket()
|
||||
if not rv:
|
||||
time.sleep(0.010)
|
||||
continue
|
||||
|
||||
pos, data = rv
|
||||
|
||||
if not frozen:
|
||||
lvo.putnextpacket(pos, data)
|
||||
|
||||
hdr = struct.pack('hhh', pos, width, height)
|
||||
for host in hosts:
|
||||
try:
|
||||
s.sendto(hdr + data, (host, port))
|
||||
except error, msg: # really socket.error
|
||||
if msg[0] <> 121: # no buffer space available
|
||||
raise error, msg # re-raise it
|
||||
print 'Warning:', msg[1]
|
||||
|
||||
lvi.close()
|
||||
lvo.close()
|
||||
|
||||
|
||||
main()
|
|
@ -1,23 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Print the value of all video parameters
|
||||
|
||||
import sys
|
||||
import sv, SV
|
||||
|
||||
def main():
|
||||
v = sv.OpenVideo()
|
||||
for name in dir(SV):
|
||||
const = getattr(SV, name)
|
||||
if type(const) is type(0):
|
||||
sys.stdout.flush()
|
||||
params = [const, 0]
|
||||
try:
|
||||
v.GetParam(params)
|
||||
except sv.error, msg:
|
||||
## print name, msg
|
||||
continue
|
||||
print name, params
|
||||
|
||||
main()
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Manipulate the time base of CMIF movies
|
||||
|
||||
|
||||
# Possibilities:
|
||||
#
|
||||
# - resample at a fixed rate
|
||||
# - divide the time codes by a speed factor (to make it go faster/slower)
|
||||
# - drop frames that are less than n msec apart (to accommodate slow players)
|
||||
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# Vtime [-m msec] [-r msec] [-s speed] [infile [outfile]]
|
||||
|
||||
|
||||
# Options:
|
||||
#
|
||||
# -m n : drop frames closer than n msec (default 0)
|
||||
# -r n : regenerate input time base n msec apart
|
||||
# -s speed : speed change factor after other processing (default 1.0)
|
||||
# infile : input file (default film.video)
|
||||
# outfile : output file (default out.video)
|
||||
|
||||
|
||||
import sys
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import VFile
|
||||
import getopt
|
||||
import string
|
||||
|
||||
|
||||
# Global options
|
||||
|
||||
speed = 1.0
|
||||
mindelta = 0
|
||||
regen = None
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
global speed, mindelta
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'm:r:s:')
|
||||
for opt, arg in opts:
|
||||
if opt == '-m':
|
||||
mindelta = string.atoi(arg)
|
||||
elif opt == '-r':
|
||||
regen = string.atoi(arg)
|
||||
elif opt == '-s':
|
||||
speed = float(eval(arg))
|
||||
if len(args) < 1:
|
||||
args.append('film.video')
|
||||
if len(args) < 2:
|
||||
args.append('out.video')
|
||||
if len(args) > 2:
|
||||
sys.stderr.write('usage: Vtime [options] [infile [outfile]]\n')
|
||||
sys.exit(2)
|
||||
sts = process(args[0], args[1])
|
||||
sys.exit(sts)
|
||||
|
||||
|
||||
# Copy one file to another
|
||||
|
||||
def process(infilename, outfilename):
|
||||
try:
|
||||
vin = VFile.BasicVinFile(infilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
except VFile.Error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
return 1
|
||||
except EOFError:
|
||||
sys.stderr.write(infilename + ': EOF in video file\n')
|
||||
return 1
|
||||
|
||||
try:
|
||||
vout = VFile.BasicVoutFile(outfilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
|
||||
vout.setinfo(vin.getinfo())
|
||||
vout.writeheader()
|
||||
|
||||
told = 0
|
||||
nin = 0
|
||||
nout = 0
|
||||
tin = 0
|
||||
tout = 0
|
||||
|
||||
while 1:
|
||||
try:
|
||||
tin, data, cdata = vin.getnextframe()
|
||||
except EOFError:
|
||||
break
|
||||
nin = nin + 1
|
||||
if regen:
|
||||
tout = nin * regen
|
||||
else:
|
||||
tout = tin
|
||||
tout = int(tout / speed)
|
||||
if tout - told < mindelta:
|
||||
continue
|
||||
told = tout
|
||||
vout.writeframe(tout, data, cdata)
|
||||
nout = nout + 1
|
||||
|
||||
vout.close()
|
||||
vin.close()
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
main()
|
|
@ -1,97 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Decompress a jpeg or jpeggrey video file to rgb format
|
||||
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# Vunjpeg [infile [outfile]]
|
||||
|
||||
|
||||
# Options:
|
||||
#
|
||||
# infile : input file (default film.video)
|
||||
# outfile : output file (default out.video)
|
||||
|
||||
|
||||
import sys
|
||||
import jpeg
|
||||
sys.path.append('/ufs/guido/src/video')
|
||||
import VFile
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
if len(args) < 1:
|
||||
args.append('film.video')
|
||||
if len(args) < 2:
|
||||
args.append('out.video')
|
||||
if len(args) > 2:
|
||||
sys.stderr.write('usage: Vunjpeg [infile [outfile]]\n')
|
||||
sys.exit(2)
|
||||
sts = process(args[0], args[1])
|
||||
sys.exit(sts)
|
||||
|
||||
|
||||
# Copy one file to another
|
||||
|
||||
def process(infilename, outfilename):
|
||||
try:
|
||||
vin = VFile.BasicVinFile(infilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
except VFile.Error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
return 1
|
||||
except EOFError:
|
||||
sys.stderr.write(infilename + ': EOF in video file\n')
|
||||
return 1
|
||||
|
||||
try:
|
||||
vout = VFile.BasicVoutFile(outfilename)
|
||||
except IOError, msg:
|
||||
sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n')
|
||||
return 1
|
||||
|
||||
info = vin.getinfo()
|
||||
if info[0] == 'jpeg':
|
||||
format = 'rgb'
|
||||
width, height = vin.getsize()
|
||||
bytes = 4
|
||||
elif info[0] == 'jpeggrey':
|
||||
format = 'grey'
|
||||
width, height = vin.getsize()
|
||||
pf = vin.packfactor
|
||||
width, height = width/pf, height/pf
|
||||
bytes = 1
|
||||
else:
|
||||
sys.stderr.write('Vunjpeg: input not in jpeg[grey] format\n')
|
||||
return 1
|
||||
info = (format,) + info[1:]
|
||||
vout.setinfo(info)
|
||||
vout.writeheader()
|
||||
sts = 0
|
||||
n = 0
|
||||
try:
|
||||
while 1:
|
||||
t, data, cdata = vin.getnextframe()
|
||||
n = n + 1
|
||||
sys.stderr.write('Frame ' + `n` + '...')
|
||||
data, w, h, b = jpeg.decompress(data)
|
||||
if (w, h, b) <> (width, height, bytes):
|
||||
sys.stderr.write('jpeg data has wrong size\n')
|
||||
sts = 1
|
||||
else:
|
||||
vout.writeframe(t, data, None)
|
||||
sys.stderr.write('\n')
|
||||
except EOFError:
|
||||
pass
|
||||
return sts
|
||||
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
main()
|
|
@ -1,167 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Play synchronous video and audio.
|
||||
# Highly experimental!
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
import string
|
||||
import os
|
||||
|
||||
import VFile
|
||||
import aifc
|
||||
|
||||
import gl, GL, DEVICE
|
||||
import al, AL
|
||||
|
||||
|
||||
def usage():
|
||||
sys.stderr.write( \
|
||||
'usage: aplay [-o offset] [-q qsize] videofile audiofile\n')
|
||||
sys.exit(2)
|
||||
|
||||
def main():
|
||||
offset = 0
|
||||
qsize = 0 # This defaults to 1/10 second of sound
|
||||
videofile = 'film.video'
|
||||
audiofile = 'film.aiff'
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'o:q:')
|
||||
except getopt.error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
usage()
|
||||
|
||||
try:
|
||||
for o, a in opts:
|
||||
if o == '-o':
|
||||
offset = string.atoi(a)
|
||||
if o == '-q':
|
||||
qsize = string.atoi(a)
|
||||
except string.atoi_error:
|
||||
sys.stderr.write(o + ' arg must be integer\n')
|
||||
usage()
|
||||
|
||||
if len(args) > 2:
|
||||
usage()
|
||||
|
||||
if args: videofile = args[0]
|
||||
if args[1:]: audiofile = args[1]
|
||||
|
||||
if not os.path.exists(videofile) and \
|
||||
os.path.exists(videofile + '.video'):
|
||||
if not args[1:] and os.path.exists(videofile + '.aiff'):
|
||||
audiofile = videofile + '.aiff'
|
||||
videofile = videofile + '.video'
|
||||
|
||||
print 'Opening video input file..'
|
||||
vin = VFile.VinFile(videofile)
|
||||
|
||||
print 'Opening audio input file..'
|
||||
ain = aifc.open(audiofile, 'r')
|
||||
print 'rate :', ain.getframerate()
|
||||
print 'channels:', ain.getnchannels()
|
||||
print 'frames :', ain.getnframes()
|
||||
print 'width :', ain.getsampwidth()
|
||||
print 'kbytes :', \
|
||||
ain.getnframes() * ain.getnchannels() * ain.getsampwidth()
|
||||
|
||||
print 'Opening audio output port..'
|
||||
c = al.newconfig()
|
||||
c.setchannels(ain.getnchannels())
|
||||
c.setwidth(ain.getsampwidth())
|
||||
nullsample = '\0' * ain.getsampwidth()
|
||||
samples_per_second = ain.getnchannels() * ain.getframerate()
|
||||
if qsize <= 0: qsize = samples_per_second / 10
|
||||
qsize = max(qsize, 512)
|
||||
c.setqueuesize(qsize)
|
||||
saveparams = [AL.OUTPUT_RATE, 0]
|
||||
al.getparams(AL.DEFAULT_DEVICE, saveparams)
|
||||
newparams = [AL.OUTPUT_RATE, ain.getframerate()]
|
||||
al.setparams(AL.DEFAULT_DEVICE, newparams)
|
||||
aport = al.openport(audiofile, 'w', c)
|
||||
|
||||
print 'Opening video output window..'
|
||||
gl.foreground()
|
||||
gl.prefsize(vin.width, vin.height)
|
||||
wid = gl.winopen(videofile + ' + ' + audiofile)
|
||||
gl.clear()
|
||||
vin.initcolormap()
|
||||
|
||||
print 'Playing..'
|
||||
gl.qdevice(DEVICE.ESCKEY)
|
||||
gl.qdevice(DEVICE.LEFTARROWKEY)
|
||||
gl.qdevice(DEVICE.RIGHTARROWKEY)
|
||||
## gl.qdevice(DEVICE.UPARROWKEY)
|
||||
## gl.qdevice(DEVICE.DOWNARROWKEY)
|
||||
gl.qdevice(DEVICE.SPACEKEY)
|
||||
|
||||
while 1:
|
||||
samples_written = 0
|
||||
samples_read = 0
|
||||
lastt = 0
|
||||
pause = 0
|
||||
while 1:
|
||||
if gl.qtest():
|
||||
dev, val = gl.qread()
|
||||
if val == 1:
|
||||
if dev == DEVICE.ESCKEY:
|
||||
sys.exit(0)
|
||||
elif dev == DEVICE.LEFTARROWKEY:
|
||||
offset = offset - 100
|
||||
print 'offset =', offset
|
||||
elif dev == DEVICE.RIGHTARROWKEY:
|
||||
offset = offset + 100
|
||||
print 'offset =', offset
|
||||
elif dev == DEVICE.SPACEKEY:
|
||||
pause = (not pause)
|
||||
|
||||
if pause:
|
||||
continue
|
||||
|
||||
try:
|
||||
t, data, cdata = vin.getnextframe()
|
||||
except EOFError:
|
||||
break
|
||||
t = int(t)
|
||||
dt = t - lastt
|
||||
lastt = t
|
||||
target = samples_per_second * t / 1000
|
||||
n = target - samples_written + qsize - offset
|
||||
if n > 0:
|
||||
# This call will block until the time is right:
|
||||
try:
|
||||
samples = ain.readframes(n)
|
||||
except EOFError:
|
||||
samples = ''
|
||||
k = len(samples) / len(nullsample)
|
||||
samples_read = samples_read + k
|
||||
if k < n:
|
||||
samples = samples + (n-k) * nullsample
|
||||
aport.writesamps(samples)
|
||||
samples_written = samples_written + n
|
||||
vin.showframe(data, cdata)
|
||||
|
||||
while 1:
|
||||
try:
|
||||
samples = ain.readframes(qsize)
|
||||
except EOFError:
|
||||
break
|
||||
if not samples:
|
||||
break
|
||||
aport.writesamps(samples)
|
||||
k = len(samples) / len(nullsample)
|
||||
samples_read = samples_read + k
|
||||
samples_written = samples_written + k
|
||||
|
||||
print samples_read, 'samples ==',
|
||||
print samples_read * 1.0 / samples_per_second, 'sec.'
|
||||
print lastt, 'milliseconds'
|
||||
|
||||
print 'Restarting..'
|
||||
ain.close()
|
||||
ain = aifc.open(audiofile, 'r')
|
||||
vin.rewind()
|
||||
|
||||
|
||||
main()
|
|
@ -1,200 +0,0 @@
|
|||
.de PP
|
||||
.LP
|
||||
..
|
||||
.de pT
|
||||
.IP \fB\\$1\fP
|
||||
..
|
||||
.TL
|
||||
CMIF video file format
|
||||
.AU
|
||||
Jack Jansen
|
||||
(Version of 27-Feb-92)
|
||||
.SH
|
||||
Introduction
|
||||
.PP
|
||||
The CMIF video format was invented to allow various applications
|
||||
to exchange video data. The format consists of
|
||||
a header containing global information (like data format)
|
||||
followed by a sequence of frames, each consisting of a header
|
||||
followed by the actual frame data.
|
||||
All information except pixel data is
|
||||
encoded in ASCII. Pixel data is \fIalways\fP encoded in Silicon Graphics
|
||||
order, which means that the first pixel in the frame is the lower left
|
||||
pixel on the screen.
|
||||
.PP
|
||||
All ASCII data except the first line of the file
|
||||
is in python format. This means that
|
||||
outer parentheses can be ommitted, and parentheses around a tuple with
|
||||
one element can also be omitted. So, the lines
|
||||
.IP
|
||||
.ft C
|
||||
.nf
|
||||
('grey',(4))
|
||||
('grey',4)
|
||||
'grey',4
|
||||
.LP
|
||||
have the same meaning.
|
||||
To ease parsing in C programs, however, it is advised that there are
|
||||
no parenteses around single items, and that there are parentheses around
|
||||
lists. So, the second format above is preferred.
|
||||
.PP
|
||||
The current version is version 3, but this document will also explain
|
||||
shortly what the previous formats looked like.
|
||||
.SH
|
||||
Header.
|
||||
.PP
|
||||
The header consists of three lines. The first line identifies the file
|
||||
as a CMIF video file, and gives the version number.
|
||||
It looks as follows:
|
||||
.IP
|
||||
.ft C
|
||||
CMIF video 3.0
|
||||
.LP
|
||||
All programs expect the layout to be exactly like this, so no
|
||||
extra spaces, etc. should be added.
|
||||
.PP
|
||||
The second line specifies the data format. Its format is a python
|
||||
tuple with two members. The first member is a string giving the format
|
||||
type and the second is a tuple containing type-specific information.
|
||||
The following formats are currently understood:
|
||||
.pT rgb
|
||||
The video data is 24 bit RGB packed into 32 bit words.
|
||||
R is the least significant byte, then G and then B. The top byte is
|
||||
unused.
|
||||
.IP
|
||||
There is no type-specific information, so the complete data format
|
||||
line is
|
||||
.IP
|
||||
.ft C
|
||||
('rgb',())
|
||||
.pT grey
|
||||
The video data is greyscale, at most 8 bits. Data is packed into
|
||||
8 bit bytes (in the low-order bits). The extra information is the
|
||||
number of significant bits, so an example data format line is
|
||||
.IP
|
||||
.ft C
|
||||
('grey',(6))
|
||||
.pT yiq
|
||||
The video data is in YIQ format. This is a format that has one luminance
|
||||
component, Y, and two chrominance components, I and Q. The luminance and
|
||||
chrominance components are encoded in \fItwo\fP pixel arrays: first an
|
||||
array of 8-bit luminance values followed by a array of 16 bit chrominance
|
||||
values. See the section on chrominance coding for details.
|
||||
.IP
|
||||
The type specific part contains the number of bits for Y, I and Q,
|
||||
the chrominance packfactor and the colormap offset. So, a sample format
|
||||
information line of
|
||||
.IP
|
||||
.ft C
|
||||
('yiq',(5,3,3,2,1024))
|
||||
.IP
|
||||
means that the pictures have 5 bit Y values (in the luminance array),
|
||||
3 bits of I and Q each (in the chrominance array), chrominance data
|
||||
is packed for 2x2 pixels, and the first colormap index used is 1024.
|
||||
.pT hls
|
||||
The video data is in HLS format. L is the luminance component, H and S
|
||||
are the chrominance components. The data format and type specific information
|
||||
are the same as for the yiq format.
|
||||
.pT hsv
|
||||
The video data is in HSV format. V is the luminance component, H and S
|
||||
are the chrominance components. Again, data format and type specific
|
||||
information are the same as for the yiq format.
|
||||
.pT rgb8
|
||||
The video data is in 8 bit dithered rgb format. This is the format
|
||||
used internally by the Indigo. bit 0-2 are green, bit 3-4 are blue and
|
||||
bit 5-7 are red. Because rgb8 is treated more-or-less like yiq format
|
||||
internally the type-specific information is the same, with zeroes for
|
||||
the (unused) chrominance sizes:
|
||||
.IP
|
||||
.ft C
|
||||
('rgb8',(8,0,0,0,0))
|
||||
.PP
|
||||
The third header line contains width and height of the video image,
|
||||
in pixels, and the pack factor of the picture. For compatability, RGB
|
||||
images must have a pack factor of 0 (zero), and non-RGB images must
|
||||
have a pack factor of at least 1.
|
||||
The packfactor is the amount of compression done on the original video
|
||||
signal to obtain pictures. In other words, if only one out of three pixels
|
||||
and lines is stored (so every 9 original pixels have one pixel in the
|
||||
data) the packfactor is three. Width and height are the size of the
|
||||
\fIoriginal\fP picture.
|
||||
Viewers are expected to enlarge the picture so it is shown in the
|
||||
original size. RGB videos cannot be packed.
|
||||
So, a size line like
|
||||
.IP
|
||||
.ft C
|
||||
200,200,2
|
||||
.LP
|
||||
means that this was a 200x200 picture that is stored as 100x100 pixels.
|
||||
.SH
|
||||
Frame header
|
||||
.PP
|
||||
Each frame is preceded by a single header line. This line contains timing information
|
||||
and optional size information. The time information is mandatory, and
|
||||
contains the time this frame should be displayed, in milliseconds since
|
||||
the start of the film. Frames should be stored in chronological order.
|
||||
.PP
|
||||
An optional second number is interpreted as the size of the luminance
|
||||
data in bytes. Currently this number, if present, should always be the
|
||||
same as \fCwidth*height/(packfactor*packfactor)\fP (times 4 for RGB
|
||||
data), but this might change if we come up with variable-length encoding
|
||||
for frame data.
|
||||
.PP
|
||||
An optional third number is the size of the chrominance data
|
||||
in bytes. If present, the number should be equal to
|
||||
.ft C
|
||||
luminance_size2*/(chrompack*chrompack).
|
||||
.SH
|
||||
Frame data
|
||||
.PP
|
||||
For RGB films, the frame data is an array of 32 bit pixels containing
|
||||
RGB data in the lower 24 bits. For greyscale films, the frame data
|
||||
is an array of 8 bit pixels. For split luminance/chrominance films the
|
||||
data consists of two parts: first an array of 8 bit luminance values
|
||||
followed by an array of 16 bit chrominance values.
|
||||
.PP
|
||||
For all data formats, the data is stored left-to-right, bottom-to-top.
|
||||
.SH
|
||||
Chrominance coding
|
||||
.PP
|
||||
Since the human eye is apparently more sensitive to luminance changes
|
||||
than to chrominance changes we support a coding where we split the luminance
|
||||
and chrominance components of the video image. The main point of this
|
||||
is that it allows us to transmit chrominance data in a coarser granularity
|
||||
than luminance data, for instance one chrominance pixel for every
|
||||
2x2 luminance pixels. According to the theory this should result in an
|
||||
acceptable picture while reducing the data by a fair amount.
|
||||
.PP
|
||||
The coding of split chrominance/luminance data is a bit tricky, to
|
||||
make maximum use of the graphics hardware on the Personal Iris. Therefore,
|
||||
there are the following constraints on the number of bits used:
|
||||
.IP -
|
||||
No more than 8 luminance bits,
|
||||
.IP -
|
||||
No more than 11 bits total,
|
||||
.IP -
|
||||
The luminance bits are in the low-end of the data word, and are stored
|
||||
as 8 bit bytes,
|
||||
.IP -
|
||||
The two sets of chrominance bits are stored in 16 bit words, correctly
|
||||
aligned,
|
||||
.IP -
|
||||
The color map offset is added to the chrominance data. The offset should
|
||||
be at most 4096-256-2**(total number of bits). To reduce interference with
|
||||
other applications the offset should be at least 1024.
|
||||
.LP
|
||||
So, as an example, an HLS video with 5 bits L, 4 bits H, 2 bits S and an
|
||||
offset of 1024 will look as follows in-core and in-file:
|
||||
.IP
|
||||
.nf
|
||||
.ft C
|
||||
31 15 11 10 9 8 5 4 0
|
||||
+-----------------------------------+
|
||||
incore + 0+ 1+ S + H + L +
|
||||
+-----------------------------------+
|
||||
+----------+
|
||||
L-array + 0 + L +
|
||||
+----------+
|
||||
+-----------------------+
|
||||
C-array + 0+ 1+ S + H + 0 +
|
||||
+-----------------------+
|
|
@ -1,139 +0,0 @@
|
|||
import imageop
|
||||
|
||||
error = 'imgconv.error'
|
||||
|
||||
LOSSY = 1
|
||||
NOT_LOSSY = 0
|
||||
|
||||
def null(img, x, y):
|
||||
return img
|
||||
|
||||
def mono2grey(img, x, y):
|
||||
return imageop.mono2grey(img, x, y, 0, 255)
|
||||
|
||||
def grey2jpeggrey(img, x, y):
|
||||
import jpeg
|
||||
return jpeg.compress(img, x, y, 1)
|
||||
|
||||
def rgb2jpeg(img, x, y):
|
||||
import jpeg
|
||||
return jpeg.compress(img, x, y, 4)
|
||||
|
||||
def jpeggrey2grey(img, width, height):
|
||||
import jpeg
|
||||
data, width, height, bytesperpixel = jpeg.decompress(img)
|
||||
if bytesperpixel <> 1: raise RuntimeError, 'not greyscale jpeg'
|
||||
return data
|
||||
|
||||
def jpeg2rgb(img, width, height):
|
||||
import jpeg
|
||||
data, width, height, bytesperpixel = jpeg.decompress(img)
|
||||
if bytesperpixel <> 4: raise RuntimeError, 'not rgb jpeg'
|
||||
return data
|
||||
|
||||
converters = [ \
|
||||
('grey', 'grey4', imageop.grey2grey4, LOSSY), \
|
||||
('grey', 'grey2', imageop.dither2grey2, LOSSY), \
|
||||
('grey', 'mono', imageop.dither2mono, LOSSY), \
|
||||
('mono', 'grey', mono2grey, NOT_LOSSY), \
|
||||
('grey2', 'grey', imageop.grey22grey, NOT_LOSSY), \
|
||||
('grey4', 'grey', imageop.grey42grey, NOT_LOSSY), \
|
||||
('rgb', 'rgb8', imageop.rgb2rgb8, LOSSY), \
|
||||
('rgb8', 'rgb', imageop.rgb82rgb, NOT_LOSSY), \
|
||||
('rgb', 'grey', imageop.rgb2grey, LOSSY), \
|
||||
('grey', 'rgb', imageop.grey2rgb, NOT_LOSSY), \
|
||||
('jpeggrey','grey',jpeggrey2grey, NOT_LOSSY), \
|
||||
('grey', 'jpeggrey',grey2jpeggrey, LOSSY), \
|
||||
('jpeg', 'rgb', jpeg2rgb, NOT_LOSSY), \
|
||||
('rgb', 'jpeg', rgb2jpeg, LOSSY), \
|
||||
]
|
||||
|
||||
built = {}
|
||||
|
||||
def addconverter(fcs, tcs, lossy, func):
|
||||
for i in range(len(converters)):
|
||||
ifcs, itcs, irtn, ilossy = converters[i]
|
||||
if (fcs, tcs) == (ifcs, itcs):
|
||||
converters[i] = (fcs, tcs, func, lossy)
|
||||
return
|
||||
converters.append((fcs,tcs,lossy,func))
|
||||
|
||||
def getconverter(fcs, tcs):
|
||||
#
|
||||
# If formats are the same return the dummy converter
|
||||
#
|
||||
if fcs == tcs: return null
|
||||
#
|
||||
# Otherwise, if we have a converter return that one
|
||||
#
|
||||
for ifcs, itcs, irtn, ilossy in converters:
|
||||
if (fcs, tcs) == (ifcs, itcs):
|
||||
return irtn
|
||||
#
|
||||
# Finally, we try to create a converter
|
||||
#
|
||||
if not built.has_key(fcs):
|
||||
built[fcs] = enumerate_converters(fcs)
|
||||
if not built[fcs].has_key(tcs):
|
||||
raise error, 'Sorry, conversion from '+fcs+' to '+tcs+ \
|
||||
' is not implemented'
|
||||
if len(built[fcs][tcs]) == 3:
|
||||
#
|
||||
# Converter not instantiated yet
|
||||
#
|
||||
built[fcs][tcs].append(instantiate_converter(built[fcs][tcs]))
|
||||
cf = built[fcs][tcs][3]
|
||||
return cf
|
||||
|
||||
def enumerate_converters(fcs):
|
||||
cvs = {}
|
||||
formats = [fcs]
|
||||
steps = 0
|
||||
while 1:
|
||||
workdone = 0
|
||||
for ifcs, itcs, irtn, ilossy in converters:
|
||||
if ifcs == fcs:
|
||||
template = [ilossy, 1, [irtn]]
|
||||
elif cvs.has_key(ifcs):
|
||||
template = cvs[ifcs][:]
|
||||
template[2] = template[2][:]
|
||||
if ilossy:
|
||||
template[0] = ilossy
|
||||
template[1] = template[1] + 1
|
||||
template[2].append(irtn)
|
||||
else:
|
||||
continue
|
||||
if not cvs.has_key(itcs):
|
||||
cvs[itcs] = template
|
||||
workdone = 1
|
||||
else:
|
||||
previous = cvs[itcs]
|
||||
if template < previous:
|
||||
cvs[itcs] = template
|
||||
workdone = 1
|
||||
if not workdone:
|
||||
break
|
||||
steps = steps + 1
|
||||
if steps > len(converters):
|
||||
print '------------------loop in emunerate_converters--------'
|
||||
print 'CONVERTERS:'
|
||||
print converters
|
||||
print 'RESULTS:'
|
||||
print cvs
|
||||
raise error, 'Internal error - loop'
|
||||
return cvs
|
||||
|
||||
def instantiate_converter(args):
|
||||
list = args[2]
|
||||
cl = RtConverters(list)
|
||||
args.append(cl.convert)
|
||||
return args
|
||||
|
||||
class RtConverters:
|
||||
def __init__(self, list):
|
||||
self.list = list
|
||||
|
||||
def convert(self, img, w, h):
|
||||
for cv in self.list:
|
||||
img = cv(img, w, h)
|
||||
return img
|
|
@ -1,79 +0,0 @@
|
|||
import sys
|
||||
import VFile
|
||||
import getopt
|
||||
import imgfile
|
||||
import string
|
||||
import imgconv
|
||||
|
||||
def main():
|
||||
format = None
|
||||
interval = 40
|
||||
outfile = 'film.video'
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'f:i:o:')
|
||||
except getopt.error:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
for opt, arg in opts:
|
||||
if opt == '-f':
|
||||
format = arg
|
||||
elif opt == '-i':
|
||||
interval = string.atoi(arg)
|
||||
elif opt == '-o':
|
||||
outfile = arg
|
||||
else:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
if not args:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
xsize, ysize, zsize = imgfile.getsizes(args[0])
|
||||
nxsize = xsize
|
||||
|
||||
if zsize == 3:
|
||||
oformat = 'rgb'
|
||||
elif zsize == 1:
|
||||
oformat = 'grey'
|
||||
if xsize % 4:
|
||||
addbytes = 4-(xsize%4)
|
||||
nxsize = xsize + addbytes
|
||||
print 'rgb2video: add',addbytes,'pixels per line'
|
||||
else:
|
||||
print 'rgb2video: incorrect number of planes:',zsize
|
||||
sys.exit(1)
|
||||
|
||||
if format == None:
|
||||
format = oformat
|
||||
cfunc = imgconv.getconverter(oformat, format)
|
||||
|
||||
vout = VFile.VoutFile(outfile)
|
||||
vout.format = format
|
||||
vout.width = nxsize
|
||||
vout.height = ysize
|
||||
vout.writeheader()
|
||||
t = 0
|
||||
sys.stderr.write('Processing ')
|
||||
for img in args:
|
||||
sys.stderr.write(img + ' ')
|
||||
if imgfile.getsizes(img) <> (xsize, ysize, zsize):
|
||||
print 'rgb2video: Image is different size:', img
|
||||
sys.exit(1)
|
||||
data = imgfile.read(img)
|
||||
if xsize <> nxsize:
|
||||
ndata = ''
|
||||
for i in range(0,len(data), xsize):
|
||||
curline = data[i:i+xsize]
|
||||
ndata = ndata + curline + ('\0'*(nxsize-xsize))
|
||||
data = ndata
|
||||
vout.writeframe(t, cfunc(data, nxsize, ysize), None)
|
||||
t = t + interval
|
||||
sys.stderr.write('\n')
|
||||
vout.close()
|
||||
|
||||
def usage():
|
||||
print 'Usage: rgb2video [-o output] [-i frameinterval] [-f format] rgbfile ...'
|
||||
|
||||
main()
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# Defaults shared by Vsend and Vreceice
|
||||
|
||||
DEFMCAST = '225.0.0.250'
|
||||
DEFPORT = 5555
|
||||
|
||||
PKTMAX_UCAST = 16*1024 - 6
|
||||
PKTMAX_BCAST = 1450
|
||||
DEFPKTMAX = PKTMAX_BCAST
|
||||
|
||||
DEFWIDTH = 400
|
||||
DEFHEIGHT = 300
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* svgrab24 - Grab the current video input image into an rgb file.
|
||||
*
|
||||
* Jack Jansen, CWI, May 93.
|
||||
*
|
||||
* Adapted from grabone.c
|
||||
*/
|
||||
|
||||
#ident "$Revision$"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <svideo.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/device.h>
|
||||
#include <getopt.h>
|
||||
#include <image.h>
|
||||
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
SVhandle V;
|
||||
svCaptureInfo ci;
|
||||
boolean debug;
|
||||
int ch, errflg;
|
||||
int bufferSize;
|
||||
long *buffer;
|
||||
IMAGE *imgfile;
|
||||
short *r, *g, *b;
|
||||
int x, y;
|
||||
char *ProgName = argv[0];
|
||||
|
||||
debug = FALSE;
|
||||
ci.format = SV_RGB32_FRAMES;
|
||||
ci.width = 0;
|
||||
ci.height = 0;
|
||||
ci.size = 1;
|
||||
|
||||
argv++; argc--;
|
||||
if ( argc > 2 && strcmp(argv[0], "-w") == 0) {
|
||||
ci.width = atoi(argv[1]);
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
if ( argc != 1 ) {
|
||||
fprintf(stderr, "Usage: %s [-w width] rgbfilename\n", ProgName);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Open video device */
|
||||
if ((V = svOpenVideo()) == NULL) {
|
||||
svPerror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (svQueryCaptureBufferSize(V, &ci, &bufferSize) < 0) {
|
||||
svPerror("svQueryCaptureBufferSize");
|
||||
exit(1);
|
||||
}
|
||||
buffer = malloc(bufferSize);
|
||||
|
||||
if (svCaptureOneFrame(V, ci.format, &ci.width, &ci.height, buffer) < 0) {
|
||||
svPerror("svCaptureOneFrame");
|
||||
exit(1);
|
||||
}
|
||||
if (debug) {
|
||||
printf("captured size: %d by %d\n", ci.width, ci.height);
|
||||
}
|
||||
|
||||
if ( (imgfile=iopen(argv[0], "w", RLE(1), 3, ci.width, ci.height, 3)) == 0) {
|
||||
perror(argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
r = (short *)malloc(ci.width*sizeof(short));
|
||||
g = (short *)malloc(ci.width*sizeof(short));
|
||||
b = (short *)malloc(ci.width*sizeof(short));
|
||||
if ( !r || !g || !b ) {
|
||||
fprintf(stderr, "%s: malloc failed\n", ProgName);
|
||||
exit(1);
|
||||
}
|
||||
for(y=0; y<ci.height; y++) {
|
||||
for(x=0; x<ci.width; x++) {
|
||||
unsigned long data = *buffer++;
|
||||
|
||||
r[x] = data & 0xff;
|
||||
g[x] = (data>>8) & 0xff;
|
||||
b[x] = (data>>16) & 0xff;
|
||||
}
|
||||
if ( putrow(imgfile, r, y, 0) == 0 ||
|
||||
putrow(imgfile, g, y, 1) == 0 ||
|
||||
putrow(imgfile, b, y, 2) == 0) {
|
||||
fprintf(stderr, "%s: putrow failed\n", ProgName);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
iclose(imgfile);
|
||||
exit(0);
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
# Copy a video file, interactively, frame-by-frame.
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
from gl import *
|
||||
from DEVICE import *
|
||||
import VFile
|
||||
import string
|
||||
import imageop
|
||||
|
||||
def report(time, iframe):
|
||||
print 'Frame', iframe, ': t =', time
|
||||
|
||||
def usage():
|
||||
sys.stderr.write('usage: vcopy [-t type] [-m treshold] [-a] infile outfile\n')
|
||||
sys.stderr.write('-t Convert to other type\n')
|
||||
sys.stderr.write('-a Automatic\n')
|
||||
sys.stderr.write('-m Convert grey to mono with treshold\n')
|
||||
sys.stderr.write('-d Convert grey to mono with dithering\n')
|
||||
sys.exit(2)
|
||||
|
||||
def help():
|
||||
print 'Command summary:'
|
||||
print 'n get next image from input'
|
||||
print 'w write current image to output'
|
||||
|
||||
def main():
|
||||
foreground()
|
||||
opts, args = getopt.getopt(sys.argv[1:], 't:am:d')
|
||||
if len(args) <> 2:
|
||||
usage()
|
||||
[ifile, ofile] = args
|
||||
print 'open film ', ifile
|
||||
ifilm = VFile.VinFile().init(ifile)
|
||||
print 'open output ', ofile
|
||||
ofilm = VFile.VoutFile().init(ofile)
|
||||
|
||||
ofilm.setinfo(ifilm.getinfo())
|
||||
|
||||
use_grabber = 0
|
||||
continuous = 0
|
||||
tomono = 0
|
||||
tomonodither = 0
|
||||
for o, a in opts:
|
||||
if o == '-t':
|
||||
ofilm.format = a
|
||||
use_grabber = 1
|
||||
if o == '-a':
|
||||
continuous = 1
|
||||
if o == '-m':
|
||||
if ifilm.format <> 'grey':
|
||||
print '-m only supported for greyscale'
|
||||
sys.exit(1)
|
||||
tomono = 1
|
||||
treshold = string.atoi(a)
|
||||
ofilm.format = 'mono'
|
||||
if o == '-d':
|
||||
if ifilm.format <> 'grey':
|
||||
print '-m only supported for greyscale'
|
||||
sys.exit(1)
|
||||
tomonodither = 1
|
||||
ofilm.format = 'mono'
|
||||
|
||||
ofilm.writeheader()
|
||||
#
|
||||
prefsize(ifilm.width, ifilm.height)
|
||||
w = winopen(ifile)
|
||||
qdevice(KEYBD)
|
||||
qdevice(ESCKEY)
|
||||
qdevice(WINQUIT)
|
||||
qdevice(WINSHUT)
|
||||
print 'qdevice calls done'
|
||||
#
|
||||
help()
|
||||
#
|
||||
time, data, cdata = ifilm.getnextframe()
|
||||
ifilm.showframe(data, cdata)
|
||||
iframe = 1
|
||||
report(time, iframe)
|
||||
#
|
||||
while 1:
|
||||
if continuous:
|
||||
dev = KEYBD
|
||||
else:
|
||||
dev, val = qread()
|
||||
if dev in (ESCKEY, WINQUIT, WINSHUT):
|
||||
break
|
||||
if dev == REDRAW:
|
||||
reshapeviewport()
|
||||
elif dev == KEYBD:
|
||||
if continuous:
|
||||
c = '0'
|
||||
else:
|
||||
c = chr(val)
|
||||
#XXX Debug
|
||||
if c == 'R':
|
||||
c3i(255,0,0)
|
||||
clear()
|
||||
if c == 'G':
|
||||
c3i(0,255,0)
|
||||
clear()
|
||||
if c == 'B':
|
||||
c3i(0,0,255)
|
||||
clear()
|
||||
if c == 'w' or continuous:
|
||||
if use_grabber:
|
||||
data, cdata = ofilm.grabframe()
|
||||
if tomono:
|
||||
data = imageop.grey2mono(data, \
|
||||
ifilm.width, ifilm.height, \
|
||||
treshold)
|
||||
if tomonodither:
|
||||
data = imageop.dither2mono(data, \
|
||||
ifilm.width, ifilm.height)
|
||||
ofilm.writeframe(time, data, cdata)
|
||||
print 'Frame', iframe, 'written.'
|
||||
if c == 'n' or continuous:
|
||||
try:
|
||||
time,data,cdata = ifilm.getnextframe()
|
||||
ifilm.showframe(data, cdata)
|
||||
iframe = iframe+1
|
||||
report(time, iframe)
|
||||
except EOFError:
|
||||
print 'EOF'
|
||||
if continuous:
|
||||
break
|
||||
ringbell()
|
||||
elif dev == INPUTCHANGE:
|
||||
pass
|
||||
else:
|
||||
print '(dev, val) =', (dev, val)
|
||||
ofilm.close()
|
||||
|
||||
main()
|
|
@ -1,109 +0,0 @@
|
|||
CMIF video tools
|
||||
|
||||
This document gives a quick introduction to some of the tools useful
|
||||
for recording, editing and playing back video data in CMIF video
|
||||
format. All the tools mentioned currently live in /ufs/guido/bin/sgi.
|
||||
A description of the CMIF video file format can be found in
|
||||
/ufs/jack/cmif-film.ms.
|
||||
|
||||
Recording video
|
||||
|
||||
There are two tools to record video, Vrec and and Vrecb. Vrec does
|
||||
continuous capture, but can capture at most 15 frames per second.
|
||||
Vrecb uses burst capture, enabling it to capture all frames. It
|
||||
captures to main memory, however, so it cannot handle long video
|
||||
fragments. The following options are common to both programs:
|
||||
|
||||
-r rate Capture one out of 'rate' frames. Default (and
|
||||
minimum) is 1 for Vrecb, 2 for Vrec. There are some
|
||||
caveats for recording PAL, see below.
|
||||
-w width Set initial window width (and height, implicitly).
|
||||
-g bits Create greyscale film in stead of 8-bit dithered color
|
||||
film. Allowable values for 'bits' are 2, 4 or 8.
|
||||
-m Create monochrome dithered film. These look horrible.
|
||||
-M threshold Create monochrome thresholded film with specified
|
||||
threshold (in range 0..255).
|
||||
-G Create 2-bit dithered greyscale film.
|
||||
-f Capture fields in stead of frames. The film is created
|
||||
in such a way that the picture will be suitably
|
||||
enlarged on playback, so aspect ratio, etc. are
|
||||
maintained.
|
||||
-d Drop fields if they would cause data from two video
|
||||
fields to be combined. See the section on PAL for more
|
||||
details.
|
||||
|
||||
Options for Vrec:
|
||||
-a Record audio as well. You will have to twiddle audio
|
||||
and video later if you want lipsync playback.
|
||||
-q queuesize Set size of the video board circular buffer. A little
|
||||
experimentation with this may lead to more video being
|
||||
captured, but not always.
|
||||
-P frames Preallocate diskspace for 'frames' images. This may
|
||||
enable you to capture more frames.
|
||||
|
||||
Options for Vrecb:
|
||||
-n number Capture 'number' frames. Default is 60 (2 seconds).
|
||||
|
||||
Both programs accept a filename to store the video on (default
|
||||
film.video) and Vrec also accepts an audio file name (default
|
||||
film.aiff). When you want to record you press the left mouse button.
|
||||
Vrec stops recording when you release the mouse button and Vrecb stops
|
||||
after the predetermined number of frames have been recorded. During
|
||||
recording the picture may look funny, but do not let this worry you,
|
||||
the film will be ok.
|
||||
|
||||
After recording and saving, Vrec will print the deltas of the field
|
||||
numbers recorded. A list of '4 4 4 4'... means that all possible
|
||||
frames (one out of two) have been recorded. Vrecb will tell you how
|
||||
many duplicate fields have been skipped. See below on PAL useage
|
||||
again.
|
||||
|
||||
PAL caveats
|
||||
|
||||
The IndigoVideo board converts the incoming video signal to the 60Hz
|
||||
(59.something, actually) display rate. All further operations,
|
||||
including capture, are done with respect to display rate. This is
|
||||
especially bothersome in the case of PAL video, since it means one out
|
||||
of 5 frames will be duplicated. Together with the fact that, in
|
||||
continuous capture, you can only capture every second frame this leads
|
||||
to strange and wondrous effects. The frame numbers returned by the
|
||||
video board (and displayed by Vrec) are display frame numbers, and so
|
||||
bear only a very complicated (and probably non-deterministic) relation
|
||||
to PAL frame numbers. For recording simple videos this is probably no
|
||||
problem. You can use Vrec and try using -d to see which gives the best
|
||||
result. On the other hand, if you need every frame and no duplicates
|
||||
either you have to use Vrecb and supply the -d and -f option. This
|
||||
will give you exactly the fields as they appeared on the PAL tape.
|
||||
|
||||
Video playback
|
||||
|
||||
The easiest way to play back a video is to use Vplay. Calling it with
|
||||
an argument of -? will make it list all its options. A few options may
|
||||
need a bit of explanation:
|
||||
-M magnify Magnify the images by the given factor. This still
|
||||
takes any magnification specified in the film (if it
|
||||
is a field film, for instance) in account.
|
||||
-w width and
|
||||
-h height Normally the window will be the correct size for the
|
||||
film. You can set height and width, though, if you
|
||||
want the window to be bigger. This is especially
|
||||
useful if you want to record the film back to
|
||||
videotape, since you can playback in a window that is
|
||||
bigger than PAL size with a black background and you
|
||||
will have no distracting window-manager thingies on
|
||||
your videotape.
|
||||
|
||||
Video Editing
|
||||
|
||||
Vedit is a (very simple) video editor that allows you to select images
|
||||
from the input movie and copy them to an output movie. Both input and
|
||||
output films have a modest buffer that you can move around in.
|
||||
|
||||
Vaddcache takes a movie and adds a frame location cache to it. This
|
||||
will make some other programs run faster.
|
||||
|
||||
rgb2video converts a set of SGI .rgb files to a movie.
|
||||
|
||||
There are a few programs that can do image format conversion on movies
|
||||
(i.e. convert an 8-bit dithered RGB movie to a greyscale movie), but
|
||||
nothing very complete yet. Look at Vcopy.py for more information.
|
|
@ -1,159 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Convert CMIF movie file(s) to a sequence of rgb images
|
||||
|
||||
|
||||
# Help function
|
||||
|
||||
def help():
|
||||
print 'Usage: video2rgb [options] [file] ...'
|
||||
print
|
||||
print 'Options:'
|
||||
print '-q : quiet, no informative messages'
|
||||
print '-m : create monochrome (greyscale) image files'
|
||||
print '-f prefix : create image files with names "prefix0000.rgb"'
|
||||
print 'file ... : file(s) to convert; default film.video'
|
||||
|
||||
|
||||
# Imported modules
|
||||
|
||||
import sys
|
||||
sys.path.append('/ufs/jack/src/av/video') # Increase chance of finding VFile
|
||||
import VFile
|
||||
import time
|
||||
import getopt
|
||||
import string
|
||||
import imgfile
|
||||
import imgconv
|
||||
|
||||
|
||||
# Global options
|
||||
|
||||
quiet = 0
|
||||
prefix = 'film'
|
||||
seqno = 0
|
||||
mono = 0
|
||||
|
||||
|
||||
# Main program -- mostly command line parsing
|
||||
|
||||
def main():
|
||||
global quiet, prefix, mono
|
||||
|
||||
# Parse command line
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'qmf:')
|
||||
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 == '-q': quiet = 1
|
||||
if opt == '-f': prefix = arg
|
||||
if opt == '-m': mono = 1
|
||||
except string.atoi_error:
|
||||
sys.stdout = sys.stderr
|
||||
print 'Option', opt, 'requires integer argument'
|
||||
sys.exit(2)
|
||||
|
||||
# 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()
|
||||
|
||||
width, height = int(vin.width), int(vin.height)
|
||||
|
||||
try:
|
||||
if mono:
|
||||
cf = imgconv.getconverter(vin.format, 'grey')
|
||||
else:
|
||||
cf = imgconv.getconverter(vin.format, 'rgb')
|
||||
except imgconv.error:
|
||||
print 'Sorry, no converter available for type',vin.format
|
||||
return
|
||||
|
||||
if mono:
|
||||
depth = 1
|
||||
bpp = 1
|
||||
else:
|
||||
depth = 3
|
||||
bpp = 4
|
||||
|
||||
convert(vin, cf, width, height, depth, bpp, vin.packfactor)
|
||||
|
||||
def convert(vin, cf, width, height, depth, bpp, pf):
|
||||
global seqno
|
||||
|
||||
if type(pf) == type(()):
|
||||
xpf, ypf = pf
|
||||
elif pf == 0:
|
||||
xpf = ypf = 1
|
||||
else:
|
||||
xpf = ypf = pf
|
||||
while 1:
|
||||
try:
|
||||
time, data, cdata = vin.getnextframe()
|
||||
except EOFError:
|
||||
return
|
||||
if cdata:
|
||||
print 'Film contains chromdata!'
|
||||
return
|
||||
data = cf(data, width/xpf, height/abs(ypf))
|
||||
if pf:
|
||||
data = applypackfactor(data, width, height, pf, bpp)
|
||||
s = `seqno`
|
||||
s = '0'*(4-len(s)) + s
|
||||
fname = prefix + s + '.rgb'
|
||||
seqno = seqno + 1
|
||||
if not quiet:
|
||||
print 'Writing',fname,'...'
|
||||
imgfile.write(fname, data, width, height, depth)
|
||||
|
||||
def applypackfactor(image, w, h, pf, bpp):
|
||||
import imageop
|
||||
if type(pf) == type(()):
|
||||
xpf, ypf = pf
|
||||
elif pf == 0:
|
||||
xpf = ypf = 1
|
||||
else:
|
||||
xpf = ypf = pf
|
||||
w1 = w/xpf
|
||||
h1 = h/abs(ypf)
|
||||
if ypf < 0:
|
||||
ypf = -ypf
|
||||
image = imageop.crop(image, bpp, w1, h1, 0, h1-1, w1-1, 0)
|
||||
return imageop.scale(image, bpp, w1, h1, w, h)
|
||||
|
||||
# Don't forget to call the main program
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print '[Interrupt]'
|
|
@ -1,90 +0,0 @@
|
|||
from gl import *
|
||||
from GL import *
|
||||
from DEVICE import *
|
||||
import time
|
||||
import sys
|
||||
import getopt
|
||||
|
||||
class Struct(): pass
|
||||
epoch = Struct()
|
||||
EndOfFile = 'End of file'
|
||||
bye = 'bye'
|
||||
|
||||
def openvideo(filename):
|
||||
f = open(filename, 'r')
|
||||
line = f.readline()
|
||||
if not line: raise EndOfFile
|
||||
if line[:4] == 'CMIF': line = f.readline()
|
||||
x = eval(line[:-1])
|
||||
if len(x) == 3: w, h, pf = x
|
||||
else: w, h = x; pf = 2
|
||||
return f, w, h, pf
|
||||
|
||||
def loadframe(f, w, h, pf):
|
||||
line = f.readline()
|
||||
if line == '':
|
||||
raise EndOfFile
|
||||
x = eval(line[:-1])
|
||||
if type(x) == type(0) or type(x) == type(0.0):
|
||||
tijd = x
|
||||
if pf == 0:
|
||||
size = w*h*4
|
||||
else:
|
||||
size = (w/pf) * (h/pf)
|
||||
else:
|
||||
tijd, size = x
|
||||
f.seek(size, 1)
|
||||
return tijd
|
||||
|
||||
def main():
|
||||
delta = 0
|
||||
short = 0
|
||||
try:
|
||||
opts, names = getopt.getopt(sys.argv[1:], 'ds')
|
||||
except getopt.error, msg:
|
||||
sys.stderr.write(msg + '\n')
|
||||
sys.stderr.write('usage: vinfo [-d] [-s] [file] ...\n')
|
||||
sys.exit(2)
|
||||
for opt, arg in opts:
|
||||
if opt == '-d': delta = 1 # print delta between frames
|
||||
elif opt == '-s': short = 1 # short: don't print times
|
||||
if names == []:
|
||||
names = ['film.video']
|
||||
for name in names:
|
||||
try:
|
||||
f, w, h, pf = openvideo(name)
|
||||
except:
|
||||
sys.stderr.write(name + ': cannot open\n')
|
||||
continue
|
||||
if pf == 0:
|
||||
size = w*h*4
|
||||
else:
|
||||
size = (w/pf) * (h/pf)
|
||||
print name, ':', w, 'x', h, '; pf =', pf, ', size =', size,
|
||||
if pf == 0:
|
||||
print '(color)',
|
||||
else:
|
||||
print '(' + `(w/pf)` + 'x' + `(h/pf)` + ')',
|
||||
if (w/pf)%4 <> 0: print '!!!',
|
||||
print
|
||||
num = 0
|
||||
try:
|
||||
otijd = 0
|
||||
while not short:
|
||||
try:
|
||||
tijd = loadframe(f, w, h, pf)
|
||||
if delta: print '\t' + `tijd-otijd`,
|
||||
else: print '\t' + `tijd`,
|
||||
otijd = tijd
|
||||
num = num + 1
|
||||
if num % 8 == 0:
|
||||
print
|
||||
except EndOfFile:
|
||||
raise bye
|
||||
except bye:
|
||||
pass
|
||||
if num % 8 <> 0:
|
||||
print
|
||||
f.close()
|
||||
|
||||
main()
|
|
@ -1,106 +0,0 @@
|
|||
#
|
||||
# Module vtime - Keep virtual time between two nodes.
|
||||
#
|
||||
# We try for synchronised clocks by sending a packet of the for
|
||||
# (1,mytime,0) to the other side, and waiting (at most) a second for
|
||||
# a reply. This reply has the form (2,mytime,histime), and we can
|
||||
# estimate the time difference by defining histime to be exactly half-way
|
||||
# between the time we sent our message and got our reply. We send a
|
||||
# final (3,mynewtime,histime) message to allow the other side to do the
|
||||
# same computations.
|
||||
#
|
||||
# Note that the protocol suffers heavily from the 2-army problem.
|
||||
# It'll have to do until I can read up on time-sync protocols, though.
|
||||
#
|
||||
from socket import *
|
||||
import time
|
||||
|
||||
MSGSIZE = 100
|
||||
MSGTIMEOUT = 1000
|
||||
|
||||
recv_timeout = 'receive timeout'
|
||||
bad_connect = 'Bad connection'
|
||||
|
||||
def timeavg(a,b):
|
||||
return int((long(a)+b)/2L)
|
||||
def tryrecv(s):
|
||||
cnt = 0
|
||||
while 1:
|
||||
if s.avail():
|
||||
return s.recvfrom(MSGSIZE)
|
||||
time.millisleep(100)
|
||||
cnt = cnt + 100
|
||||
if cnt > MSGTIMEOUT:
|
||||
raise recv_timeout
|
||||
|
||||
class VTime():
|
||||
def init(self,(client,host,port)):
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
host = gethostbyname(host)
|
||||
localhost = gethostbyname(gethostname())
|
||||
raddr = (host,port)
|
||||
s.bind((localhost,port))
|
||||
if client:
|
||||
#
|
||||
# We loop here because we want the *second* measurement
|
||||
# for accuracy
|
||||
for loopct in (0,2):
|
||||
curtijd = time.millitimer()
|
||||
check = `(loopct,curtijd,0)`
|
||||
s.sendto(check,raddr)
|
||||
while 1:
|
||||
try:
|
||||
if loopct:
|
||||
data, other = s.recvfrom(MSGSIZE)
|
||||
else:
|
||||
data, other = tryrecv(s)
|
||||
newtijd = time.millitimer()
|
||||
if other <> raddr:
|
||||
print 'Someone else syncing to us: ', other
|
||||
raise bad_connect
|
||||
data = eval(data)
|
||||
if data[:2] == (loopct+1,curtijd):
|
||||
break
|
||||
if data[0] <> 2:
|
||||
print 'Illegal sync reply: ', data
|
||||
raise bad_connect
|
||||
except recv_timeout:
|
||||
curtijd = time.millitimer()
|
||||
check = `(loopct,curtijd,0)`
|
||||
s.sendto(check,raddr)
|
||||
histime = data[2]
|
||||
s.sendto(`(4,newtijd,histime)`,raddr)
|
||||
mytime = timeavg(curtijd,newtijd)
|
||||
#mytime = curtijd
|
||||
self.timediff = histime - mytime
|
||||
else:
|
||||
while 1:
|
||||
data,other = s.recvfrom(MSGSIZE)
|
||||
if other <> raddr:
|
||||
print 'Someone else syncing to us: ', other, ' Wanted ', raddr
|
||||
raise bad_connect
|
||||
data = eval(data)
|
||||
if data[0] in (0,2):
|
||||
curtijd = time.millitimer()
|
||||
s.sendto(`(data[0]+1,data[1],curtijd)`,raddr)
|
||||
elif data[0] == 4:
|
||||
newtijd = time.millitimer()
|
||||
histime = data[1]
|
||||
mytime = timeavg(curtijd,newtijd)
|
||||
#mytime = curtijd
|
||||
self.timediff = histime-mytime
|
||||
break
|
||||
else:
|
||||
print 'Funny data: ', data
|
||||
raise bad_connect
|
||||
return self
|
||||
#
|
||||
def his2mine(self,tijd):
|
||||
return tijd - self.timediff
|
||||
#
|
||||
def mine2his(self, tijd):
|
||||
return tijd + self.timediff
|
||||
|
||||
def test(clt, host, port):
|
||||
xx = VTime().init(clt,host,port)
|
||||
print 'Time diff: ', xx.his2mine(0)
|
|
@ -1,45 +0,0 @@
|
|||
# Define a 16x16 cursor looking like a watch
|
||||
|
||||
# X11 bitmap file:
|
||||
##define x_width 16
|
||||
##define x_height 16
|
||||
#static char x_bits[] = {
|
||||
# 0xf0, 0x0f, 0xf8, 0x1f, 0x1c, 0x38, 0x8e, 0x71, 0x87, 0xe1, 0x83, 0xc1,
|
||||
# 0x83, 0xc1, 0xf3, 0xc1, 0xf3, 0xc1, 0x03, 0xc0, 0x03, 0xc0, 0x07, 0xe0,
|
||||
# 0x0e, 0x70, 0x1c, 0x38, 0xf8, 0x1f, 0xf0, 0x0f};
|
||||
|
||||
|
||||
watch = [ \
|
||||
0x0ff0,\
|
||||
0x1ff8,\
|
||||
0x381c,\
|
||||
0x718e,\
|
||||
0xe187,\
|
||||
0xc183,\
|
||||
0xc183,\
|
||||
0xc1f3,\
|
||||
0xc1f3,\
|
||||
0xc003,\
|
||||
0xc003,\
|
||||
0xe007,\
|
||||
0x700e,\
|
||||
0x381c,\
|
||||
0x1ff8,\
|
||||
0x0ff0,\
|
||||
]
|
||||
|
||||
watch.reverse() # Turn it upside-down
|
||||
|
||||
def defwatch(index):
|
||||
import gl
|
||||
gl.defcursor(index, watch*8)
|
||||
gl.curorigin(index, 8, 8)
|
||||
|
||||
def test():
|
||||
import gl
|
||||
gl.foreground()
|
||||
gl.winopen('test watchcursor')
|
||||
defwatch(1)
|
||||
gl.setcursor(1, 0, 0)
|
||||
import time
|
||||
time.sleep(10)
|
Loading…
Reference in New Issue