mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-05 17:09:48 +00:00
GstPad: Use gst_pad_set_blocked_async_full() if available.
Avoids leaking arguments. Fixes #514717
This commit is contained in:
parent
c09e3207bc
commit
51ac26b86c
2 changed files with 63 additions and 29 deletions
|
@ -24,6 +24,17 @@
|
|||
%%
|
||||
headers
|
||||
|
||||
#if ((GST_VERSION_MAJOR > 0) || \
|
||||
(GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR > 10) || \
|
||||
(GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 10 && \
|
||||
GST_VERSION_MICRO >= 23) || \
|
||||
(GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 10 && \
|
||||
GST_VERSION_MICRO == 22 && GST_VERSION_NANO > 0))
|
||||
#define HAVE_SET_BLOCKED_ASYNC_FULL 1
|
||||
#else
|
||||
#define HAVE_SET_BLOCKED_ASYNC_FULL 0
|
||||
#endif
|
||||
|
||||
/* we need to do this until PyClosures get exception handlers */
|
||||
#ifndef pyg_closure_set_exception_handler
|
||||
# define pyg_closure_set_exception_handler(ig, nore)
|
||||
|
@ -1331,6 +1342,16 @@ _wrap_gst_pad_get_query_types_default (PyGObject *self)
|
|||
%%
|
||||
override gst_pad_set_blocked_async args
|
||||
|
||||
#if HAVE_SET_BLOCKED_ASYNC_FULL
|
||||
static void
|
||||
pad_block_destroy_data (gpointer data)
|
||||
{
|
||||
PyObject *py_data = (PyObject *) data;
|
||||
|
||||
Py_DECREF (py_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
pad_block_callback_marshal(GstPad *pad, gboolean blocked, gpointer user_data)
|
||||
{
|
||||
|
@ -1397,8 +1418,14 @@ _wrap_gst_pad_set_blocked_async (PyGObject *self, PyObject *args)
|
|||
if (data == NULL)
|
||||
return NULL;
|
||||
pyg_begin_allow_threads;
|
||||
#if HAVE_SET_BLOCKED_ASYNC_FULL
|
||||
ret = gst_pad_set_blocked_async_full (GST_PAD (self->obj), blocked,
|
||||
(GstPadBlockCallback) pad_block_callback_marshal, data,
|
||||
pad_block_destroy_data);
|
||||
#else
|
||||
ret = gst_pad_set_blocked_async (GST_PAD (self->obj), blocked,
|
||||
(GstPadBlockCallback) pad_block_callback_marshal, data);
|
||||
#endif
|
||||
pyg_end_allow_threads;
|
||||
if (ret)
|
||||
pret = Py_True;
|
||||
|
|
|
@ -516,40 +516,47 @@ class PadRefCountTest(TestCase):
|
|||
self.assertEquals(self.gccollect(), 1) # collected the pad
|
||||
gst.debug('going into teardown')
|
||||
|
||||
# re-enable this test once #514717 is fixed
|
||||
class PadBlockTest(TestCase):
|
||||
def testCallbackFlush(self):
|
||||
# check that the same block callback can be called more than once (weird
|
||||
# test but it was broken)
|
||||
|
||||
# class PadBlockRefcountTest(TestCase):
|
||||
# def testCallbackRefcount(self):
|
||||
# def blocked_cb(pad, blocked):
|
||||
# self.assertTrue(pad.set_blocked_async(False, unblocked_cb))
|
||||
def blocked_cb(pad, blocked):
|
||||
pad.push_event(gst.event_new_flush_start())
|
||||
|
||||
pad = gst.Pad('src', gst.PAD_SRC)
|
||||
pad.set_active(True)
|
||||
pad.set_blocked_async(True, blocked_cb)
|
||||
|
||||
# def unblocked_cb(pad, blocked):
|
||||
# pass
|
||||
for i in xrange(10):
|
||||
buf = gst.Buffer('ciao')
|
||||
pad.push(buf)
|
||||
pad.push_event(gst.event_new_flush_stop())
|
||||
|
||||
# cb_refcount = sys.getrefcount(blocked_cb)
|
||||
# # sys.getrefcount() returns refcount + 1
|
||||
# self.assertEquals(cb_refcount, 2)
|
||||
def testCallbackRefcount(self):
|
||||
def blocked_cb(pad, blocked):
|
||||
pad.set_blocked_async(False, unblocked_cb)
|
||||
|
||||
# fakesrc = gst.element_factory_make('fakesrc')
|
||||
# fakesrc.props.num_buffers = 2
|
||||
# fakesink = gst.element_factory_make('fakesink')
|
||||
|
||||
# pipeline = gst.Pipeline()
|
||||
# pipeline.add(fakesrc, fakesink)
|
||||
|
||||
# fakesrc.link(fakesink)
|
||||
|
||||
# pad = fakesrc.get_pad('src')
|
||||
# pad.set_blocked_async(True, blocked_cb)
|
||||
|
||||
# pipeline.set_state(gst.STATE_PLAYING)
|
||||
# pipeline.get_bus().poll(gst.MESSAGE_EOS, -1)
|
||||
# pipeline.set_state(gst.STATE_NULL)
|
||||
|
||||
# # check that we don't leak a ref to the callback
|
||||
# cb_refcount_after = sys.getrefcount(blocked_cb)
|
||||
# self.assertEquals(cb_refcount_after, cb_refcount)
|
||||
def unblocked_cb(pad, blocked):
|
||||
pass
|
||||
|
||||
cb_refcount = sys.getrefcount(blocked_cb)
|
||||
# sys.getrefcount() returns refcount + 1
|
||||
self.assertEquals(cb_refcount, 2)
|
||||
|
||||
pad = gst.Pad('src', gst.PAD_SRC)
|
||||
pad.set_active(True)
|
||||
pad.set_blocked_async(True, blocked_cb)
|
||||
# set_blocked_async refs the callback
|
||||
self.assertEquals(sys.getrefcount(blocked_cb), 3)
|
||||
|
||||
buf = gst.Buffer('ciao')
|
||||
pad.push(buf)
|
||||
|
||||
# in blocked_cb() we called set_blocked_async() with a different
|
||||
# callback, so blocked_cb() should have been unreffed
|
||||
cb_refcount_after = sys.getrefcount(blocked_cb)
|
||||
self.assertEquals(sys.getrefcount(blocked_cb), cb_refcount)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in a new issue