1. Do not inherit from clutter.Texture. I think you are creating a
circular reference here so your class has to be garbage collected
instead of ref count-deleted (which will be slower to happen).
self.sink = cluttergst.VideoSink(self) # circ ref???
I couldn't get this thing to be garbage collected for some reason (
Player::__del__ is not called if you inherited, even when you do a
gc.collect() )
BTW, gst.Pipeline() creates a new thread, and you are passing some data
around between threads here as well.
2. It seems you need to do pipeline.set_state(gst.STATE_NULL) BEFORE you
unref myplayer. This is likely a bug in gstreamer.
So for example, this one seems to work for me:
import clutter
from clutter import cluttergst
import gst
#import gc
myplayer = None
class Player():
def __init__(self):
self.texture = clutter.Texture()
self.pipeline = gst.Pipeline()
self.src = gst.element_factory_make("audiotestsrc")
self.goom = gst.element_factory_make("goom")
self.colorspace = gst.element_factory_make("ffmpegcolorspace")
self.sink = cluttergst.VideoSink(self.texture)
self.pipeline.add(self.src, self.goom, self.colorspace,
self.sink)
gst.element_link_many(self.src, self.goom, self.colorspace,
self.sink)
self.pipeline.set_state(gst.STATE_PLAYING)
def __del__(self):
### This is called BEFORE object is destroyed
print 'Player del'
self.pipeline.set_state(gst.STATE_NULL) #### IMPORTANT
#gc.collect()
def restart_player(a,b):
global myplayer
if myplayer:
print 'removing old player: %s' % myplayer
stage.remove(myplayer.texture)
myplayer = None
myplayer = Player()
print 'created new player: %s' % myplayer
myplayer.texture.show()
stage.add(myplayer.texture)
stage = clutter.stage_get_default()
stage.set_size(320,240)
stage.connect('key-press-event', restart_player)
stage.show_all()
clutter.main()
-Ashwin
-----Original Message-----
From: Emmanuele Bassi [mailto:[EMAIL PROTECTED]
Sent: Wednesday, February 06, 2008 5:01 PM
To: [email protected]
Subject: Re: [clutter] Memory leak with pyclutter
On Wed, 2008-02-06 at 23:40 +0200, Tero Saarni wrote:
> Hi,
>
> I have a Clutter based Python application that leaks a lot of memory.
> Objects instantiated from my python classes inheriting from clutter
> never seem to get freed.
which version of python is it? 2.4 or 2.5? unfortunately, python is
known for leaking memory pool all around; 2.5 lessened the leaks, but
there are some issues with lists and tuples (for instance) that would
require a complete overhaul.
> I created a small example (modified from examples/videosink.py) that
> demonstrates the memory leak. Key press event on the stage window
> will assign over the previously created Player object which I assume
> should trigger the old one being garbage collected at some point.
in theory. in practise, it's better if you explicitly call del() on the
variable before reassigning it.
> However there seems to be some references that keep the objects in
> memory forever.
it is possible that the bindings keep a reference too much; it's mostly
autogenerated code, though.
> After running this loop couple of times the process reserves all my
> memory (be careful not getting your computer completely unresponsive).
>
>
> import clutter
> from clutter import cluttergst
> import gst
>
> myplayer = None
>
> class Player(clutter.Texture):
>
> def __init__(self):
> super(Player, self).__init__()
>
> self.pipeline = gst.Pipeline()
> self.src = gst.element_factory_make("audiotestsrc")
> self.goom = gst.element_factory_make("goom")
> self.colorspace = gst.element_factory_make("ffmpegcolorspace")
> self.sink = cluttergst.VideoSink(self)
>
> self.pipeline.add(self.src, self.goom, self.colorspace,
self.sink)
> gst.element_link_many(self.src, self.goom, self.colorspace,
self.sink)
> self.pipeline.set_state(gst.STATE_PLAYING)
>
>
>
> def restart_player(a,b):
> global myplayer
> if myplayer:
> print 'removing old player: %s' % myplayer
> stage.remove(myplayer)
> myplayer = Player()
> print 'created new player: %s' % myplayer
> myplayer.show()
> stage.add(myplayer)
you miss a:
return True
at the end of the event handler.
> I must be missing something obvious... All help is appreciated! :)
as I said, it can be either:
1. a bug in python
2. a bug in the pygobject/pygst bindings
3. a bug in pyclutter
yours is also somewhat a corner case: you should reuse the Player class
and change the source instead of removing/adding the entire actor every
time.
I'd appreciate if you could run valgrind on the script; I'll have a go
as soon as I can.
ciao,
Emmanuele.
--
Emmanuele Bassi, OpenedHand Ltd.
Unit R, Homesdale Business Centre
216-218 Homesdale Rd., Bromley - BR12QZ
http://www.o-hand.com
--
To unsubscribe send a mail to [EMAIL PROTECTED]
--
To unsubscribe send a mail to [EMAIL PROTECTED]