From d6df98461273fa2fa8e97ce3f70c6cc5ae9f84d8 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 19 Dec 2006 11:38:01 +0000 Subject: [PATCH] gst/gst.defs: Update API definitions. Original commit message from CVS: * gst/gst.defs: Update API definitions. * gst/common.h: * gst/gstpad.override: Add wrapper functions for settings activate, activatepull and activatepush functions on pads. * gst/gst.override: Wrapper for gst_segment_set_seek() and gst_segment_clip() Remove global ignore for *_init(), allows gst_segment_init() to be properly code-generated. * testsuite/Makefile.am: * testsuite/test_segment.py: Add unit test for gst.Segment object. --- ChangeLog | 16 +++++ gst/common.h | 3 + gst/gst.defs | 8 +++ gst/gst.override | 92 ++++++++++++++++++++++++- gst/gstpad.override | 140 ++++++++++++++++++++++++++++++++++++++ testsuite/Makefile.am | 1 + testsuite/test_segment.py | 61 +++++++++++++++++ 7 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 testsuite/test_segment.py diff --git a/ChangeLog b/ChangeLog index d0e966dbaa..b201882549 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-12-19 Edward Hervey + + * gst/gst.defs: + Update API definitions. + * gst/common.h: + * gst/gstpad.override: + Add wrapper functions for settings activate, activatepull and + activatepush functions on pads. + * gst/gst.override: + Wrapper for gst_segment_set_seek() and gst_segment_clip() + Remove global ignore for *_init(), allows gst_segment_init() to be + properly code-generated. + * testsuite/Makefile.am: + * testsuite/test_segment.py: + Add unit test for gst.Segment object. + 2006-12-16 Edward Hervey * testsuite/test_pad.py: diff --git a/gst/common.h b/gst/common.h index e3957ee247..1da5b124b2 100644 --- a/gst/common.h +++ b/gst/common.h @@ -43,6 +43,9 @@ typedef struct { GClosure *get_function; GClosure *getcaps_function; GClosure *setcaps_function; + GClosure *activate_function; + GClosure *activatepull_function; + GClosure *activatepush_function; } PyGstPadPrivate; typedef struct { diff --git a/gst/gst.defs b/gst/gst.defs index 4248e56c4f..63e55c77ff 100644 --- a/gst/gst.defs +++ b/gst/gst.defs @@ -6512,6 +6512,14 @@ (return-type "const-gchar*") ) +(define-function state_change_return_get_name + (c-name "gst_element_state_change_return_get_name") + (return-type "const-gchar*") + (parameters + '("GstStateChangeReturn" "state_ret") + ) +) + (define-method link (of-object "GstElement") (c-name "gst_element_link") diff --git a/gst/gst.override b/gst/gst.override index a668fe063f..caeb1cf0e7 100644 --- a/gst/gst.override +++ b/gst/gst.override @@ -272,7 +272,6 @@ ignore-glob *_valist *_ref *_unref - *_init *_deinit *_full gst_class_* @@ -926,6 +925,30 @@ _wrap_gst_clock_get_calibration (PyGObject * self) return ret; } +%% +override gst_clock_add_observation kwargs +static PyObject * +_wrap_gst_clock_add_observation (PyGObject *self, PyObject * args, PyObject * kwargs) +{ + static char *kwlist[] = { "slave", "master", NULL}; + GstClockTime master, slave; + gdouble squared = 1.0; + PyObject *py_ret; + gboolean ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "KK:GstClock.add_observation", + kwlist, &master, &slave)) + return NULL; + + ret = gst_clock_add_observation (GST_CLOCK (self->obj), master, slave, + &squared); + + py_ret = PyList_New(2); + PyList_SetItem(py_ret, 0, PyBool_FromLong(ret)); + PyList_SetItem(py_ret, 1, PyFloat_FromDouble(squared)); + return py_ret; +} + %% override gst_type_find_helper_for_buffer kwargs static PyObject * @@ -1128,3 +1151,70 @@ _wrap_gst_type_find_new (PyObject *self, PyObject *args, PyObject *kwargs) return pytypefind; } +%% +override gst_segment_set_seek kwargs +static PyObject * +_wrap_gst_segment_set_seek (PyObject * self, PyObject * args, PyObject * kwargs) +{ + static char *kwlist[] = { "rate", "format", "flags", "start_type", "start", + "stop_type", "stop", NULL }; + GstSeekType start_type, stop_type; + PyObject *py_format = NULL, *py_flags = NULL, *py_start_type = NULL; + PyObject *py_stop_type = NULL, *py_ret; + double rate; + GstFormat format; + gint64 start, stop; + GstSeekFlags flags; + gboolean update = FALSE; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dOOOLOL:GstSegment.set_seek", + kwlist, &rate, &py_format, &py_flags, + &py_start_type, &start, &py_stop_type, + &stop)) + return NULL; + if (pyg_enum_get_value(GST_TYPE_FORMAT, py_format, (gint *)&format)) + return NULL; + if (pyg_flags_get_value(GST_TYPE_SEEK_FLAGS, py_flags, (gint *)&flags)) + return NULL; + if (pyg_enum_get_value(GST_TYPE_SEEK_TYPE, py_start_type, (gint *)&start_type)) + return NULL; + if (pyg_enum_get_value(GST_TYPE_SEEK_TYPE, py_stop_type, (gint *)&stop_type)) + return NULL; + pyg_begin_allow_threads; + gst_segment_set_seek(pyg_boxed_get(self, GstSegment), rate, format, flags, + start_type, start, stop_type, stop, &update); + pyg_end_allow_threads; + py_ret = PyBool_FromLong(update); + return py_ret; +} +%% +override gst_segment_clip kwargs +static PyObject * +_wrap_gst_segment_clip (PyObject * self, PyObject * args, PyObject * kwargs) +{ + static char *kwlist[] = { "format", "start", "stop", NULL}; + GstFormat format; + gint64 start, stop; + gint64 cstart = -1; + gint64 cstop = -1; + gboolean ret; + PyObject *py_ret, *py_format; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OLL:GstSegment.clip", + kwlist, &py_format, &start, &stop)) + return NULL; + if (pyg_enum_get_value(GST_TYPE_FORMAT, py_format, (gint *)&format)) + return NULL; + pyg_begin_allow_threads; + ret = gst_segment_clip (pyg_boxed_get(self, GstSegment), format, start, stop, + &cstart, &cstop); + pyg_end_allow_threads; + + /* Returns gboolean ret, gint64 clip_start, gint64 clip_stop */ + py_ret = PyList_New(3); + PyList_SetItem(py_ret, 0, PyBool_FromLong(ret)); + PyList_SetItem(py_ret, 1, PyLong_FromLongLong(cstart)); + PyList_SetItem(py_ret, 2, PyLong_FromLongLong(cstop)); + + return py_ret; +} diff --git a/gst/gstpad.override b/gst/gstpad.override index 39335b74d7..608b4d63e3 100644 --- a/gst/gstpad.override +++ b/gst/gstpad.override @@ -81,6 +81,9 @@ free_pad_private (gpointer data) INVALIDATE_CLOSURE (private->get_function) INVALIDATE_CLOSURE (private->getcaps_function) INVALIDATE_CLOSURE (private->setcaps_function) + INVALIDATE_CLOSURE (private->activate_function) + INVALIDATE_CLOSURE (private->activatepull_function) + INVALIDATE_CLOSURE (private->activatepush_function) #undef INVALIDATE_CLOSURE } @@ -395,7 +398,144 @@ _wrap_gst_pad_set_setcaps_function (PyGObject *self, SET_PAD_CLOSURE (self, args, kwargs, setcaps_function) } +%% +override gst_pad_set_activate_function kwargs +static void EXCEPTION_HANDLER +handle_activate_function_exception (GValue * ret, guint n, const GValue * params) +{ + GstElement *element = GST_ELEMENT (gst_pad_get_parent (g_value_get_object (¶ms[0]))); + + if (!_pygst_element_check_error (element)) { + g_assert_not_reached (); /* only returns FALSE when there's no error */ + } +} + +static gboolean +call_activate_function (GstPad * pad) +{ + GClosure * closure; + GValue ret = { 0, }; + GValue args[1] = { {0, }}; + gboolean bool; + + g_value_init (&ret, G_TYPE_BOOLEAN); + g_value_set_boolean (&ret, FALSE); + g_value_init(&args[0], GST_TYPE_PAD); + g_value_set_object (&args[0], pad); + closure = pad_private(pad)->activate_function; + + g_closure_invoke (closure, &ret, 1, args, NULL); + + bool = g_value_get_boolean (&ret); + + g_value_unset (&ret); + g_value_unset (&args[0]); + + return bool; +} + +static PyObject * +_wrap_gst_pad_set_activate_function (PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + SET_PAD_CLOSURE (self, args, kwargs, activate_function) +} +%% +override gst_pad_set_activatepull_function kwargs + +static void EXCEPTION_HANDLER +handle_activatepull_function_exception (GValue * ret, guint n, const GValue * params) +{ + GstElement *element = GST_ELEMENT (gst_pad_get_parent (g_value_get_object (¶ms[0]))); + + if (!_pygst_element_check_error (element)) { + g_assert_not_reached (); /* only returns FALSE when there's no error */ + } +} + +static gboolean +call_activatepull_function (GstPad * pad, gboolean active) +{ + GClosure * closure; + GValue ret = { 0, }; + GValue args[2] = { {0, }, {0, } }; + gboolean bool; + + g_value_init (&ret, G_TYPE_BOOLEAN); + g_value_set_boolean (&ret, FALSE); + g_value_init (&args[0], GST_TYPE_PAD); + g_value_set_object (&args[0], pad); + g_value_init (&args[1], G_TYPE_BOOLEAN); + g_value_set_boolean (&args[1], active); + closure = pad_private(pad)->activatepull_function; + + g_closure_invoke (closure, &ret, 2, args, NULL); + + bool = g_value_get_boolean (&ret); + + g_value_unset (&ret); + g_value_unset (&args[0]); + g_value_unset (&args[1]); + + return bool; +} + +static PyObject * +_wrap_gst_pad_set_activatepull_function (PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + SET_PAD_CLOSURE (self, args, kwargs, activatepull_function); +} +%% +override gst_pad_set_activatepush_function kwargs + +static void EXCEPTION_HANDLER +handle_activatepush_function_exception (GValue * ret, guint n, const GValue * params) +{ + GstElement *element = GST_ELEMENT (gst_pad_get_parent (g_value_get_object (¶ms[0]))); + + if (!_pygst_element_check_error (element)) { + g_assert_not_reached (); /* only returns FALSE when there's no error */ + } +} + +static gboolean +call_activatepush_function (GstPad * pad, gboolean active) +{ + GClosure * closure; + GValue ret = { 0, }; + GValue args[2] = { {0, }, {0, }}; + gboolean bool; + + g_value_init (&ret, G_TYPE_BOOLEAN); + g_value_set_boolean (&ret, FALSE); + g_value_init (&args[0], GST_TYPE_PAD); + g_value_set_object (&args[0], pad); + g_value_init (&args[1], G_TYPE_BOOLEAN); + g_value_set_boolean (&args[1], active); + closure = pad_private(pad)->activatepush_function; + + g_closure_invoke (closure, &ret, 2, args, NULL); + + bool = g_value_get_boolean (&ret); + + g_value_unset (&ret); + g_value_unset (&args[0]); + g_value_unset (&args[1]); + + return bool; +} + +static PyObject * +_wrap_gst_pad_set_activatepush_function (PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + SET_PAD_CLOSURE (self, args, kwargs, activatepush_function); +} %% override-slot GstPad.tp_repr static PyObject * diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 6020383c30..d8fd3f61b3 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -31,6 +31,7 @@ tests = \ test_pipeline.py \ test_registry.py \ test_struct.py \ + test_segment.py \ test_xml.py check-local: testhelper.la diff --git a/testsuite/test_segment.py b/testsuite/test_segment.py new file mode 100644 index 0000000000..96417cf090 --- /dev/null +++ b/testsuite/test_segment.py @@ -0,0 +1,61 @@ +# -*- Mode: Python -*- +# vi:si:et:sw=4:sts=4:ts=4 +# +# gst-python - Python bindings for GStreamer +# Copyright (C) 2006 Edward Hervey +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from common import gst, unittest, TestCase + +class SegmentTest(TestCase): + def testSeekNoSize(self): + segment = gst.Segment() + segment.init(gst.FORMAT_BYTES) + + # configure segment to start at 100 with no defined stop position + update = segment.set_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_NONE, + gst.SEEK_TYPE_SET, 100, + gst.SEEK_TYPE_NONE, -1) + self.assertEquals(update, True) + self.assertEquals(segment.start, 100) + self.assertEquals(segment.stop, -1) + + # configure segment to stop relative, should not do anything since + # size is unknown + update = segment.set_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_NONE, + gst.SEEK_TYPE_NONE, 200, + gst.SEEK_TYPE_CUR, -100) + + self.assertEquals(update, False) + self.assertEquals(segment.start, 100) + self.assertEquals(segment.stop, -1) + + # clipping on outside range, always returns False + res, cstart, cstop = segment.clip(gst.FORMAT_BYTES, 0, 50) + self.assertEquals(res, False) + + # touching lower bound but outside + res, cstart, cstop = segment.clip(gst.FORMAT_BYTES, 50, 100) + self.assertEquals(res, False) + + # partially inside + res, cstart, cstop = segment.clip(gst.FORMAT_BYTES, 50, 150) + self.assertEquals(res, True) + self.assertEquals(cstart, 100) + self.assertEquals(cstop, 150) + +if __name__ == "__main__": + unittest.main()