From 26fa6dd184a8d6d103eaddf5f12bd7e5144413fb Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Mon, 1 Jun 2009 22:02:47 +0200 Subject: [PATCH] wrap gst_tag_to_vorbis_comment; fix uint tag setting Setting gst.TAG_TRACK_NUMBER was failing because GStreamer expects a uint while Python object -> GValue conversion was giving an int. gst_tag_to_vorbis_comment was wrapped so this conversion could be tested and failed on properly. --- gst/gsttaglist.override | 18 +++++++++++++++++ gst/tag.override | 40 ++++++++++++++++++++++++++++++++++++++ testsuite/common.py | 11 +++++++++++ testsuite/test_pipeline.py | 32 ++++++++++++++++++++++++++++++ testsuite/test_taglist.py | 6 +++++- 5 files changed, 106 insertions(+), 1 deletion(-) diff --git a/gst/gsttaglist.override b/gst/gsttaglist.override index 93c902f9fe..37752323da 100644 --- a/gst/gsttaglist.override +++ b/gst/gsttaglist.override @@ -95,15 +95,33 @@ _wrap_gst_tag_list_ass_subscript(PyGObject *self, { const char *key; GstStructure* structure; + GType tagtype; structure = (GstStructure*)self->obj; key = PyString_AsString(py_key); if (py_value != NULL) { GValue v = { 0, }; + if (!pygst_value_init_for_pyobject (&v, py_value)) return -1; if (pygst_value_from_pyobject(&v, py_value)) return -1; + + /* some tags are supposed to be uint, but there is no unsigned + * int python type, so convert here if needed */ + if (gst_tag_exists (key)) { + tagtype = gst_tag_get_type (key); + + if (tagtype && tagtype != G_VALUE_TYPE (&v)) { + GValue w = { 0, }; + + g_value_init (&w, tagtype); + g_value_transform (&v, &w); + g_value_unset (&v); + g_value_init (&v, tagtype); + g_value_copy (&w, &v); + } + } gst_structure_set_value(structure, key, &v); g_value_unset(&v); } else { diff --git a/gst/tag.override b/gst/tag.override index 52ef76b552..b908d5b5af 100644 --- a/gst/tag.override +++ b/gst/tag.override @@ -62,3 +62,43 @@ ignore-glob *init *_free *_get_type + +%% +override gst_tag_to_vorbis_comments +static PyObject * +_wrap_gst_tag_to_vorbis_comments(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_taglist; + const GstTagList *taglist; + const gchar *tag; + + const GList *list; + const GList *l; + PyObject *py_list; + + if (!PyArg_ParseTuple(args, "Os", &py_taglist, &tag)) + return NULL; + + if (pyg_boxed_check(py_taglist, GST_TYPE_TAG_LIST)) + taglist = pyg_boxed_get(py_taglist, GstTagList); + else { + PyErr_SetString(PyExc_TypeError, "list should be a GstTagList"); + return NULL; + } + + + pyg_begin_allow_threads; + list = gst_tag_to_vorbis_comments (taglist, tag); + pyg_end_allow_threads; + + py_list = PyList_New(0); + + for (l = list; l; l = l->next) { + gchar *pair = (gchar *)l->data; + PyObject *py_pair = PyString_FromString(pair); + PyList_Append(py_list, py_pair); + Py_DECREF(py_pair); + } + return py_list; + +} diff --git a/testsuite/common.py b/testsuite/common.py index 5ec46f4ca6..cc81745ca9 100644 --- a/testsuite/common.py +++ b/testsuite/common.py @@ -78,6 +78,17 @@ except ImportError: file = gst.interfaces.__file__ assert file.startswith(path), 'bad gst.interfaces path: %s' % file +# gst's tags is in topbuilddir/gst +path = os.path.abspath(os.path.join(topbuilddir, 'gst')) +try: + import gst.tag +except ImportError: + # hack: we import it from our builddir/gst/.libs instead; ugly + import tag + gst.tag = tag +file = gst.tag.__file__ +assert file.startswith(path), 'bad gst.tag path: %s' % file + # gst's pbutils is in topbuilddir/gst path = os.path.abspath(os.path.join(topbuilddir, 'gst')) try: diff --git a/testsuite/test_pipeline.py b/testsuite/test_pipeline.py index a84b98843a..a57c7f96ba 100644 --- a/testsuite/test_pipeline.py +++ b/testsuite/test_pipeline.py @@ -73,6 +73,38 @@ class Pipeline(TestCase): self.pipeline.set_state(gst.STATE_NULL) self.assertEqual(self.pipeline.get_state()[1], gst.STATE_NULL) +class PipelineTags(TestCase): + def setUp(self): + self.gctrack() + self.pipeline = gst.parse_launch('audiotestsrc num-buffers=100 ! vorbisenc name=encoder ! oggmux name=muxer ! fakesink') + + def tearDown(self): + del self.pipeline + self.gccollect() + self.gcverify() + + def testRun(self): + # in 0.10.15.1, this triggers + # sys:1: gobject.Warning: g_value_get_uint: assertion `G_VALUE_HOLDS_UINT (value)' failed + # during pipeline playing + + l = gst.TagList() + l[gst.TAG_ARTIST] = 'artist' + l[gst.TAG_TRACK_NUMBER] = 1 + encoder = self.pipeline.get_by_name('encoder') + encoder.merge_tags(l, gst.TAG_MERGE_APPEND) + + self.assertEqual(self.pipeline.get_state()[1], gst.STATE_NULL) + self.pipeline.set_state(gst.STATE_PLAYING) + self.assertEqual(self.pipeline.get_state()[1], gst.STATE_PLAYING) + + time.sleep(1) + + self.assertEqual(self.pipeline.get_state()[1], gst.STATE_PLAYING) + self.pipeline.set_state(gst.STATE_NULL) + self.assertEqual(self.pipeline.get_state()[1], gst.STATE_NULL) + + class Bus(TestCase): def testGet(self): pipeline = gst.Pipeline('test') diff --git a/testsuite/test_taglist.py b/testsuite/test_taglist.py index 227a812864..2b94918725 100644 --- a/testsuite/test_taglist.py +++ b/testsuite/test_taglist.py @@ -64,4 +64,8 @@ class TestTagList(TestCase): self.failUnless(isinstance(taglist[gst.TAG_ARTIST], unicode)) self.assertEquals(taglist[gst.TAG_ARTIST], u'S\xc3\xadgur R\xc3\xb3s') - + def testUnsignedInt(self): + taglist = gst.TagList() + taglist[gst.TAG_TRACK_NUMBER] = 1 + vorbis = gst.tag.to_vorbis_comments(taglist, gst.TAG_TRACK_NUMBER) + self.assertEquals(vorbis, ['TRACKNUMBER=1'])