summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xDemo/sgi/video/Vb.py286
1 files changed, 201 insertions, 85 deletions
diff --git a/Demo/sgi/video/Vb.py b/Demo/sgi/video/Vb.py
index 6d4c4b5..2a46571 100755
--- a/Demo/sgi/video/Vb.py
+++ b/Demo/sgi/video/Vb.py
@@ -2,6 +2,8 @@
# Video bag-of-tricks
+# XXX To do: audio; rationalize user interface; ...?
+
import sys
import getopt
import string
@@ -33,9 +35,10 @@ def main():
StopCapture = 'StopCapture'
-formats = ['rgb8', 'grey8', 'grey4', 'grey2', \
- 'grey2_dith', 'mono_dith', 'mono_thresh']
-formatmap = {'rgb24': 'rgb', 'grey8': 'grey'}
+Labels = ['rgb8', 'grey8', 'grey4', 'grey2', \
+ 'grey2 dith', 'mono dith', 'mono thresh']
+Formats = ['rgb8', 'grey', 'grey4', 'grey2', \
+ 'grey2', 'mono', 'mono']
class VideoBagOfTricks:
@@ -53,22 +56,13 @@ class VideoBagOfTricks:
fl.set_event_call_back(self.do_event)
return self
- def setwatch(self):
- gl.winset(self.form.window)
- gl.setcursor(WATCH, 0, 0)
-
- def setarrow(self):
- gl.winset(self.form.window)
- gl.setcursor(ARROW, 0, 0)
-
def setdefaults(self):
+ self.mono_thresh = 128
self.format = 'rgb8'
self.c_format.clear_choice()
- for label in formats:
+ for label in Labels:
self.c_format.addto_choice(label)
- self.c_format.set_choice(1 + formats.index(self.format))
- self.mono_thresh = 128
- self.mono_use_thresh = 0
+ self.get_format()
self.b_drop.set_button(1)
self.b_burst.set_button(0)
self.in_rate.set_input('2')
@@ -77,9 +71,14 @@ class VideoBagOfTricks:
self.in_file.set_input('film.video')
def openvideo(self):
- self.video = sv.OpenVideo()
- param = [SV.BROADCAST, 0]
- self.video.GetParam(param)
+ try:
+ self.video = sv.OpenVideo()
+ except sv.error, msg:
+ print 'Error opening video:', msg
+ self.video = None
+ #sys.exit(1)
+ 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
@@ -118,9 +117,12 @@ class VideoBagOfTricks:
def settitle(self):
gl.winset(self.window)
- gl.wintitle(self.maketitle())
+ x, y = gl.getsize()
+ title = 'Vb:' + self.in_file.get_input() + ' (%dx%d)' % (x, y)
+ gl.wintitle(title)
def bindvideo(self):
+ if not self.video: return
x, y = gl.getsize()
self.video.SetSize(x, y)
drop = self.b_drop.get_button()
@@ -128,7 +130,7 @@ class VideoBagOfTricks:
param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF]
else:
param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON]
- if self.getformat()[:3] == 'rgb':
+ if self.rgb:
param = param+[SV.COLOR, SV.DEFAULT_COLOR, \
SV.DITHER, 1, \
SV.INPUT_BYPASS, 0]
@@ -150,35 +152,47 @@ class VideoBagOfTricks:
self.rebindvideo()
self.settitle()
- def cb_format(self, *args):
+ def get_format(self):
i = self.c_format.get_choice()
- label = format = formats[i-1]
- if '_' in format:
- i = string.find(format, '_')
- format = format[:i]
- if formatmap.has_key(format):
- format = formatmap[format]
+ label = Labels[i-1]
+ format = Formats[i-1]
self.format = format
#
- if label == 'mono_thresh':
- self.mono_use_thresh = 1
+ self.rgb = (format[:3] == 'rgb')
+ self.mono = (format == 'mono')
+ self.grey = (format[:4] == 'grey')
+ self.mono_use_thresh = (label == 'mono thresh')
+ s = format[4:]
+ if 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
+
+ def cb_format(self, *args):
+ self.get_format()
+ 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`)
- else:
- self.mono_use_thresh = 0
- #
+ fl.show_message('Bad input, using', \
+ `self.mono_thresh`, '')
self.rebindvideo()
- def getformat(self):
- return self.format
-
def cb_rate(self, *args):
pass
@@ -222,39 +236,103 @@ class VideoBagOfTricks:
gl.ringbell()
def cb_capture(self, *args):
+ if not self.video:
+ gl.ringbell()
+ return
+ if self.b_burst.get_button():
+ self.burst_capture()
+ else:
+ self.cont_capture()
+
+ def burst_capture(self):
self.setwatch()
- self.g_main.hide_object()
- self.cb_file() # Make sure filename is OK
- filename = self.in_file.get_input()
- format = self.getformat()
- vout = VFile.VoutFile().init(filename)
- vout.setformat(format)
gl.winset(self.window)
x, y = gl.getsize()
- vout.setsize(x, y)
- vout.writeheader()
- convertor = None
- if format[:4] == 'grey':
- s = format[4:]
- if s:
- greybits = string.atoi(s)
- else:
- greybits = 8
- # XXX Should get this from somewhere else?
- if greybits == 2:
- convertor = imageop.grey2grey2
- elif greybits == 4:
- convertor = imageop.grey2grey4
- elif greybits == -2:
- convertor = imageop.dither2grey2
- mono = (format == 'mono')
vformat = SV.RGB8_FRAMES
- qsize = 0
- rate = eval(self.in_rate.get_input())
+ try:
+ nframes = string.atoi(self.in_nframes.get_input())
+ except string.atoi_error:
+ nframes = 0
+ if nframes == 0:
+ try:
+ maxmem = \
+ float(eval(self.in_maxmem.get_input()))
+ except:
+ maxmem = 1.0
+ memsize = int(maxmem * 1024 * 1024)
+ nframes = calcnframes(x, y, \
+ self.mono or self.grey, memsize)
+ print 'nframes =', nframes
+ rate = string.atoi(self.in_rate.get_input())
+ # XXX Should check ranges and not crash if non-integer
+ info = (vformat, x, y, nframes, rate)
+ try:
+ info2, data, bitvec = self.video.CaptureBurst(info)
+ except sv.error, msg:
+ fl.show_message('Capture error:', str(msg), '')
+ self.setarrow()
+ return
+ print info2
+ self.save_burst(info2, data, bitvec)
+ self.setarrow()
+
+ def save_burst(self, info, data, bitvec):
+ (vformat, x, y, nframes, rate) = info
+ self.open_file()
+ 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, nframes*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]
+ realframeno = realframeno + 1
+ fn = int(realframeno*tpf)
+ if not self.write_frame(fn, field):
+ break
+ #print okstretch, 'ok',
+ #print skipstretch, 'skipped'
+ #print 'Skipped', nskipped, 'duplicate frames'
+ self.close_file()
+
+ def cont_capture(self):
+ self.setwatch()
+ self.g_main.hide_object()
+ self.open_file()
+ vformat = SV.RGB8_FRAMES
+ qsize = 1 # XXX Should be an option?
+ try:
+ rate = string.atoi(self.in_rate.get_input())
+ except string.atoi_error:
+ rate = 2
+ x, y = self.vout.getsize()
info = (vformat, x, y, qsize, rate)
ids = []
- tpf = 50
- self.video.InitContinuousCapture(info)
+ 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
+ info2 = self.video.InitContinuousCapture(info)
+ if info2 <> info:
+ print 'Info mismatch: requested', info, 'got', info2
self.capturing = 1
self.g_stop.show_object()
self.setarrow()
@@ -273,37 +351,75 @@ class VideoBagOfTricks:
data = cd.InterleaveFields(1)
cd.UnlockCaptureData()
t = id*tpf
- if convertor:
- data = convertor(data, len(data), 1)
- elif 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:
- vout.writeframe(t, data, None)
- except IOError, msg:
- if msg == (0, 'Error 0'):
- msg = 'disk full??'
- fl.show_message('IOError: ' + str(msg))
+ if not self.write_frame(t, data):
break
self.setwatch()
self.g_stop.hide_object()
self.capturing = 0
- vout.close()
self.video.EndContinuousCapture()
+ self.close_file()
self.g_main.show_object()
self.setarrow()
+ def open_file(self):
+ gl.winset(self.window)
+ x, y = gl.getsize()
+ self.cb_file() # Make sure filename is OK
+ filename = self.in_file.get_input()
+ vout = VFile.VoutFile().init(filename)
+ vout.setformat(self.format)
+ vout.setsize(x, y)
+ if self.b_burst.get_button():
+ vout.setpf((1, -2))
+ vout.writeheader()
+ self.vout = vout
+
+ def close_file(self):
+ try:
+ self.vout.close()
+ except IOError, msg:
+ if msg == (0, 'Error 0'):
+ msg = 'disk full??'
+ fl.show_message('IOError', str(msg), '')
+ del self.vout
+
+ def write_frame(self, t, data):
+ 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(t, data, None)
+ except IOError, msg:
+ if msg == (0, 'Error 0'):
+ msg = 'disk full??'
+ fl.show_message('IOError', str(msg), '')
+ return 0
+ return 1
+
def cb_quit(self, *args):
raise SystemExit, 0
- def maketitle(self):
- x, y = gl.getsize()
- return 'Vb:' + self.in_file.get_input() + ' (%dx%d)' % (x, y)
+ def setwatch(self):
+ gl.winset(self.form.window)
+ gl.setcursor(WATCH, 0, 0)
+
+ def setarrow(self):
+ gl.winset(self.form.window)
+ gl.setcursor(ARROW, 0, 0)
+
+def calcnframes(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)
try:
main()