/usr/share/pyshared/glitch/gst/video.py is in python-glitch 0.6-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | "Upload GStreamer video data as textures."
import gst, gobject
import OpenGL.GL as gl
from glitch.texture import ApplyTexture, Texture, TexturedSquare
class VideoTexture(Texture, gobject.GObject):
"Abstract base class for GStreamer-based video textures."
__gsignals__ = {
'new-buffer': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_PYOBJECT,))
}
internal_format = gl.GL_RGB
format = gl.GL_RGB
y_flip = True
def __init__(self):
gobject.GObject.__init__(self)
Texture.__init__(self, None, None, None)
self.bin = self.make_bin()
self.appsink = self.bin.get_by_name('appsink')
self.appsink.props.emit_signals = True
self.new_buffer_handler = \
self.appsink.connect('new-buffer', self.pull_buffer)
self.buffer = None
def make_bin(self):
"""
Called to create the GStreamer bin.
The bin should have an appsink called "appsink".
"""
raise NotImplementedError
def pull_buffer(self, appsink):
if self.width is None:
pad = appsink.get_pad('sink')
caps = pad.get_negotiated_caps()
self.width = caps[0]['width']
self.height = caps[0]['height']
self.buffer = appsink.emit('pull-buffer')
self.version += 1
self.data = self.buffer.data
self.emit('new-buffer', self.buffer)
def stop(self):
self.appsink.disconnect(self.new_buffer_handler)
def upload(self, ctx):
if self.buffer is not None:
Texture.upload(self, ctx)
class VideoFileTexture(VideoTexture):
"Load a video from a file."
def __init__(self, path):
self.path = path
VideoTexture.__init__(self)
def make_bin(self):
bin = gst.parse_bin_from_description('''
filesrc name=filesrc !
decodebin name=decodebin !
videoscale !
ffmpegcolorspace !
video/x-raw-rgb,bpp=24 !
appsink name=appsink
''', False)
filesrc = bin.get_by_name('filesrc')
filesrc.props.location = self.path
return bin
class Video(ApplyTexture):
"Utility to show a video in a square."
def __init__(self, texture, **kw):
assert 'children' not in kw
ApplyTexture.__init__(self, texture, **kw)
self.texture = texture
# XXX: Perhaps this should be TexturedRectangle.
self.children = [TexturedSquare()]
def _no_video(self):
# XXX: Perhaps it should be possible to disable this.
gl.glBegin(gl.GL_LINE_STRIP)
gl.glVertex2f(1, 1)
gl.glVertex2f(1, 0)
gl.glVertex2f(0, 0)
gl.glVertex2f(0, 1)
gl.glVertex2f(1, 1)
gl.glEnd()
gl.glBegin(gl.GL_LINES)
gl.glVertex2f(1, 1)
gl.glVertex2f(0, 0)
gl.glVertex2f(1, 0)
gl.glVertex2f(0, 1)
gl.glEnd()
def render(self, ctx):
if self.texture.buffer is None:
self._no_video()
else:
ApplyTexture.render(self, ctx)
|