Commit b05eaf19 authored by Jack Jansen's avatar Jack Jansen

DisplayVideoIn - Class similar to LiveVideoIn but sends data from

                 screen
Dsend - Main program analogous to Vsend to send data from display
parent 1d6821f5
# 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
return self
# 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
#!/ufs/guido/bin/sgi/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().init(wid, width, height, vtype)
lvi = DisplayVideoIn.DisplayVideoIn().init(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.millisleep(10)
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()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment