[gst-devel] optimizing pyGst for screen grabs

Erik Blankinship erikb at mediamods.com
Thu Oct 14 18:08:12 CEST 2010


My pyGst application plays an ogv file and grabs frames as pixbufs when I
call screen_grab.

Unfortunately, this pipeline encodes every frame into jpeg!  I have tried
unsuccessfully to unlink the fake_queue from the tee (so that it can be
re-attached when screen_grab is called).  The video freezes instead!

Any suggestions?


import gtk
import pygtk
pygtk.require('2.0')
import sys
import pygst
pygst.require('0.10')
import gst
import gst.interfaces
import gobject
gobject.threads_init()


class VidPlayback:

def __init__(self):
self.window = None
self.playing = False

self.picExposureOpen = False

self.pipeline = gst.Pipeline( )
self.player = gst.element_factory_make( "playbin", "playbin" )
self.pipeline.add( self.player )

self.sink_bin = gst.Bin( )
self.player.set_property( "video-sink", self.sink_bin )

self.sink_tee = gst.element_factory_make( "tee" )
self.sink_bin.add( self.sink_tee )

sink_tee_pad = self.sink_tee.get_pad( "sink" )
ghost_tee_pad = gst.GhostPad( "sink", sink_tee_pad )
self.sink_bin.add_pad( ghost_tee_pad )

self.add_video_sink( )
self.add_fake_sink( )

bus = self.pipeline.get_bus( )
bus.enable_sync_message_emission( )
bus.add_signal_watch( )
bus.connect( 'sync-message::element', self._onSyncMessageCb )
bus.connect( 'message', self._onMessageCb )

def add_video_sink( self ):
queue = gst.element_factory_make( "queue" )
sink = gst.element_factory_make( "xvimagesink", "xvimagesink" )
self.sink_bin.add( queue, sink )
gst.element_link_many( self.sink_tee, queue, sink )

def add_fake_sink( self ):
self.fake_queue = gst.element_factory_make( "queue" )
self.fake_queue.set_property( "leaky", True )
self.fake_queue.set_property( "max-size-buffers", 1 )

self.fake_colorspace = gst.element_factory_make( "ffmpegcolorspace",
"ffmpegcolorspace" )
self.fake_jpeg = gst.element_factory_make( "jpegenc", "jpegenc" )

self.fake_sink = gst.element_factory_make( "fakesink", "fakesink" )
self.HANDOFF_ID = self.fake_sink.connect( "handoff", self.handoff_cb )
self.fake_sink.set_property( "signal-handoffs", True )

self.sink_bin.add( self.fake_queue, self.fake_colorspace, self.fake_jpeg,
self.fake_sink )
gst.element_link_many( self.sink_tee, self.fake_queue, self.fake_colorspace,
self.fake_jpeg, self.fake_sink )


def screen_grab( self ):
if (self.picExposureOpen):
return
self.picExposureOpen = True


def handoff_cb( self, fsink, buffer, pad, user_data=None ):
if not self.picExposureOpen:
return

pic = gtk.gdk.pixbuf_loader_new_with_mime_type("image/jpeg")
pic.write( buffer )
pic.close( )
pixBuf = pic.get_pixbuf( )
del pic

print( "your pixBuf is ready: ", pixBuf )

self.picExposureOpen = False
return pixBuf

def _onMessageCb(self, bus, message):
t = message.type
if t == gst.MESSAGE_EOS:
pass
elif t == gst.MESSAGE_ERROR:
err, debug = message.parse_error( )
pass

def _onSyncMessageCb(self, bus, message):
if message.structure is None:
return True
if message.structure.get_name() == 'prepare-xwindow-id':
self.window.set_sink(message.src)
message.src.set_property('force-aspect-ratio', True)
return True

def setFile(self, path):
uri = "file://" + str( path )
if (self.player.get_property('uri') == uri):
self.seek(gst.SECOND*0)
return

self.player.set_state(gst.STATE_READY)
self.player.set_property('uri', uri)
self.play( )


def seek( self, time ):
event = gst.event_new_seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH |
gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, time, gst.SEEK_TYPE_NONE, 0)
res = self.pipeline.send_event(event)
if res:
self.pipeline.set_new_stream_time(0L)

def play(self):
self.playing = True
self.pipeline.set_state(gst.STATE_PLAYING)


def stop(self):
self.playing = False
self.pipeline.set_state(gst.STATE_NULL)


class PlayVideoWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)

self.imagesink = None
self.unset_flags(gtk.DOUBLE_BUFFERED)
self.set_flags(gtk.APP_PAINTABLE)


def set_sink(self, sink):
if (self.imagesink != None):
assert self.window.xid
self.imagesink = None
del self.imagesink

self.imagesink = sink
self.imagesink.set_xwindow_id(self.window.xid)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20101014/b45064ad/attachment.htm>


More information about the gstreamer-devel mailing list