From 03f65e4179abbdc41608e3acbb64d58857beb6f4 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 13 Oct 2005 15:56:16 +0000 Subject: [PATCH] gst/: Updated to new API Original commit message from CVS: * gst/gst-types.defs: * gst/gst.defs: Updated to new API * gst/gstbus.override: bus.add_watch() now uses gst_bus_add_watch_full() using pyg_destroy_notify as the DestroyNotify function, thus enabling proper python garbage collection. * testsuite/common.py: Let's check refcounting of ALL gst.Object * testsuite/test_bin.py: Added debug * testsuite/test_bus.py: Added "message" signal version of test --- ChangeLog | 16 +++++ gst/gst-types.defs | 1 - gst/gst.defs | 7 +- gst/gstbus.override | 4 +- testsuite/common.py | 5 +- testsuite/test_bin.py | 8 +++ testsuite/test_bus.py | 162 +++++++++++++++++++++++++++++++++++++----- 7 files changed, 179 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0356846c38..cb2695aaa6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-10-13 Edward Hervey + + * gst/gst-types.defs: + * gst/gst.defs: + Updated to new API + * gst/gstbus.override: + bus.add_watch() now uses gst_bus_add_watch_full() using + pyg_destroy_notify as the DestroyNotify function, thus enabling + proper python garbage collection. + * testsuite/common.py: + Let's check refcounting of ALL gst.Object + * testsuite/test_bin.py: + Added debug + * testsuite/test_bus.py: + Added "message" signal version of test + 2005-10-13 Thomas Vander Stichele * gst/gstelement.override: diff --git a/gst/gst-types.defs b/gst/gst-types.defs index 265936ae2b..ca19e6e037 100644 --- a/gst/gst-types.defs +++ b/gst/gst-types.defs @@ -646,7 +646,6 @@ (gtype-id "GST_TYPE_MINI_OBJECT_FLAGS") (values '("readonly" "GST_MINI_OBJECT_FLAG_READONLY") - '("static" "GST_MINI_OBJECT_FLAG_STATIC") '("last" "GST_MINI_OBJECT_FLAG_LAST") ) ) diff --git a/gst/gst.defs b/gst/gst.defs index fb84ce17e6..a9d3c6b43b 100644 --- a/gst/gst.defs +++ b/gst/gst.defs @@ -1114,7 +1114,7 @@ (parameters '("GstState*" "state") '("GstState*" "pending") - '("GTimeVal*" "timeout") + '("GstClockTime" "timeout") ) ) @@ -1691,7 +1691,7 @@ '("GstFormat" "format") '("gint64" "start_value") '("gint64" "stop_value") - '("gint64" "base") + '("gint64" "stream_time") ) ) @@ -1700,11 +1700,12 @@ (c-name "gst_event_parse_newsegment") (return-type "none") (parameters + '("gboolean*" "update") '("gdouble*" "rate") '("GstFormat*" "format") '("gint64*" "start_value") '("gint64*" "end_value") - '("gint64*" "base") + '("gint64*" "stream_time") ) ) diff --git a/gst/gstbus.override b/gst/gstbus.override index 1c7ad54bc5..4ab6e967a2 100644 --- a/gst/gstbus.override +++ b/gst/gstbus.override @@ -206,8 +206,8 @@ _wrap_gst_bus_add_watch (PyGObject *self, PyObject *args) if (data == NULL) return NULL; - sigid = gst_bus_add_watch (GST_BUS (self->obj), - (GstBusFunc) bus_func, data); + sigid = gst_bus_add_watch_full (GST_BUS (self->obj), G_PRIORITY_DEFAULT, + (GstBusFunc) bus_func, data, (GDestroyNotify)pyg_destroy_notify); return PyInt_FromLong(sigid); } diff --git a/testsuite/common.py b/testsuite/common.py index 25226bcf33..7015aafe0a 100644 --- a/testsuite/common.py +++ b/testsuite/common.py @@ -110,7 +110,8 @@ def run_silent(function, *args, **kwargs): class TestCase(unittest.TestCase): - _types = [gst.Controller, gst.Object, gst.Element, gst.Pad, gst.Bus, gst.MiniObject] + _types = [gst.Object, gst.MiniObject] + _except_types = [gst.Registry, gst.Plugin, gst.PluginFeature] def gccollect(self): # run the garbage collector @@ -141,6 +142,8 @@ class TestCase(unittest.TestCase): objs = [o for o in gc.get_objects() if isinstance(o, c)] new.extend([o for o in objs if o not in self._tracked[c]]) + for u in self._except_types: + new = [o for o in new if not isinstance(o, u)] self.failIf(new, new) #self.failIf(new, ["%r:%d" % (type(o), id(o)) for o in new]) del self._tracked diff --git a/testsuite/test_bin.py b/testsuite/test_bin.py index 5dca82f238..dc06d55726 100644 --- a/testsuite/test_bin.py +++ b/testsuite/test_bin.py @@ -105,13 +105,21 @@ class BinAddRemove(TestCase): TestCase.tearDown(self) def testError(self): + gst.info("creating fakesrc") src = gst.element_factory_make('fakesrc', 'name') + gst.info("creating fakesink") sink = gst.element_factory_make('fakesink', 'name') + gst.info("adding src:%d to bin" % src.__gstrefcount__) + self.assertEqual(src.__gstrefcount__, 1) self.bin.add(src) + self.assertEqual(src.__gstrefcount__, 2) + gst.info("added src:%d" % src.__gstrefcount__) self.assertRaises(gst.AddError, self.bin.add, sink) self.assertRaises(gst.AddError, self.bin.add, src) self.assertRaises(gst.RemoveError, self.bin.remove, sink) + gst.info("removing src") self.bin.remove(src) + gst.info("removed") self.assertRaises(gst.RemoveError, self.bin.remove, src) def testMany(self): diff --git a/testsuite/test_bus.py b/testsuite/test_bus.py index ab3e2dc4b4..18eb70e86a 100644 --- a/testsuite/test_bus.py +++ b/testsuite/test_bus.py @@ -22,43 +22,72 @@ from common import gst, unittest, TestCase import gobject -class BusAddWatchTest(TestCase): - # FIXME: one last remaining ref - def tearDown(self): - pass - +class BusSignalTest(TestCase): def testGoodConstructor(self): loop = gobject.MainLoop() - + gst.info ("creating pipeline") pipeline = gst.parse_launch("fakesrc ! fakesink") + gst.info ("getting bus") bus = pipeline.get_bus() + gst.info ("got bus") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) self.assertEquals(bus.__gstrefcount__, 2) self.assertEquals(pipeline.__gstrefcount__, 1) - watch_id = bus.add_watch(self._message_received, pipeline, loop, "one") + gst.info ("about to add a watch on the bus") + watch_id = bus.connect("message", self._message_received, pipeline, loop, "one") + bus.add_signal_watch() + gst.info ("added a watch on the bus") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) self.assertEquals(bus.__gstrefcount__, 3) self.assertEquals(pipeline.__gstrefcount__, 1) - pipeline.set_state(gst.STATE_PLAYING) - + gst.info("setting to playing") + ret = pipeline.set_state(gst.STATE_PLAYING) + gst.info("set to playing %s, loop.run" % ret) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) loop.run() - pipeline.set_state(gst.STATE_PAUSED) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("setting to paused") + ret = pipeline.set_state(gst.STATE_PAUSED) + gst.info("set to paused %s, loop.run" % ret) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + loop.run() + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + + gst.info("setting to ready") + ret = pipeline.set_state(gst.STATE_READY) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("set to READY %s, loop.run" % ret) loop.run() - pipeline.set_state(gst.STATE_READY) - loop.run() - - pipeline.set_state(gst.STATE_NULL) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("setting to NULL") + ret = pipeline.set_state(gst.STATE_NULL) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("set to NULL %s" % ret) self.gccollect() self.assertEquals(bus.__gstrefcount__, 3) self.assertEquals(pipeline.__gstrefcount__, 1) - self.failUnless(gobject.source_remove(watch_id)) + gst.info("about to remove the watch id") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + bus.remove_signal_watch() + gst.info("bus watch id removed") + bus.disconnect(watch_id) + gst.info("disconnected callback") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) self.gccollect() + gst.info("pipeliner:%d/%d busr:%d" % (pipeline.__gstrefcount__, pipeline.__grefcount__, bus.__gstrefcount__)) + self.assertEquals(bus.__gstrefcount__, 2) - self.assertEquals(pipeline.__gstrefcount__, 1) + + gst.info("removing pipeline") del pipeline + gst.info("pipeline removed") + gst.info("busr:%d" % bus.__gstrefcount__) + self.gccollect() # flush the bus @@ -66,7 +95,7 @@ class BusAddWatchTest(TestCase): bus.set_flushing(False) self.gccollect() # FIXME: refcount is still 2 - # self.assertEquals(bus.__gstrefcount__, 1) + self.assertEquals(bus.__gstrefcount__, 1) def _message_received(self, bus, message, pipeline, loop, id): self.failUnless(isinstance(bus, gst.Bus)) @@ -74,6 +103,105 @@ class BusAddWatchTest(TestCase): self.assertEquals(id, "one") loop.quit() return True + + + +class BusAddWatchTest(TestCase): + + def testADumbExample(self): + gst.info("creating pipeline") + pipeline = gst.parse_launch("fakesrc ! fakesink") + gst.info("pipeliner:%s" % pipeline.__gstrefcount__) + bus = pipeline.get_bus() + gst.info("got bus, pipeliner:%d, busr:%d" % (pipeline.__gstrefcount__, + bus.__gstrefcount__)) +## watch_id = bus.add_watch(self._message_received, pipeline) +## gst.info("added watch, pipeliner:%d, busr:%d" % (pipeline.__gstrefcount__, +## bus.__gstrefcount__)) +## gobject.source_remove(watch_id) +## gst.info("removed watch, pipeliner:%d, busr:%d" % (pipeline.__gstrefcount__, +## bus.__gstrefcount__)) + + + def testGoodConstructor(self): + loop = gobject.MainLoop() + gst.info ("creating pipeline") + pipeline = gst.parse_launch("fakesrc ! fakesink") + gst.info ("getting bus") + bus = pipeline.get_bus() + gst.info ("got bus") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + self.assertEquals(bus.__gstrefcount__, 2) + self.assertEquals(pipeline.__gstrefcount__, 1) + gst.info ("about to add a watch on the bus") + watch_id = bus.add_watch(self._message_received, pipeline, loop, "one") + gst.info ("added a watch on the bus") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + self.assertEquals(bus.__gstrefcount__, 3) + self.assertEquals(pipeline.__gstrefcount__, 1) + + gst.info("setting to playing") + ret = pipeline.set_state(gst.STATE_PLAYING) + gst.info("set to playing %s, loop.run" % ret) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + loop.run() + + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("setting to paused") + ret = pipeline.set_state(gst.STATE_PAUSED) + gst.info("set to paused %s, loop.run" % ret) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + loop.run() + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + + gst.info("setting to ready") + ret = pipeline.set_state(gst.STATE_READY) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("set to READY %s, loop.run" % ret) + loop.run() + + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("setting to NULL") + ret = pipeline.set_state(gst.STATE_NULL) + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + gst.info("set to NULL %s" % ret) + self.gccollect() + self.assertEquals(bus.__gstrefcount__, 3) + self.assertEquals(pipeline.__gstrefcount__, 1) + + gst.info("about to remove the watch id") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + self.failUnless(gobject.source_remove(watch_id)) + gst.info("bus watch id removed") + gst.info("pipeliner:%d busr:%d" % (pipeline.__gstrefcount__, bus.__gstrefcount__)) + self.gccollect() + gst.info("pipeliner:%d/%d busr:%d" % (pipeline.__gstrefcount__, pipeline.__grefcount__, bus.__gstrefcount__)) + + self.assertEquals(bus.__gstrefcount__, 2) + self.assertEquals(pipeline.__gstrefcount__, 1) + + gst.info("removing pipeline") + del pipeline + gst.info("pipeline removed") + gst.info("busr:%d" % bus.__gstrefcount__) + + self.gccollect() + + # flush the bus + bus.set_flushing(True) + bus.set_flushing(False) + self.gccollect() + # FIXME: refcount is still 2 + self.assertEquals(bus.__gstrefcount__, 1) + + def _message_received(self, bus, message, pipeline, loop, id): + self.failUnless(isinstance(bus, gst.Bus)) + self.failUnless(isinstance(message, gst.Message)) + self.assertEquals(id, "one") + # doesn't the following line stop the mainloop before the end of the state change ? + loop.quit() + return True + if __name__ == "__main__": unittest.main()