/usr/share/sugar/activities/Physics.activity/olpcgames/video.py is in sugar-physics-activity 7+dfsg-1.2.
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | """Video widget for displaying a gstreamer pipe
Note: currently this module is not all that elegant or useful,
we need a better recipe for using and working with Video
under OLPCGames.
"""
import logging
log = logging.getLogger( 'olpcgames.video' )
#log.setLevel( logging.INFO )
import os
import signal
import pygame
import weakref
import olpcgames
from olpcgames import _gtkmain
import pygtk
pygtk.require('2.0')
import gtk
import gst
class VideoWidget(gtk.DrawingArea):
"""Widget to render GStreamer video over our Pygame Canvas
The VideoWidget is a simple GTK window which is
held by the PygameCanvas, just as is the Pygame
window we normally use. As such this approach
*cannot* work without the GTK wrapper.
It *should* be possible to use raw X11 operations
to create a child window of the Pygame/SDL window
and use that for the same purpose, but that would
require some pretty low-level ctypes hacking.
Attributes of Note:
rect -- Pygame rectangle which tells us where to
display ourselves, setting the rect changes the
position and size of the window.
"""
_imagesink = None
_renderedRect = None
def __init__(self, rect=None, force_aspect_ratio=True):
super(VideoWidget, self).__init__()
self.unset_flags(gtk.DOUBLE_BUFFERED)
if rect is None:
rect = pygame.Rect( (0,0), (160,120))
self.rect = rect
self.force_aspect_ratio = force_aspect_ratio
self.set_size_request(rect.width,rect.height)
olpcgames.WIDGET.put( self, rect.left,rect.top)
self._renderedRect = rect
self.show()
def set_rect( self, rect ):
"""Set our rectangle (area of the screen)"""
log.debug( 'Set rectangle: %s', rect )
self.set_size_request(rect.width,rect.height)
olpcgames.WIDGET.move( self, rect.left,rect.top)
self.rect = rect
def do_expose_event(self, event):
"""Handle exposure event (trigger redraw by gst)"""
if self._imagesink:
self._imagesink.expose()
return False
else:
return True
def set_sink(self, sink):
"""Set our window-sink for output"""
assert self.window.xid
self._imagesink = sink
self._imagesink.set_xwindow_id(self.window.xid)
self._imagesink.set_property('force-aspect-ratio', self.force_aspect_ratio)
class PygameWidget( object ):
"""Render "full-screen" video to the entire Pygame screen
Not particularly useful unless this happens to be exactly what you need.
"""
def __init__( self ):
try:
window_id = pygame.display.get_wm_info()['window']
except KeyError, err: # pygame-ctypes...
window_id = int(os.environ['SDL_WINDOWID'])
self.window_id = window_id
self._imagesink = None
#self._holder = _gtkmain.Holder()
def set_sink( self, sink ):
"""Set up our gst sink"""
log.info( 'Setting sink: %s', sink )
self._imagesink = sink
sink.set_xwindow_id( self.window_id )
#pipe_desc = 'v4l2src ! video/x-raw-yuv,width=160,height=120 ! ffmpegcolorspace ! xvimagesink'
class Player(object):
pipe_desc = 'v4l2src ! ffmpegcolorspace ! video/x-raw-yuv ! xvimagesink'
test_pipe_desc = 'videotestsrc ! ffmpegcolorspace ! video/x-raw-yuv ! xvimagesink'
_synchronized = False
def __init__(self, videowidget, pipe_desc=pipe_desc):
self._playing = False
self._videowidget = videowidget
self._pipeline = gst.parse_launch(pipe_desc)
bus = self._pipeline.get_bus()
bus.enable_sync_message_emission()
bus.add_signal_watch()
bus.connect('sync-message::element', self.on_sync_message)
bus.connect('message', self.on_message)
def play(self):
log.info( 'Play' )
if self._playing == False:
self._pipeline.set_state(gst.STATE_PLAYING)
self._playing = True
def pause(self):
log.info( 'Pause' )
if self._playing == True:
if self._synchronized:
log.debug( ' pause already sync\'d' )
self._pipeline.set_state(gst.STATE_PAUSED)
self._playing = False
def stop( self ):
"""Stop all playback"""
self._pipeline.set_state( gst.STATE_NULL )
def on_sync_message(self, bus, message):
log.info( 'Sync: %s', message )
if message.structure is None:
return
if message.structure.get_name() == 'prepare-xwindow-id':
self._synchronized = True
self._videowidget.set_sink(message.src)
def on_message(self, bus, message):
log.info( 'Message: %s', message )
t = message.type
if t == gst.MESSAGE_ERROR:
err, debug = message.parse_error()
log.warn("Video error: (%s) %s" ,err, debug)
self._playing = False
if __name__ == "__main__":
# Simple testing code...
logging.basicConfig()
log.setLevel( logging.DEBUG )
from pygame import image,display, event
import pygame
def main():
display.init()
maxX,maxY = display.list_modes()[0]
screen = display.set_mode( (maxX/3, maxY/3 ) )
display.flip()
pgw = PygameWidget( )
p = Player( pgw, pipe_desc=Player.test_pipe_desc )
p.play()
clock = pygame.time.Clock()
running = True
while running:
clock.tick( 60 )
for evt in [pygame.event.wait()] + pygame.event.get():
if evt.type == pygame.KEYDOWN:
if p._playing:
p.pause()
else:
p.play()
elif evt.type == pygame.QUIT:
p.stop()
running = False
#display.flip()
main()
|