# 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:]