mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-01 22:21:13 +00:00
overrides: fix callback setter overrides (bis)
The previous commit broke those by trying to pass weak refs through pygobject, but we should probably have tested the elements beyond instantiation: weakref.WeakMethod returns a callable, but that callable when called only returns the ephemeral bound method, which is the object we want to call, but pygobject has no support for that. Instead, fix the memory leaks we were going after by decoupling the lifecycle of the callback and that of the pad, by passing functors to pygobject.
This commit is contained in:
parent
34e0e3ce11
commit
c04bb945b0
1 changed files with 19 additions and 22 deletions
|
@ -140,42 +140,39 @@ class Caps(Gst.Caps):
|
|||
Caps = override(Caps)
|
||||
__all__.append('Caps')
|
||||
|
||||
class Pad(Gst.Pad):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._real_chain_func = None
|
||||
self._real_event_func = None
|
||||
self._real_query_func = None
|
||||
super(Gst.Pad, self).__init__(*args, **kwargs)
|
||||
class PadFunc:
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def _chain_override(self, pad, parent, buf):
|
||||
return self._real_chain_func(pad, buf)
|
||||
def __call__(self, pad, parent, obj):
|
||||
if isinstance(self.func, weakref.WeakMethod):
|
||||
func = self.func()
|
||||
else:
|
||||
func = self.func
|
||||
|
||||
def _event_override(self, pad, parent, event):
|
||||
return self._real_event_func(pad, event)
|
||||
|
||||
def _query_override(self, pad, parent, query):
|
||||
try:
|
||||
res = self._real_query_func(pad, query)
|
||||
res = func(pad, obj)
|
||||
except TypeError:
|
||||
try:
|
||||
res = self._real_query_func(pad, parent, query)
|
||||
res = func(pad, parent, obj)
|
||||
except TypeError:
|
||||
raise TypeError("Invalid query method %s, 2 or 3 arguments required"
|
||||
% self._real_query_func)
|
||||
raise TypeError("Invalid method %s, 2 or 3 arguments required"
|
||||
% func)
|
||||
|
||||
return res
|
||||
|
||||
class Pad(Gst.Pad):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Gst.Pad, self).__init__(*args, **kwargs)
|
||||
|
||||
def set_chain_function(self, func):
|
||||
self._real_chain_func = func
|
||||
self.set_chain_function_full(weakref.WeakMethod(self._chain_override), None)
|
||||
self.set_chain_function_full(PadFunc(func), None)
|
||||
|
||||
def set_event_function(self, func):
|
||||
self._real_event_func = func
|
||||
self.set_event_function_full(weakref.WeakMethod(func), None)
|
||||
self.set_event_function_full(PadFunc(func), None)
|
||||
|
||||
def set_query_function(self, func):
|
||||
self._real_query_func = func
|
||||
self.set_query_function_full(weakref.WeakMethod(self._query_override), None)
|
||||
self.set_query_function_full(PadFunc(func), None)
|
||||
|
||||
def query_caps(self, filter=None):
|
||||
return Gst.Pad.query_caps(self, filter)
|
||||
|
|
Loading…
Reference in a new issue