From b05eaf19093446e7aa00d0ad432be11740806c35 Mon Sep 17 00:00:00 2001 From: Jack Jansen Date: Wed, 17 Feb 1993 15:58:49 +0000 Subject: DisplayVideoIn - Class similar to LiveVideoIn but sends data from screen Dsend - Main program analogous to Vsend to send data from display --- Demo/sgi/video/DisplayVideoIn.py | 100 +++++++++++++++++++++ Demo/sgi/video/Dsend.py | 189 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100755 Demo/sgi/video/DisplayVideoIn.py create mode 100755 Demo/sgi/video/Dsend.py diff --git a/Demo/sgi/video/DisplayVideoIn.py b/Demo/sgi/video/DisplayVideoIn.py new file mode 100755 index 0000000..427d30a --- /dev/null +++ b/Demo/sgi/video/DisplayVideoIn.py @@ -0,0 +1,100 @@ +# 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 diff --git a/Demo/sgi/video/Dsend.py b/Demo/sgi/video/Dsend.py new file mode 100755 index 0000000..3213caa --- /dev/null +++ b/Demo/sgi/video/Dsend.py @@ -0,0 +1,189 @@ +#!/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 = '' + 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() -- cgit v0.12