New modules LiveVideo{In,Out} (interfaces will change!).

New programs V{send,receive} to send/receive video over UDP.
Comment typo changed in Vaddcache.
This commit is contained in:
Guido van Rossum 1992-09-22 17:23:17 +00:00
parent 42e07afe3d
commit ba06615c9f
5 changed files with 320 additions and 1 deletions

95
Demo/sgi/video/LiveVideoIn.py Executable file
View File

@ -0,0 +1,95 @@
# 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.
# Parameters:
# - vw, vh specify the size of the video window.
# This initializes continuous capture.
def init(self, pktmax, vw, vh):
if not have_video:
raise RuntimeError, 'no video available'
realvw = vh*SV.PAL_XMAX/SV.PAL_YMAX
if realvw < vw:
print 'Funny, image too narrow...'
self.realwidth, self.realheight = v.QuerySize(realvw, vh)
##print 'Recording video in size', \
## self.realwidth, self.realheight
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.width
self.pktsize = self.lpp*self.width
##print 'lpp =', self.lpp, '; pktsize =', self.pktsize
# Initialize capture
v.SetSize(self.realwidth, self.realheight)
dummy = v.InitContinuousCapture(SV.RGB8_FRAMES, \
self.realwidth, self.realheight, 2, 5)
self.data = None
self.lpos = 0
return self
# Remove an instance.
# This turns off continuous capture.
def close(self):
v.EndContinuousCapture()
# 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:
try:
cd, id = v.GetCaptureData()
except sv.error:
return None
data = cd.InterleaveFields(1)
cd.UnlockCaptureData()
self.data = imageop.crop(data, 1, \
self.realwidth, \
self.realheight, \
self.x0, self.y0, \
self.x1, self.y1)
self.lpos = 0
data = self.data[:self.pktsize]
self.data = self.data[self.pktsize:]
lpos = self.lpos
self.lpos = self.lpos + self.lpp
return lpos, data

56
Demo/sgi/video/LiveVideoOut.py Executable file
View File

@ -0,0 +1,56 @@
# Live video output (display video on the screen, presumably from the net)
import gl
from VFile import Displayer
# Video output (displayer) class.
class LiveVideoOut:
def init(self, wid, xywh, vw, vh):
##print 'Init', wid, xywh
##print 'video', vw, vw
self.vw = vw
self.vh = vh
self.disp = Displayer().init()
info = ('rgb8', 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.resize(xywh)
gl.winset(oldwid)
return self
def resize(self, (x, y, w, h)):
oldwid = gl.winget()
gl.winset(self.wid)
##print 'Resize', x, y, w, h
gl.winposition(x, x+w-1, y, y+h-1)
gl.reshapeviewport()
if w < self.vw or h < self.vh:
self.toosmall = 1
else:
self.disp.xorigin = (w-self.vw)/2
self.disp.yorigin = (h-self.vh)/2
self.toosmall = 0
##print 'VIDEO OFFSET:', \
## self.disp.xorigin, self.disp.yorigin
self.disp.clear()
gl.winset(oldwid)
def putnextpacket(self, pos, data):
if self.toosmall:
return
oldwid = gl.winget()
gl.winset(self.wid)
nline = len(data)/self.vw
if nline*self.vw <> len(data):
print 'Incorrect-sized video fragment'
self.disp.showpartframe(data, None, (0, pos, self.vw, nline))
gl.winset(oldwid)
def close(self):
print 'Done video out'

View File

@ -10,7 +10,7 @@
# Options: # Options:
# #
# file ... : file(s) to inspect; default film.video # file ... : file(s) to modify; default film.video
import sys import sys

74
Demo/sgi/video/Vreceive.py Executable file
View File

@ -0,0 +1,74 @@
#!/ufs/guido/bin/sgi/python-405
# Receive live video UDP packets.
# Usage: Vreceive [port]
import sys
import struct
from socket import *
import select
import gl, GL, DEVICE
sys.path.append('/ufs/guido/src/video')
import LiveVideoOut
PKTMAX = 16*1024
WIDTH = 400
HEIGHT = 300
HOST = ''
PORT = 5555
def main():
port = PORT
if sys.argv[1:]:
port = eval(sys.argv[1])
width, height = WIDTH, HEIGHT
gl.foreground()
gl.prefsize(width, height)
wid = gl.winopen('Vreceive')
gl.qdevice(DEVICE.ESCKEY)
gl.qdevice(DEVICE.WINSHUT)
gl.qdevice(DEVICE.WINQUIT)
x, y = gl.getorigin()
lvo = LiveVideoOut.LiveVideoOut().init(wid, (x, y, width, height), \
width, height)
s = socket(AF_INET, SOCK_DGRAM)
s.bind(HOST, port)
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:
gl.clear()
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
width, height = w, h
lvo.close()
lvo = LiveVideoOut.LiveVideoOut() \
.init(wid, (x, y, width, height), \
width, height)
lvo.putnextpacket(pos, data[6:])
else:
x = select.select(selectargs)
lvo.close()
main()

94
Demo/sgi/video/Vsend.py Executable file
View File

@ -0,0 +1,94 @@
#!/ufs/guido/bin/sgi/python-405
# Send live video UDP packets.
# Usage: Vsend [host [port]]
import sys
import time
import struct
from socket import *
import gl, GL, DEVICE
sys.path.append('/ufs/guido/src/video')
import LiveVideoIn
import LiveVideoOut
PKTMAX_UCAST = 16*1024 - 6
PKTMAX_BCAST = 1450
WIDTH = 400
HEIGHT = 300
HOST = '<broadcast>'
PORT = 5555
def main():
if not LiveVideoIn.have_video:
print 'Sorry, no video (use python-405 on roos)'
sys.exit(1)
host = HOST
port = PORT
if sys.argv[1:]:
host = sys.argv[1]
if sys.argv[2:]:
port = eval(sys.argv[2])
if host == '<broadcast>':
pktmax = PKTMAX_BCAST
else:
pktmax = PKTMAX_UCAST
gl.foreground()
gl.prefsize(WIDTH, HEIGHT)
wid = gl.winopen('Vsend')
gl.keepaspect(WIDTH, HEIGHT)
gl.stepunit(8, 6)
gl.winconstraints()
gl.qdevice(DEVICE.ESCKEY)
gl.qdevice(DEVICE.WINSHUT)
gl.qdevice(DEVICE.WINQUIT)
width, height = gl.getsize()
x, y = gl.getorigin()
lvo = LiveVideoOut.LiveVideoOut().init(wid, (x, y, width, height), \
width, height)
lvi = LiveVideoIn.LiveVideoIn().init(pktmax, width, height)
s = socket(AF_INET, SOCK_DGRAM)
s.allowbroadcast(1)
while 1:
if gl.qtest():
dev, val = gl.qread()
if dev in (DEVICE.ESCKEY, \
DEVICE.WINSHUT, DEVICE.WINQUIT):
break
if dev == DEVICE.REDRAW:
w, h = gl.getsize()
x, y = gl.getorigin()
if (w, h) <> (width, height):
lvi.close()
width, height = w, h
lvi = LiveVideoIn.LiveVideoIn() \
.init(pktmax, width, height)
lvo.close()
lvo = LiveVideoOut.LiveVideoOut() \
.init(wid, \
(x, y, width, height), \
width, height)
rv = lvi.getnextpacket()
if not rv:
time.millisleep(10)
continue
pos, data = rv
lvo.putnextpacket(pos, data)
hdr = struct.pack('hhh', pos, width, height)
s.sendto(hdr + data, (host, port))
lvi.close()
lvo.close()
main()