This commit is contained in:
Akkariin Meiko
2022-03-12 03:16:09 +08:00
Unverified
parent 12b76e0c7a
commit 27c4ec74a1
10075 changed files with 5122287 additions and 1 deletions
+138
View File
@@ -0,0 +1,138 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2015 Thibault Saunier <thibault.saunier@collabora.com>
#
# This program 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 program 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 program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# SPDX-License-Identifier: LGPL-2.0-or-later
"""
A collection of objects to use for testing
Copyied from pitivi
"""
import os
import gc
import unittest
import gi.overrides
import gi
gi.require_version("Gst", "1.0")
from gi.repository import Gst
detect_leaks = os.environ.get("TEST_DETECT_LEAKS", "1") not in ("0", "")
class TestCase(unittest.TestCase):
_tracked_types = (Gst.MiniObject, Gst.Element, Gst.Pad, Gst.Caps)
def gctrack(self):
self.gccollect()
self._tracked = []
for obj in gc.get_objects():
if not isinstance(obj, self._tracked_types):
continue
self._tracked.append(obj)
def gccollect(self):
ret = 0
while True:
c = gc.collect()
ret += c
if c == 0:
break
return ret
def gcverify(self):
leaked = []
for obj in gc.get_objects():
if not isinstance(obj, self._tracked_types) or \
obj in self._tracked:
continue
leaked.append(obj)
# we collect again here to get rid of temporary objects created in the
# above loop
self.gccollect()
for elt in leaked:
print(elt)
for i in gc.get_referrers(elt):
print(" ", i)
self.assertFalse(leaked, leaked)
del self._tracked
def setUp(self):
self._num_failures = len(getattr(self._result, 'failures', []))
self._num_errors = len(getattr(self._result, 'errors', []))
if detect_leaks:
self.gctrack()
def tearDown(self):
# don't barf gc info all over the console if we have already failed a
# test case
if (self._num_failures < len(getattr(self._result, 'failures', []))
or self._num_errors < len(getattr(self._result, 'failures', []))):
return
if detect_leaks:
self.gccollect()
self.gcverify()
# override run() to save a reference to the test result object
def run(self, result=None):
if not result:
result = self.defaultTestResult()
self._result = result
unittest.TestCase.run(self, result)
class SignalMonitor(object):
def __init__(self, obj, *signals):
self.signals = signals
self.connectToObj(obj)
def connectToObj(self, obj):
self.obj = obj
for signal in self.signals:
obj.connect(signal, self._signalCb, signal)
setattr(self, self._getSignalCounterName(signal), 0)
setattr(self, self._getSignalCollectName(signal), [])
def disconnectFromObj(self, obj):
obj.disconnect_by_func(self._signalCb)
del self.obj
def _getSignalCounterName(self, signal):
field = '%s_count' % signal.replace('-', '_')
return field
def _getSignalCollectName(self, signal):
field = '%s_collect' % signal.replace('-', '_')
return field
def _signalCb(self, obj, *args):
name = args[-1]
field = self._getSignalCounterName(name)
setattr(self, field, getattr(self, field, 0) + 1)
field = self._getSignalCollectName(name)
setattr(self, field, getattr(self, field, []) + [args[:-1]])
@@ -0,0 +1,241 @@
{
pthread leak
Memcheck:Leak
fun:calloc
fun:allocate_dtv
fun:_dl_allocate_tls*
}
{
pthread leak 2
Memcheck:Leak
fun:memalign
fun:_dl_allocate_tls*
}
{
popt leak
Memcheck:Leak
fun:malloc
fun:nss_parse_service_list
fun:__nss_database_lookup
obj:*
obj:*
fun:getpwuid_r@@GLIBC_2.2.5
fun:g_get_any_init_do
fun:g_get_home_dir
fun:init_post
fun:init_popt_callback
}
{
pygobject init leak
Memcheck:Leak
fun:calloc
fun:g_malloc0
fun:type_node_*
fun:type_node_*
fun:*
fun:*
fun:g_type_init*
fun:initgobject
}
{
borked pthread creation
Memcheck:Param
write(buf)
fun:__pthread_initialize_manager
fun:pthread_create@@GLIBC_2.2.5
fun:g_thread_create*
fun:g_thread_create*
}
{
borked pthread creation 2
Memcheck:Param
write(buf)
fun:pthread_create@@GLIBC_2.2.5
fun:*
fun:*
fun:*
fun:*
fun:gst_task_start
}
{
Syscall param clone(child_tidptr) contains uninitialised byte(s)
Memcheck:Param
clone(child_tidptr)
fun:clone
}
{
memory loss when creating thread
Memcheck:Leak
fun:malloc
fun:__pthread_initialize_manager
fun:pthread_create*
}
# pyg_enable_threads memleak
{
memleak in pyg_enable_threads
Memcheck:Leak
fun:malloc
fun:*
fun:*
fun:*
fun:*
fun:*
fun:pyg_enable_threads
}
{
memleak in pyg_enable_threads 2
Memcheck:Leak
fun:malloc
fun:*
fun:*
fun:*
fun:*
fun:pyg_enable_threads
}
{
memleak in pyg_enable_threads 3
Memcheck:Leak
fun:malloc
fun:*
fun:*
fun:*
fun:pyg_enable_threads
}
#pygobject leaks
{
PyType_Ready leak
Memcheck:Leak
fun:malloc
fun:PyObject_Malloc
fun:_PyObject_GC_Malloc
fun:PyType_GenericAlloc
fun:*
fun:*
fun:PyType_Ready
}
#gst debug category new leak
{
gst debug category new leak
Memcheck:Leak
fun:malloc
fun:g_malloc
fun:g_strdup
fun:_gst_debug_category_new
}
# memleak in gst_element_state_get_name that we can't get rid of
{
gst_element_state_get_name
Memcheck:Leak
fun:malloc
fun:*
fun:g_vasprintf
fun:g_strdup*
fun:g_strdup*
fun:_wrap_gst_element_state_get_name
}
#memleak in pygobject_new_with_interfaces
# weird, cos it seems to free the return value of g_type_interfaces
{
_gst_element_factory_make
Memcheck:Leak
fun:malloc
fun:g_malloc
fun:g_type_interfaces
}
#memleak in static_pad_template
{
gst_static_pad_template_get
Memcheck:Leak
fun:calloc
fun:g_malloc0
fun:g_type_create_instance
fun:g_object_constructor
fun:gst_object_constructor
fun:*
fun:*
fun:*
fun:gst_static_pad_template_get
}
#leak in libxml
{
xml_parse_memory leak
Memcheck:Leak
fun:malloc
fun:*
fun:xml*
}
# FIXME : This is an awful leak that has do to with the gst_pad_set_*_function wrappers
{
leak in gst_pad_set_*_function wrappers
Memcheck:Leak
fun:calloc
fun:g_malloc0
fun:pad_private
}
# python leak in runtime compiler
{
python leak in runtime compiler
Memcheck:Leak
fun:malloc
fun:_PyObject_GC_Malloc
fun:_PyObject_GC_New*
fun:PyDict_New
fun:PySymtableEntry_New
fun:symtable_*
fun:symtable_*
fun:jcompile
}
#FIXME : These leaks are in core. See bug #344761
{
leak in init_gst, when creating the argv to give to gst_init_check()
Memcheck:Leak
fun:*
fun:g_malloc
fun:init_gst
}
{
The GOption context is leaking in gst_init_check
Memcheck:Leak
fun:*
fun:g_malloc0
fun:g_option_context_new
fun:gst_init_check
fun:init_gst
}
{
The GDir is leaked.
Memcheck:Leak
fun:*
fun:g_malloc
fun:g_dir_open
fun:gst_registry_scan_path_level
fun:gst_registry_scan_path
fun:init_post
fun:g_option_context_parse
fun:gst_init_check
fun:init_gst
}
@@ -0,0 +1,41 @@
runtests = files('runtests.py')
tests = [
['Test gst', 'test_gst.py'],
['Test fundamentals', 'test_types.py'],
['Test plugins', 'test_plugin.py'],
]
pluginsdirs = []
if not meson.is_subproject()
pkgconfig = find_program('pkg-config')
runcmd = run_command(pkgconfig, '--variable=pluginsdir',
'gstreamer-' + api_version, check: true)
pluginsdirs = runcmd.stdout().split()
endif
runcmd = run_command(python, '-c', '''with open("@0@/mesonconfig.py", "w") as f:
f.write("path='@1@'")'''.format(
join_paths(meson.current_build_dir()), join_paths(meson.current_build_dir(), '..')),
check: true)
pluginsdirs = []
if gst_dep.type_name() == 'pkgconfig'
pbase = dependency('gstreamer-plugins-base-' + api_version, required : false)
pluginsdirs = [gst_dep.get_variable('pluginsdir'),
pbase.get_variable('pluginsdir')]
endif
pypluginsdir = [join_paths (meson.project_build_root(), 'plugin'), meson.current_source_dir()]
foreach i: tests
test_name = i.get(0)
env = environment()
env.set('GST_OVERRIDE_SRC_PATH', join_paths (meson.current_source_dir(), '..', 'gi', 'overrides'))
env.set('GST_OVERRIDE_BUILD_PATH', join_paths (meson.current_build_dir(), '..', 'gi', 'overrides'))
env.set('GST_PLUGIN_LOADING_WHITELIST', 'gstreamer', 'gst-plugins-base',
'gst-python@' + meson.project_build_root())
env.set('GST_PLUGIN_PATH_1_0', meson.global_build_root(), pluginsdirs + pypluginsdir)
env.set('GST_REGISTRY', join_paths(meson.current_build_dir(), '@0@.registry'.format(test_name)))
test(test_name, python, args: [runtests, i.get(1)], env: env)
endforeach
@@ -0,0 +1,28 @@
#include "test-object.h"
enum
{
/* FILL ME */
SIGNAL_EVENT,
LAST_SIGNAL
};
static guint test_object_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
static void
test_object_init (TestObject * self)
{
}
static void
test_object_class_init (TestObjectClass * klass)
{
test_object_signals[SIGNAL_EVENT] =
g_signal_new ("event", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (TestObjectClass, event), NULL, NULL,
g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_EVENT);
}
@@ -0,0 +1,23 @@
#include <glib-object.h>
#include <gst/gstevent.h>
/* TestObject */
typedef struct {
GObject parent;
} TestObject;
typedef struct {
GObjectClass parent_class;
/* signals */
void (*event) (TestObject *object, GstEvent *event);
} TestObjectClass;
#define TEST_TYPE_OBJECT (test_object_get_type())
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_OBJECT, TestObjectClass))
GType test_object_get_type (void);
@@ -0,0 +1,83 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gobject, gst, unittest, TestCase
class AdapterTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.adapter = gst.Adapter()
def tearDown(self):
self.adapter = None
TestCase.tearDown(self)
def testAvailable(self):
# starts empty
self.assertEquals(self.adapter.available(), 0)
self.assertEquals(self.adapter.available_fast(), 0)
# let's give it 4 bytes
self.adapter.push(gst.Buffer("1234"))
self.assertEquals(self.adapter.available_fast(), 4)
# let's give it another 5 bytes
self.adapter.push(gst.Buffer("56789"))
# we now have 9 bytes
self.assertEquals(self.adapter.available(), 9)
# but can only do a fast take of 4 bytes (the first buffer)
self.assertEquals(self.adapter.available_fast(), 4)
def testPeek(self):
self.adapter.push(gst.Buffer("0123456789"))
# let's peek at 5 bytes
b = self.adapter.peek(5)
# it can return more than 5 bytes
self.assert_(len(b) >= 5)
self.assertEquals(b, "01234")
# it's still 10 bytes big
self.assertEquals(self.adapter.available(), 10)
# if we try to peek more than what's available, we'll have None
self.assertEquals(self.adapter.peek(11), None)
def testFlush(self):
self.adapter.push(gst.Buffer("0123456789"))
self.assertEquals(self.adapter.available(), 10)
self.adapter.flush(5)
self.assertEquals(self.adapter.available(), 5)
# it flushed the first 5 bytes
self.assertEquals(self.adapter.peek(5), "56789")
self.adapter.flush(5)
self.assertEquals(self.adapter.available(), 0)
def testTake(self):
self.adapter.push(gst.Buffer("0123456789"))
self.assertEquals(self.adapter.available(), 10)
s = self.adapter.take(5)
self.assertEquals(s, "01234")
self.assertEquals(self.adapter.available(), 5)
@@ -0,0 +1,38 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gobject, gst, unittest, TestCase
class Audio(TestCase):
def testBufferclip(self):
assert hasattr(gst.audio, "buffer_clip")
# create a segment
segment = gst.Segment()
gst.debug("Created the new segment")
# we'll put a new segment of 500ms to 1000ms
segment.set_newsegment(False, 1.0, gst.FORMAT_TIME, 0, -1, 0)
gst.debug("Initialized the new segment")
# create a new dummy buffer
b = gst.Buffer("this is a really useless line")
gst.debug("Created the buffer")
# clip... which shouldn't do anything
b2 = gst.audio.buffer_clip(b, segment, 44100, 8)
gst.debug("DONE !")
@@ -0,0 +1,196 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 Edward Hervey
# Copyright (C) 2005 Thomas Vander Stichele
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gobject, gst, unittest, TestCase, pygobject_2_13
import sys
import time
# see
# http://www.sicem.biz/personal/lgs/docs/gobject-python/gobject-tutorial.html
class MyBin(gst.Bin):
_state_changed = False
def __init__(self, name):
# we need to call GObject's init to be able to do self.do_*
gobject.GObject.__init__(self)
# since we can't chain up to our parent's __init__, we set the
# name manually
self.set_property('name', name)
def do_change_state(self, state_change):
if state_change == gst.STATE_CHANGE_PAUSED_TO_PLAYING:
self._state_changed = True
# FIXME: it seems a vmethod increases the refcount without unreffing
# print self.__gstrefcount__
# print self.__grefcount__
# chain up to parent
return gst.Bin.do_change_state(self, state_change)
# we need to register the type for PyGTK < 2.8
gobject.type_register(MyBin)
# FIXME: fix leak in vmethods before removing overriding fixture
class BinSubclassTest(TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def testStateChange(self):
bin = MyBin("mybin")
self.assertEquals(bin.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(bin), pygobject_2_13 and 2 or 3)
self.assertEquals(bin.get_name(), "mybin")
self.assertEquals(bin.__gstrefcount__, 1)
# test get_state with no timeout
(ret, state, pending) = bin.get_state()
self.failIfEqual(ret, gst.STATE_CHANGE_FAILURE)
self.assertEquals(bin.__gstrefcount__, 1)
# set to playing
bin.set_state(gst.STATE_PLAYING)
self.failUnless(bin._state_changed)
# test get_state with no timeout
(ret, state, pending) = bin.get_state()
self.failIfEqual(ret, gst.STATE_CHANGE_FAILURE)
if ret == gst.STATE_CHANGE_SUCCESS:
self.assertEquals(state, gst.STATE_PLAYING)
self.assertEquals(pending, gst.STATE_VOID_PENDING)
# test get_state with a timeout
(ret, state, pending) = bin.get_state(1)
self.failIfEqual(ret, gst.STATE_CHANGE_FAILURE)
if ret == gst.STATE_CHANGE_SUCCESS:
self.assertEquals(state, gst.STATE_PLAYING)
self.assertEquals(pending, gst.STATE_VOID_PENDING)
(ret, state, pending) = bin.get_state(timeout=gst.SECOND)
# back to NULL
bin.set_state(gst.STATE_NULL)
class BinAddRemove(TestCase):
def setUp(self):
TestCase.setUp(self)
self.bin = gst.Bin('bin')
def tearDown(self):
del self.bin
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):
src = gst.element_factory_make('fakesrc')
sink = gst.element_factory_make('fakesink')
self.bin.add(src, sink)
self.assertRaises(gst.AddError, self.bin.add, src, sink)
self.bin.remove(src, sink)
self.assertRaises(gst.RemoveError, self.bin.remove, src, sink)
class Preroll(TestCase):
def setUp(self):
TestCase.setUp(self)
self.bin = gst.Bin('bin')
def tearDown(self):
# FIXME: wait for state change thread to settle down
while self.bin.__gstrefcount__ > 1:
time.sleep(0.1)
self.assertEquals(self.bin.__gstrefcount__, 1)
del self.bin
TestCase.tearDown(self)
def testFake(self):
src = gst.element_factory_make('fakesrc')
sink = gst.element_factory_make('fakesink')
self.bin.add(src)
# bin will go to paused, src pad task will start and error out
self.bin.set_state(gst.STATE_PAUSED)
ret = self.bin.get_state()
self.assertEquals(ret[0], gst.STATE_CHANGE_SUCCESS)
self.assertEquals(ret[1], gst.STATE_PAUSED)
self.assertEquals(ret[2], gst.STATE_VOID_PENDING)
# adding the sink will cause the bin to go in preroll mode
gst.debug('adding sink and setting to PAUSED, should cause preroll')
self.bin.add(sink)
sink.set_state(gst.STATE_PAUSED)
ret = self.bin.get_state(timeout=0)
self.assertEquals(ret[0], gst.STATE_CHANGE_ASYNC)
self.assertEquals(ret[1], gst.STATE_PAUSED)
self.assertEquals(ret[2], gst.STATE_PAUSED)
# to actually complete preroll, we need to link and re-enable fakesrc
src.set_state(gst.STATE_READY)
src.link(sink)
src.set_state(gst.STATE_PAUSED)
ret = self.bin.get_state()
self.assertEquals(ret[0], gst.STATE_CHANGE_SUCCESS)
self.assertEquals(ret[1], gst.STATE_PAUSED)
self.assertEquals(ret[2], gst.STATE_VOID_PENDING)
self.bin.set_state(gst.STATE_NULL)
self.bin.get_state()
class ConstructorTest(TestCase):
def testGood(self):
bin = gst.Bin()
bin = gst.Bin(None)
bin = gst.Bin('')
bin = gst.Bin('myname')
def testBad(self):
# these are now valid. pygobject will take care of converting
# the arguments to a string.
#self.assertRaises(TypeError, gst.Bin, 0)
#self.assertRaises(TypeError, gst.Bin, gst.Bin())
pass
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,178 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import sys
import gc
from common import gobject, gst, unittest, TestCase
class BufferTest(TestCase):
def testBufferBuffer(self):
buf = gst.Buffer('test')
assert str(buffer(buf)) == 'test'
def testBufferStr(self):
buffer = gst.Buffer('test')
assert str(buffer) == 'test'
def testBufferAlloc(self):
bla = 'mooooooo'
buffer = gst.Buffer(bla + '12345')
gc.collect ()
assert str(buffer) == 'mooooooo12345'
def testBufferBadConstructor(self):
self.assertRaises(TypeError, gst.Buffer, 'test', 0)
def testBufferStrNull(self):
test_string = 't\0e\0s\0t\0'
buffer = gst.Buffer(test_string)
assert str(buffer) == test_string
def testBufferSize(self):
test_string = 'a little string'
buffer = gst.Buffer(test_string)
assert len(buffer) == len(test_string)
assert hasattr(buffer, 'size')
assert buffer.size == len(buffer)
def testBufferCreateSub(self):
s = ''
for i in range(64):
s += '%02d' % i
buffer = gst.Buffer(s)
self.assertEquals(len(buffer), 128)
sub = buffer.create_sub(16, 16)
self.assertEquals(sub.size, 16)
self.assertEquals(sub.data, buffer.data[16:32])
self.assertEquals(sub.offset, gst.CLOCK_TIME_NONE)
def testBufferMerge(self):
buffer1 = gst.Buffer('foo')
buffer2 = gst.Buffer('bar')
merged_buffer = buffer1.merge(buffer2)
assert str(merged_buffer) == 'foobar'
def testBufferJoin(self):
buffer1 = gst.Buffer('foo')
buffer2 = gst.Buffer('bar')
joined_buffer = buffer1.merge(buffer2)
assert str(joined_buffer) == 'foobar'
def testBufferSpan(self):
buffer1 = gst.Buffer('foo')
buffer2 = gst.Buffer('bar')
spaned_buffer = buffer1.span(0L, buffer2, 6L)
assert str(spaned_buffer) == 'foobar'
def testBufferCopyOnWrite(self):
s='test_vector'
buffer = gst.Buffer(s)
sub = buffer.create_sub(0, buffer.size)
self.assertEquals(sub.size, buffer.size)
out = sub.copy_on_write ()
self.assertEquals(out.size, sub.size)
assert str(out) == str(buffer)
out[5] = 'w'
assert str(out) == 'test_wector'
def testBufferFlagIsSet(self):
buffer = gst.Buffer()
# Off by default
assert not buffer.flag_is_set(gst.BUFFER_FLAG_READONLY)
# Try switching on and off
buffer.flag_set(gst.BUFFER_FLAG_READONLY)
assert buffer.flag_is_set(gst.BUFFER_FLAG_READONLY)
buffer.flag_unset(gst.BUFFER_FLAG_READONLY)
assert not buffer.flag_is_set(gst.BUFFER_FLAG_READONLY)
# Try switching on and off
buffer.flag_set(gst.BUFFER_FLAG_IN_CAPS)
assert buffer.flag_is_set(gst.BUFFER_FLAG_IN_CAPS)
buffer.flag_unset(gst.BUFFER_FLAG_IN_CAPS)
assert not buffer.flag_is_set(gst.BUFFER_FLAG_IN_CAPS)
def testAttrFlags(self):
buffer = gst.Buffer()
assert hasattr(buffer, "flags")
assert isinstance(buffer.flags, int)
def testAttrTimestamp(self):
buffer = gst.Buffer()
assert hasattr(buffer, "timestamp")
assert isinstance(buffer.timestamp, long)
assert buffer.timestamp == gst.CLOCK_TIME_NONE
buffer.timestamp = 0
assert buffer.timestamp == 0
buffer.timestamp = 2**64 - 1
assert buffer.timestamp == 2**64 - 1
def testAttrDuration(self):
buffer = gst.Buffer()
assert hasattr(buffer, "duration")
assert isinstance(buffer.duration, long)
assert buffer.duration == gst.CLOCK_TIME_NONE
buffer.duration = 0
assert buffer.duration == 0
buffer.duration = 2**64 - 1
assert buffer.duration == 2**64 - 1
def testAttrOffset(self):
buffer = gst.Buffer()
assert hasattr(buffer, "offset")
assert isinstance(buffer.offset, long)
assert buffer.offset == gst.CLOCK_TIME_NONE
buffer.offset = 0
assert buffer.offset == 0
buffer.offset = 2**64 - 1
assert buffer.offset == 2**64 - 1
def testAttrOffset_end(self):
buffer = gst.Buffer()
assert hasattr(buffer, "offset_end")
assert isinstance(buffer.offset_end, long)
assert buffer.offset_end == gst.CLOCK_TIME_NONE
buffer.offset_end = 0
assert buffer.offset_end == 0
buffer.offset_end = 2**64 - 1
assert buffer.offset_end == 2**64 - 1
def testBufferCaps(self):
buffer = gst.Buffer()
caps = gst.caps_from_string('foo/blah')
gst.info("before settings caps")
buffer.set_caps(caps)
gst.info("after settings caps")
c = buffer.get_caps()
gst.info("after getting caps")
self.assertEquals(caps, c)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,242 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2005 Thomas Vander Stichele
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, unittest, TestCase
import gobject
import time
import sys
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)
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)
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)
# FIXME: state change thread needs to die
while pipeline.__gstrefcount__ > 1:
gst.debug('waiting for pipeline refcount to drop')
time.sleep(0.1)
self.assertEquals(pipeline.__gstrefcount__, 1)
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
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")
loop.quit()
return True
def testSyncHandlerCallbackRefcount(self):
def callback1():
pass
def callback2():
pass
bus = gst.Bus()
# set
self.failUnless(sys.getrefcount(callback1), 2)
bus.set_sync_handler(callback1)
self.failUnless(sys.getrefcount(callback1), 3)
# set again
self.failUnless(sys.getrefcount(callback1), 3)
bus.set_sync_handler(callback1)
self.failUnless(sys.getrefcount(callback1), 3)
# replace
# this erros out in gst_bus_set_sync_handler, but we need to check that
# we don't leak anyway
self.failUnless(sys.getrefcount(callback2), 2)
bus.set_sync_handler(callback2)
self.failUnless(sys.getrefcount(callback1), 2)
self.failUnless(sys.getrefcount(callback2), 3)
# unset
bus.set_sync_handler(None)
self.failUnless(sys.getrefcount(callback2), 2)
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()
@@ -0,0 +1,196 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import sys
from common import gst, unittest, TestCase
class CapsTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.caps = gst.caps_from_string('video/x-raw-yuv,width=10,framerate=5/1;video/x-raw-rgb,width=15,framerate=10/1')
self.assertEquals(self.caps.__refcount__, 1)
self.structure = self.caps[0]
self.any = gst.Caps("ANY")
self.assertEquals(self.any.__refcount__, 1)
self.empty = gst.Caps()
self.assertEquals(self.empty.__refcount__, 1)
def testCapsMime(self):
mime = self.structure.get_name()
assert mime == 'video/x-raw-yuv'
def testCapsList(self):
'check if we can access Caps as a list'
structure = self.caps[0]
mime = structure.get_name()
assert mime == 'video/x-raw-yuv'
structure = self.caps[1]
mime = structure.get_name()
assert mime == 'video/x-raw-rgb'
def testCapsContainingMiniObjects(self):
# buffer contains hex encoding of ascii 'abcd'
caps = gst.Caps("video/x-raw-yuv, buf=(buffer)61626364")
buf = caps[0]['buf']
assert isinstance(buf, gst.Buffer)
assert buf.data == "abcd"
buf = gst.Buffer("1234")
caps[0]['buf2'] = buf
buf2 = caps[0]['buf2']
assert buf2 == buf
def testCapsConstructEmpty(self):
caps = gst.Caps()
assert isinstance(caps, gst.Caps)
def testCapsConstructFromString(self):
caps = gst.Caps('video/x-raw-yuv,width=10')
assert isinstance(caps, gst.Caps)
assert len(caps) == 1
assert isinstance(caps[0], gst.Structure)
assert caps[0].get_name() == 'video/x-raw-yuv'
assert isinstance(caps[0]['width'], int)
assert caps[0]['width'] == 10
def testCapsConstructFromStructure(self):
struct = gst.structure_from_string('video/x-raw-yuv,width=10,framerate=[0/1, 25/3]')
caps = gst.Caps(struct)
assert isinstance(caps, gst.Caps)
assert len(caps) == 1
assert isinstance(caps[0], gst.Structure)
assert caps[0].get_name() == 'video/x-raw-yuv'
assert isinstance(caps[0]['width'], int)
assert caps[0]['width'] == 10
assert isinstance(caps[0]['framerate'], gst.FractionRange)
def testCapsConstructFromStructures(self):
struct1 = gst.structure_from_string('video/x-raw-yuv,width=10')
struct2 = gst.structure_from_string('video/x-raw-rgb,height=20.0')
caps = gst.Caps(struct1, struct2)
assert isinstance(caps, gst.Caps)
assert len(caps) == 2
struct = caps[0]
assert isinstance(struct, gst.Structure), struct
assert struct.get_name() == 'video/x-raw-yuv', struct.get_name()
assert struct.has_key('width')
assert isinstance(struct['width'], int)
assert struct['width'] == 10
struct = caps[1]
assert isinstance(struct, gst.Structure), struct
assert struct.get_name() == 'video/x-raw-rgb', struct.get_name()
assert struct.has_key('height')
assert isinstance(struct['height'], float)
assert struct['height'] == 20.0
def testCapsReferenceStructs(self):
'test that shows why it\'s not a good idea to use structures by reference'
caps = gst.Caps('hi/mom,width=0')
structure = caps[0]
del caps
assert structure['width'] == 0
def testCapsStructureChange(self):
'test if changing the structure of the caps works by reference'
assert self.structure['width'] == 10
self.structure['width'] = 5
assert self.structure['width'] == 5.0
# check if we changed the caps as well
structure = self.caps[0]
assert structure['width'] == 5.0
def testCapsBadConstructor(self):
struct = gst.structure_from_string('video/x-raw-yuv,width=10')
self.assertRaises(TypeError, gst.Caps, None)
self.assertRaises(TypeError, gst.Caps, 1)
self.assertRaises(TypeError, gst.Caps, 2.0)
self.assertRaises(TypeError, gst.Caps, object)
self.assertRaises(TypeError, gst.Caps, 1, 2, 3)
# This causes segfault!
#self.assertRaises(TypeError, gst.Caps, struct, 10, None)
def testTrueFalse(self):
'test that comparisons using caps work the intended way'
assert self.any # not empty even though it has no structures
assert not self.empty
assert not gst.Caps('EMPTY') # also empty
assert gst.Caps('your/mom')
def testComparisons(self):
assert self.empty < self.any
assert self.empty < self.structure
assert self.empty < self.caps
assert self.caps < self.any
assert self.empty <= self.empty
assert self.caps <= self.caps
assert self.caps <= self.any
assert self.empty == "EMPTY"
assert self.caps != self.any
assert self.empty != self.any
assert self.any > self.empty
assert self.any >= self.empty
def testFilters(self):
name = 'video/x-raw-yuv'
filtercaps = gst.Caps(*[struct for struct in self.caps if struct.get_name() == name])
intersection = self.caps & 'video/x-raw-yuv'
assert filtercaps == intersection
def doSubtract(self, set, subset):
'''mimic the test in GStreamer core's testsuite/caps/subtract.c'''
assert not set - set
assert not subset - subset
assert not subset - set
test = set - subset
assert test
test2 = test | subset
test = test2 - set
assert not test
#our own extensions foolow here
assert subset == set & subset
assert set == set | subset
assert set - subset == set ^ subset
def testSubtract(self):
self.doSubtract(
gst.Caps ("some/mime, _int = [ 1, 2 ], list = { \"A\", \"B\", \"C\" }"),
gst.Caps ("some/mime, _int = 1, list = \"A\""))
self.doSubtract(
gst.Caps ("some/mime, _double = (double) 1.0; other/mime, _int = { 1, 2 }"),
gst.Caps ("some/mime, _double = (double) 1.0"))
def testNoneValue(self):
caps = gst.Caps("foo")
def invalid_assignment():
caps[0]["bar"] = None
self.assertRaises(TypeError, invalid_assignment)
def invalid_set_value():
caps[0].set_value("bar", None)
self.assertRaises(TypeError, invalid_set_value)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,268 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, unittest, TestCase, pygobject_2_13
import sys
# since I can't subclass gst.Element for some reason, I use a bin here
# it don't matter to Jesus
class TestElement(gst.Bin):
def break_it_down(self):
self.debug('Hammer Time')
class ElementTest(TestCase):
name = 'fakesink'
alias = 'sink'
def testGoodConstructor(self):
element = gst.element_factory_make(self.name, self.alias)
assert element is not None, 'element is None'
assert isinstance(element, gst.Element)
assert element.get_name() == self.alias
## FIXME : Make a new test for state changes, using bus signals
## class FakeSinkTest(ElementTest):
## FAKESINK_STATE_ERROR_NONE = "0"
## FAKESINK_STATE_ERROR_NULL_READY, = "1"
## FAKESINK_STATE_ERROR_READY_PAUSED, = "2"
## FAKESINK_STATE_ERROR_PAUSED_PLAYING = "3"
## FAKESINK_STATE_ERROR_PLAYING_PAUSED = "4"
## FAKESINK_STATE_ERROR_PAUSED_READY = "5"
## FAKESINK_STATE_ERROR_READY_NULL = "6"
## name = 'fakesink'
## alias = 'sink'
## def setUp(self):
## ElementTest.setUp(self)
## self.element = gst.element_factory_make('fakesink', 'sink')
## def tearDown(self):
## self.element.set_state(gst.STATE_NULL)
## del self.element
## ElementTest.tearDown(self)
## def checkError(self, old_state, state, name):
## assert self.element.get_state() == gst.STATE_NULL
## assert self.element.set_state(old_state)
## assert self.element.get_state() == old_state
## self.element.set_property('state-error', name)
## self.error = False
## def error_cb(element, source, gerror, debug):
## assert isinstance(element, gst.Element)
## assert element == self.element
## assert isinstance(source, gst.Element)
## assert source == self.element
## assert isinstance(gerror, gst.GError)
## self.error = True
## self.element.connect('error', error_cb)
## self.element.set_state (state)
## assert self.error, 'error not set'
## #assert error_message.find('ERROR') != -1
## self.element.get_state() == old_state, 'state changed'
## def testStateErrorNullReady(self):
## self.checkError(gst.STATE_NULL, gst.STATE_READY,
## self.FAKESINK_STATE_ERROR_NULL_READY)
## def testStateErrorReadyPaused(self):
## self.checkError(gst.STATE_READY, gst.STATE_PAUSED,
## self.FAKESINK_STATE_ERROR_READY_PAUSED)
## def testStateErrorPausedPlaying(self):
## self.checkError(gst.STATE_PAUSED, gst.STATE_PLAYING,
## self.FAKESINK_STATE_ERROR_PAUSED_PLAYING)
## def testStateErrorPlayingPaused(self):
## self.checkError(gst.STATE_PLAYING, gst.STATE_PAUSED,
## self.FAKESINK_STATE_ERROR_PLAYING_PAUSED)
## def testStateErrorPausedReady(self):
## self.checkError(gst.STATE_PAUSED, gst.STATE_READY,
## self.FAKESINK_STATE_ERROR_PAUSED_READY)
## def testStateErrorReadyNull(self):
## self.checkError(gst.STATE_READY, gst.STATE_NULL,
## self.FAKESINK_STATE_ERROR_READY_NULL)
## def checkStateChange(self, old, new):
## def state_change_cb(element, old_s, new_s):
## assert isinstance(element, gst.Element)
## assert element == self.element
## assert old_s == old
## assert new_s == new
## assert self.element.set_state(old)
## assert self.element.get_state(0.0)[1] == old
## # FIXME: replace with messages
## # self.element.connect('state-change', state_change_cb)
## assert self.element.set_state(new)
## assert self.element.get_state(0.0)[1] == new
## def testStateChangeNullReady(self):
## self.checkStateChange(gst.STATE_NULL, gst.STATE_READY)
## def testStateChangeReadyPaused(self):
## self.checkStateChange(gst.STATE_READY, gst.STATE_PAUSED)
## def testStateChangePausedPlaying(self):
## self.checkStateChange(gst.STATE_PAUSED, gst.STATE_PLAYING)
## def testStateChangePlayingPaused(self):
## self.checkStateChange(gst.STATE_PLAYING, gst.STATE_PAUSED)
## def testStateChangePausedReady(self):
## self.checkStateChange(gst.STATE_PAUSED, gst.STATE_READY)
## def testStateChangeReadyNull(self):
## self.checkStateChange(gst.STATE_READY, gst.STATE_NULL)
class NonExistentTest(ElementTest):
name = 'this-element-does-not-exist'
alias = 'no-alias'
testGoodConstructor = lambda s: None
testGoodConstructor2 = lambda s: None
class FileSrcTest(ElementTest):
name = 'filesrc'
alias = 'source'
class FileSinkTest(ElementTest):
name = 'filesink'
alias = 'sink'
class ElementName(TestCase):
def testElementStateGetName(self):
get_name = gst.element_state_get_name
for state in ('NULL',
'READY',
'PLAYING',
'PAUSED'):
name = 'STATE_' + state
assert hasattr(gst, name)
attr = getattr(gst, name)
assert get_name(attr) == state
assert get_name(gst.STATE_VOID_PENDING) == 'VOID_PENDING'
assert get_name(-1) == 'UNKNOWN!(-1)'
self.assertRaises(TypeError, get_name, '')
class QueryTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.pipeline = gst.parse_launch('fakesrc name=source ! fakesink')
self.assertEquals(self.pipeline.__gstrefcount__, 1)
self.element = self.pipeline.get_by_name('source')
self.assertEquals(self.pipeline.__gstrefcount__, 1)
self.assertEquals(self.element.__gstrefcount__, 2)
self.assertEquals(sys.getrefcount(self.element), pygobject_2_13 and 2 or 3)
def tearDown(self):
del self.pipeline
del self.element
TestCase.tearDown(self)
def testQuery(self):
gst.debug('querying fakesrc in FORMAT_BYTES')
res = self.element.query_position(gst.FORMAT_BYTES)
self.assertEquals(self.pipeline.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3)
self.assertEquals(self.element.__gstrefcount__, 2)
self.assertEquals(sys.getrefcount(self.element), pygobject_2_13 and 2 or 3)
assert res
assert res[0] == 0
self.assertRaises(gst.QueryError, self.element.query_position,
gst.FORMAT_TIME)
self.gccollect()
class QueueTest(TestCase):
def testConstruct(self):
queue = gst.element_factory_make('queue')
assert queue.get_name() == 'queue0'
self.assertEquals(queue.__gstrefcount__, 1)
class DebugTest(TestCase):
def testDebug(self):
e = gst.element_factory_make('fakesrc')
e.error('I am an error string')
e.warning('I am a warning string')
e.info('I am an info string')
e.debug('I am a debug string')
e.log('I am a log string')
e.debug('I am a formatted %s %s' % ('log', 'string'))
def testElementDebug(self):
e = TestElement("testelement")
e.set_property("name", "testelement")
e.break_it_down()
class LinkTest(TestCase):
def testLinkNoPads(self):
src = gst.Bin()
sink = gst.Bin()
self.assertRaises(gst.LinkError, src.link, sink)
def testLink(self):
src = gst.element_factory_make('fakesrc')
sink = gst.element_factory_make('fakesink')
self.failUnless(src.link(sink))
# FIXME: this unlink leaks, no idea why
# src.unlink(sink)
# print src.__gstrefcount__
def testLinkPads(self):
src = gst.element_factory_make('fakesrc')
sink = gst.element_factory_make('fakesink')
# print src.__gstrefcount__
self.failUnless(src.link_pads("src", sink, "sink"))
src.unlink_pads("src", sink, "sink")
def testLinkFiltered(self):
# a filtered link uses capsfilter and thus needs a bin
bin = gst.Bin()
src = gst.element_factory_make('fakesrc')
sink = gst.element_factory_make('fakesink')
bin.add(src, sink)
caps = gst.caps_from_string("audio/x-raw-int")
self.failUnless(src.link(sink, caps))
# DANGER WILL. src is not actually connected to sink, since
# there's a capsfilter in the way. What a leaky abstraction.
# FIXME
# src.unlink(sink)
# instead, mess with pads directly
pad = src.get_pad('src')
pad.unlink(pad.get_peer())
pad = sink.get_pad('sink')
pad.get_peer().unlink(pad)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,244 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import os
import sys
import time
import tempfile
from common import gst, unittest, testhelper, TestCase
class EventTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.pipeline = gst.parse_launch('fakesrc ! fakesink name=sink')
self.sink = self.pipeline.get_by_name('sink')
self.pipeline.set_state(gst.STATE_PLAYING)
def tearDown(self):
gst.debug('setting pipeline to NULL')
self.pipeline.set_state(gst.STATE_NULL)
gst.debug('set pipeline to NULL')
# FIXME: wait for state change thread to die
while self.pipeline.__gstrefcount__ > 1:
gst.debug('waiting for self.pipeline G rc to drop to 1')
time.sleep(0.1)
self.assertEquals(self.pipeline.__gstrefcount__, 1)
del self.sink
del self.pipeline
TestCase.tearDown(self)
def testEventSeek(self):
# this event only serves to change the rate of data transfer
event = gst.event_new_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH,
gst.SEEK_TYPE_NONE, 0, gst.SEEK_TYPE_NONE, 0)
# FIXME: but basesrc goes into an mmap/munmap spree, needs to be fixed
event = gst.event_new_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH,
gst.SEEK_TYPE_SET, 0, gst.SEEK_TYPE_NONE, 0)
assert event
gst.debug('sending event')
self.sink.send_event(event)
gst.debug('sent event')
self.assertEqual(event.parse_seek(), (1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH,
gst.SEEK_TYPE_SET, 0, gst.SEEK_TYPE_NONE, 0))
def testWrongEvent(self):
buffer = gst.Buffer()
self.assertRaises(TypeError, self.sink.send_event, buffer)
number = 1
self.assertRaises(TypeError, self.sink.send_event, number)
class EventFileSrcTest(TestCase):
def setUp(self):
TestCase.setUp(self)
gst.info("start")
self.filename = tempfile.mktemp()
open(self.filename, 'w').write(''.join(map(str, range(10))))
self.pipeline = gst.parse_launch('filesrc name=source location=%s blocksize=1 ! fakesink signal-handoffs=1 name=sink' % self.filename)
self.source = self.pipeline.get_by_name('source')
self.sink = self.pipeline.get_by_name('sink')
self.sigid = self.sink.connect('handoff', self.handoff_cb)
self.bus = self.pipeline.get_bus()
def tearDown(self):
self.pipeline.set_state(gst.STATE_NULL)
self.sink.disconnect(self.sigid)
if os.path.exists(self.filename):
os.remove(self.filename)
del self.bus
del self.pipeline
del self.source
del self.sink
del self.handoffs
TestCase.tearDown(self)
def handoff_cb(self, element, buffer, pad):
self.handoffs.append(str(buffer))
def playAndIter(self):
self.handoffs = []
self.pipeline.set_state(gst.STATE_PLAYING)
assert self.pipeline.set_state(gst.STATE_PLAYING)
while 42:
msg = self.bus.pop()
if msg and msg.type == gst.MESSAGE_EOS:
break
assert self.pipeline.set_state(gst.STATE_PAUSED)
handoffs = self.handoffs
self.handoffs = []
return handoffs
def sink_seek(self, offset, method=gst.SEEK_TYPE_SET):
self.sink.seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH,
method, offset,
gst.SEEK_TYPE_NONE, 0)
def testSimple(self):
handoffs = self.playAndIter()
assert handoffs == map(str, range(10))
def testSeekCur(self):
self.sink_seek(8)
self.playAndIter()
class TestEmit(TestCase):
def testEmit(self):
object = testhelper.get_object()
object.connect('event', self._event_cb)
# First emit from C
testhelper.emit_event(object)
# Then emit from Python
object.emit('event', gst.event_new_eos())
def _event_cb(self, obj, event):
assert isinstance(event, gst.Event)
class TestDelayedEventProbe(TestCase):
# this test:
# starts a pipeline with only a source
# adds an event probe to catch the (first) new-segment
# adds a buffer probe to "autoplug" and send out this event
def setUp(self):
TestCase.setUp(self)
self.pipeline = gst.Pipeline()
self.src = gst.element_factory_make('fakesrc')
self.src.set_property('num-buffers', 10)
self.pipeline.add(self.src)
self.srcpad = self.src.get_pad('src')
def tearDown(self):
gst.debug('setting pipeline to NULL')
self.pipeline.set_state(gst.STATE_NULL)
gst.debug('set pipeline to NULL')
# FIXME: wait for state change thread to die
while self.pipeline.__gstrefcount__ > 1:
gst.debug('waiting for self.pipeline G rc to drop to 1')
time.sleep(0.1)
self.assertEquals(self.pipeline.__gstrefcount__, 1)
def testProbe(self):
self.srcpad.add_event_probe(self._event_probe_cb)
self._buffer_probe_id = self.srcpad.add_buffer_probe(
self._buffer_probe_cb)
self._newsegment = None
self._eos = None
self._had_buffer = False
self.pipeline.set_state(gst.STATE_PLAYING)
while not self._eos:
time.sleep(0.1)
# verify if our newsegment event is still around and valid
self.failUnless(self._newsegment)
self.assertEquals(self._newsegment.type, gst.EVENT_NEWSEGMENT)
self.assertEquals(self._newsegment.__grefcount__, 1)
# verify if our eos event is still around and valid
self.failUnless(self._eos)
self.assertEquals(self._eos.type, gst.EVENT_EOS)
self.assertEquals(self._eos.__grefcount__, 1)
def _event_probe_cb(self, pad, event):
if event.type == gst.EVENT_NEWSEGMENT:
self._newsegment = event
self.assertEquals(event.__grefcount__, 3)
# drop the event, we're storing it for later sending
return False
if event.type == gst.EVENT_EOS:
self._eos = event
# we also want fakesink to get it
return True
# sinks now send Latency events upstream
if event.type == gst.EVENT_LATENCY:
return True
self.fail("Got an unknown event %r" % event)
def _buffer_probe_cb(self, pad, buffer):
self.failUnless(self._newsegment)
# fake autoplugging by now putting in a fakesink
sink = gst.element_factory_make('fakesink')
self.pipeline.add(sink)
self.src.link(sink)
sink.set_state(gst.STATE_PLAYING)
pad = sink.get_pad('sink')
pad.send_event(self._newsegment)
# we don't want to be called again
self.srcpad.remove_buffer_probe(self._buffer_probe_id)
self._had_buffer = True
# now let the buffer through
return True
class TestEventCreationParsing(TestCase):
def testEventStep(self):
if hasattr(gst.Event, "parse_step"):
e = gst.event_new_step(gst.FORMAT_TIME, 42, 1.0, True, True)
self.assertEquals(e.type, gst.EVENT_STEP)
fmt, amount, rate, flush, intermediate = e.parse_step()
self.assertEquals(fmt, gst.FORMAT_TIME)
self.assertEquals(amount, 42)
self.assertEquals(rate, 1.0)
self.assertEquals(flush, True)
self.assertEquals(intermediate, True)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,194 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, unittest, TestCase, pygobject_2_13
import sys
import gc
import gobject
class SrcBin(gst.Bin):
def prepare(self):
src = gst.element_factory_make('fakesrc')
self.add(src)
pad = src.get_pad("src")
ghostpad = gst.GhostPad("src", pad)
self.add_pad(ghostpad)
gobject.type_register(SrcBin)
class SinkBin(gst.Bin):
def prepare(self):
sink = gst.element_factory_make('fakesink')
self.add(sink)
pad = sink.get_pad("sink")
ghostpad = gst.GhostPad("sink", pad)
self.add_pad(ghostpad)
self.sink = sink
def connect_handoff(self, cb, *args, **kwargs):
self.sink.set_property('signal-handoffs', True)
self.sink.connect('handoff', cb, *args, **kwargs)
gobject.type_register(SinkBin)
class PipeTest(TestCase):
def setUp(self):
gst.info("setUp")
TestCase.setUp(self)
self.pipeline = gst.Pipeline()
self.assertEquals(self.pipeline.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3)
self.src = SrcBin()
self.src.prepare()
self.sink = SinkBin()
self.sink.prepare()
self.assertEquals(self.src.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3)
self.assertEquals(self.sink.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3)
gst.info("end of SetUp")
def tearDown(self):
gst.info("tearDown")
self.assertTrue (self.pipeline.__gstrefcount__ >= 1 and self.pipeline.__gstrefcount__ <= 2)
self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3)
self.assertEquals(self.src.__gstrefcount__, 2)
self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3)
self.assertEquals(self.sink.__gstrefcount__, 2)
self.assertEquals(sys.getrefcount(self.sink), 3)
gst.debug('deleting pipeline')
del self.pipeline
self.gccollect()
self.assertEquals(self.src.__gstrefcount__, 1) # parent gone
self.assertEquals(self.sink.__gstrefcount__, 1) # parent gone
self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3)
self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3)
gst.debug('deleting src')
del self.src
self.gccollect()
gst.debug('deleting sink')
del self.sink
self.gccollect()
TestCase.tearDown(self)
def testBinState(self):
self.pipeline.add(self.src, self.sink)
self.src.link(self.sink)
self.sink.connect_handoff(self._sink_handoff_cb)
self._handoffs = 0
self.assertTrue(self.pipeline.set_state(gst.STATE_PLAYING) != gst.STATE_CHANGE_FAILURE)
while True:
(ret, cur, pen) = self.pipeline.get_state()
if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_PLAYING:
break
while self._handoffs < 10:
pass
self.assertEquals(self.pipeline.set_state(gst.STATE_NULL), gst.STATE_CHANGE_SUCCESS)
while True:
(ret, cur, pen) = self.pipeline.get_state()
if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_NULL:
break
## def testProbedLink(self):
## self.pipeline.add(self.src)
## pad = self.src.get_pad("src")
## self.sink.connect_handoff(self._sink_handoff_cb)
## self._handoffs = 0
## # FIXME: adding a probe to the ghost pad does not work atm
## # id = pad.add_buffer_probe(self._src_buffer_probe_cb)
## realpad = pad.get_target()
## self._probe_id = realpad.add_buffer_probe(self._src_buffer_probe_cb)
## self._probed = False
## while True:
## (ret, cur, pen) = self.pipeline.get_state()
## if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_PLAYING:
## break
## while not self._probed:
## pass
## while self._handoffs < 10:
## pass
## self.pipeline.set_state(gst.STATE_NULL)
## while True:
## (ret, cur, pen) = self.pipeline.get_state()
## if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_NULL:
## break
def _src_buffer_probe_cb(self, pad, buffer):
gst.debug("received probe on pad %r" % pad)
self._probed = True
gst.debug('adding sink bin')
self.pipeline.add(self.sink)
# this seems to get rid of the warnings about pushing on an unactivated
# pad
gst.debug('setting sink state')
# FIXME: attempt one: sync to current pending state of bin
(res, cur, pen) = self.pipeline.get_state(timeout=0)
target = pen
if target == gst.STATE_VOID_PENDING:
target = cur
gst.debug("setting sink state to %r" % target)
# FIXME: the following print can cause a lock-up; why ?
# print target
# if we don't set async, it will possibly end up in PAUSED
self.sink.set_state(target)
gst.debug('linking')
self.src.link(self.sink)
gst.debug('removing buffer probe id %r' % self._probe_id)
pad.remove_buffer_probe(self._probe_id)
self._probe_id = None
gst.debug('done')
def _sink_handoff_cb(self, sink, buffer, pad):
gst.debug('received handoff on pad %r' % pad)
self._handoffs += 1
class TargetTest(TestCase):
def test_target(self):
src = gst.Pad("src", gst.PAD_SRC)
ghost = gst.GhostPad("ghost_src", src)
self.failUnless(ghost.get_target() is src)
ghost.set_target(None)
self.failUnless(ghost.get_target() is None)
ghost.set_target(src)
self.failUnless(ghost.get_target() is src)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,92 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, unittest, TestCase
import gobject
def find_mixer_element():
""" Searches for an element implementing the mixer interface """
allmix = [x for x in gst.registry_get_default().get_feature_list(gst.ElementFactory)
if x.has_interface("GstMixer") and x.has_interface("GstPropertyProbe")]
if allmix == []:
return None
return allmix[0]
class Availability(TestCase):
def testXOverlay(self):
assert hasattr(gst.interfaces, 'XOverlay')
assert issubclass(gst.interfaces.XOverlay, gobject.GInterface)
def testMixer(self):
assert hasattr(gst.interfaces, 'Mixer')
assert issubclass(gst.interfaces.Mixer, gobject.GInterface)
class FunctionCall(TestCase):
def FIXME_testXOverlay(self):
# obviously a testsuite is not allowed to instantiate this
# since it needs a running X or will fail. find some way to
# deal with that.
element = gst.element_factory_make('xvimagesink')
assert isinstance(element, gst.Element)
assert isinstance(element, gst.interfaces.XOverlay)
element.set_xwindow_id(0L)
class MixerTest(TestCase):
def setUp(self):
TestCase.setUp(self)
amix = find_mixer_element()
if amix:
self.mixer = amix.create()
else:
self.mixer = None
def tearDown(self):
del self.mixer
TestCase.tearDown(self)
def testGetProperty(self):
if self.mixer == None:
return
self.failUnless(self.mixer.probe_get_property('device'))
self.assertRaises(ValueError,
self.mixer.probe_get_property, 'non-existent')
def testGetProperties(self):
if self.mixer == None:
return
properties = self.mixer.probe_get_properties()
self.failUnless(properties)
self.assertEqual(type(properties), list)
prop = properties[0]
self.assertEqual(prop.name, 'device')
self.assertEqual(prop.value_type, gobject.TYPE_STRING)
def testGetValuesName(self):
if self.mixer == None:
return
values = self.mixer.probe_get_values_name('device')
self.assertEqual(type(values), list)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,117 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# Copyright (C) 2005 Johan Dahlin
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import unittest
from common import gst, TestCase
class IteratorTest(TestCase):
# XXX: Elements
def testBinIterateElements(self):
pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink")
elements = list(pipeline.elements())
fakesrc = pipeline.get_by_name("src")
fakesink = pipeline.get_by_name("sink")
self.assertEqual(len(elements), 2)
self.failUnless(fakesrc in elements)
self.failUnless(fakesink in elements)
pipeline.remove(fakesrc)
elements = list(pipeline.elements())
self.assertEqual(len(elements), 1)
self.failUnless(not fakesrc in pipeline)
# XXX : There seems to be a problem about the GType
# set in gst_bin_iterated_sorted
def testBinIterateSorted(self):
pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink")
elements = list(pipeline.sorted())
fakesrc = pipeline.get_by_name("src")
fakesink = pipeline.get_by_name("sink")
self.assertEqual(elements[0], fakesink)
self.assertEqual(elements[1], fakesrc)
def testBinIterateRecurse(self):
pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink")
elements = list(pipeline.recurse())
fakesrc = pipeline.get_by_name("src")
fakesink = pipeline.get_by_name("sink")
self.assertEqual(elements[0], fakesink)
self.assertEqual(elements[1], fakesrc)
def testBinIterateSinks(self):
pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink")
elements = list(pipeline.sinks())
fakesrc = pipeline.get_by_name("src")
fakesink = pipeline.get_by_name("sink")
self.assertEqual(len(elements), 1)
self.failUnless(fakesink in elements)
self.failUnless(not fakesrc in elements)
def testIteratePadsFakeSrc(self):
fakesrc = gst.element_factory_make('fakesrc')
pads = list(fakesrc.pads())
srcpad = fakesrc.get_pad('src')
self.assertEqual(len(pads), 1)
self.assertEqual(pads[0], srcpad)
srcpads = list(fakesrc.src_pads())
self.assertEqual(len(srcpads), 1)
self.assertEqual(srcpads[0], srcpad)
sinkpads = list(fakesrc.sink_pads())
self.assertEqual(sinkpads, [])
self.assertEqual(len(list(fakesrc)), 1)
for pad in fakesrc:
self.assertEqual(pad, srcpad)
break
else:
raise AssertionError
def testIteratePadsFakeSink(self):
fakesink = gst.element_factory_make('fakesink')
pads = list(fakesink.pads())
sinkpad = fakesink.get_pad('sink')
self.assertEqual(len(pads), 1)
self.assertEqual(pads[0], sinkpad)
srcpads = list(fakesink.src_pads())
self.assertEqual(srcpads, [])
sinkpads = list(fakesink.sink_pads())
self.assertEqual(len(sinkpads), 1)
self.assertEqual(sinkpads[0], sinkpad)
self.assertEqual(len(list(fakesink)), 1)
for pad in fakesink:
self.assertEqual(pad, sinkpad)
break
else:
raise AssertionError
def testInvalidIterator(self):
p = gst.Pad("p", gst.PAD_SRC)
# The C function will return NULL, we should
# therefore have an exception raised
self.assertRaises(TypeError, p.iterate_internal_links)
del p
@@ -0,0 +1,37 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, TestCase
from gst import tag
class TesLibTag(TestCase):
def testXmp(self):
taglist = gst.TagList()
taglist['title'] = 'my funny title'
taglist['geo-location-latitude'] = 23.25
xmp = tag.tag_list_to_xmp_buffer (taglist, True)
self.assertNotEquals(xmp, None)
taglist2 = tag.tag_list_from_xmp_buffer (xmp)
self.assertEquals(len(taglist2), 2)
self.assertEquals(taglist2['title'], 'my funny title')
self.assertEquals(taglist2['geo-location-latitude'], 23.25)
@@ -0,0 +1,202 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2005 Thomas Vander Stichele
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import sys
from common import gobject, gst, unittest, TestCase
import gc
class NewTest(TestCase):
def testEOS(self):
gst.info("creating new bin")
b = gst.Bin()
gst.info("creating new EOS message from that bin")
m = gst.message_new_eos(b)
gst.info("got message : %s" % m)
def message_application_cb(self, bus, message):
gst.info("got application message")
self.got_message = True
self.loop.quit()
def testApplication(self):
self.loop = gobject.MainLoop()
gst.info("creating new pipeline")
bin = gst.Pipeline()
bus = bin.get_bus()
bus.add_signal_watch()
self.got_message = False
bus.connect('message::application', self.message_application_cb)
struc = gst.Structure("foo")
msg = gst.message_new_application(bin, struc)
# the bus is flushing in NULL, so we need to set the pipeline to READY
bin.set_state(gst.STATE_READY)
bus.post(msg)
self.loop.run()
bus.remove_signal_watch()
bin.set_state(gst.STATE_NULL)
self.failUnless(self.got_message == True)
self.gccollect()
class TestCreateMessages(TestCase):
def setUp(self):
TestCase.setUp(self)
self.element = gst.Bin()
def tearDown(self):
del self.element
def testCustomMessage(self):
# create two custom messages using the same structure
s = gst.Structure("something")
assert s != None
e1 = gst.message_new_custom(gst.MESSAGE_APPLICATION, self.element, s)
assert e1
e2 = gst.message_new_custom(gst.MESSAGE_APPLICATION, self.element, s)
assert e2
# make sure the two structures are equal
self.assertEquals(e1.structure.to_string(),
e2.structure.to_string())
def testTagMessage(self):
# Create a taglist
t = gst.TagList()
t['something'] = "else"
t['another'] = 42
# Create two messages using that same taglist
m1 = gst.message_new_tag(self.element, t)
assert m1
m2 = gst.message_new_tag(self.element, t)
assert m2
# make sure the two messages have the same taglist
t1 = m1.parse_tag()
assert t1
keys = t1.keys()
keys.sort()
self.assertEquals(keys, ['another', 'something'])
self.assertEquals(t1['something'], "else")
self.assertEquals(t1['another'], 42)
t2 = m2.parse_tag()
assert t2
keys = t2.keys()
keys.sort()
self.assertEquals(keys, ['another', 'something'])
self.assertEquals(t2['something'], "else")
self.assertEquals(t2['another'], 42)
def testTagFullMessage(self):
if hasattr(gst.Message, 'parse_tag_full'):
p = gst.Pad("blahblah", gst.PAD_SRC)
# Create a taglist
t = gst.TagList()
t['something'] = "else"
t['another'] = 42
# Create two messages using that same taglist
m1 = gst.message_new_tag_full(self.element, p, t)
assert m1
m2 = gst.message_new_tag_full(self.element, p, t)
assert m2
# make sure the two messages have the same taglist
p1, t1 = m1.parse_tag_full()
assert t1
keys = t1.keys()
keys.sort()
self.assertEquals(p1, p)
self.assertEquals(keys, ['another', 'something'])
self.assertEquals(t1['something'], "else")
self.assertEquals(t1['another'], 42)
p2, t2 = m2.parse_tag_full()
assert t2
keys = t2.keys()
keys.sort()
self.assertEquals(p2, p)
self.assertEquals(keys, ['another', 'something'])
self.assertEquals(t2['something'], "else")
self.assertEquals(t2['another'], 42)
def testStepStartMessage(self):
if hasattr(gst, 'message_new_step_start'):
m = gst.message_new_step_start(self.element, True,
gst.FORMAT_TIME, 42, 1.0,
True, True)
self.assertEquals(m.type, gst.MESSAGE_STEP_START)
active, format, amount, rate, flush, intermediate = m.parse_step_start()
self.assertEquals(active, True)
self.assertEquals(format, gst.FORMAT_TIME)
self.assertEquals(amount, 42)
self.assertEquals(rate, 1.0)
self.assertEquals(flush, True)
self.assertEquals(intermediate, True)
def testStepDoneMessage(self):
if hasattr(gst, 'message_new_step_done'):
m = gst.message_new_step_done(self.element, gst.FORMAT_TIME, 42,
1.0, True, True, 54, True)
self.assertEquals(m.type, gst.MESSAGE_STEP_DONE)
fmt, am, rat, flu, inter, dur, eos = m.parse_step_done()
self.assertEquals(fmt, gst.FORMAT_TIME)
self.assertEquals(am, 42)
self.assertEquals(rat, 1.0)
self.assertEquals(flu, True)
self.assertEquals(inter, True)
self.assertEquals(dur, 54)
self.assertEquals(eos, True)
def testStructureChangeMessage(self):
if hasattr(gst, 'message_new_structure_change'):
p = gst.Pad("blah", gst.PAD_SINK)
m = gst.message_new_structure_change(p,
gst.STRUCTURE_CHANGE_TYPE_PAD_LINK,
self.element, True)
self.assertEquals(m.type, gst.MESSAGE_STRUCTURE_CHANGE)
sct, owner, busy = m.parse_structure_change()
self.assertEquals(sct, gst.STRUCTURE_CHANGE_TYPE_PAD_LINK)
self.assertEquals(owner, self.element)
self.assertEquals(busy, True)
def testRequestStateMessage(self):
if hasattr(gst, 'message_new_request_state'):
m = gst.message_new_request_state(self.element, gst.STATE_NULL)
self.assertEquals(m.type, gst.MESSAGE_REQUEST_STATE)
self.assertEquals(m.parse_request_state(), gst.STATE_NULL)
def testBufferingStatsMessage(self):
if hasattr(gst.Message, 'set_buffering_stats'):
gst.debug("Creating buffering message")
m = gst.message_new_buffering(self.element, 50)
gst.debug("Setting stats")
m.set_buffering_stats(gst.BUFFERING_LIVE, 30, 1024, 123456)
self.assertEquals(m.type, gst.MESSAGE_BUFFERING)
mode, ain, aout, left = m.parse_buffering_stats()
self.assertEquals(mode, gst.BUFFERING_LIVE)
self.assertEquals(ain, 30)
self.assertEquals(aout, 1024)
self.assertEquals(left, 123456)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,568 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, unittest, TestCase, pygobject_2_13
import sys
import time
class PadTemplateTest(TestCase):
def testConstructor(self):
template = gst.PadTemplate("template", gst.PAD_SINK,
gst.PAD_ALWAYS, gst.caps_from_string("audio/x-raw-int"))
self.failUnless(template)
self.assertEquals(sys.getrefcount(template), pygobject_2_13 and 2 or 3)
#self.assertEquals(template.__gstrefcount__, 1)
class PadPushUnlinkedTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.src = gst.Pad("src", gst.PAD_SRC)
self.sink = gst.Pad("sink", gst.PAD_SINK)
def tearDown(self):
self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3)
self.assertEquals(self.src.__gstrefcount__, 1)
del self.src
self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3)
self.assertEquals(self.sink.__gstrefcount__, 1)
del self.sink
TestCase.tearDown(self)
def testNoProbe(self):
self.buffer = gst.Buffer()
self.assertEquals(self.buffer.__grefcount__, 1)
self.assertEquals(self.src.push(self.buffer), gst.FLOW_NOT_LINKED)
# pushing it takes a ref in the python wrapper to keep buffer
# alive afterwards; but the core unrefs the ref it receives
self.assertEquals(self.buffer.__grefcount__, 1)
def testFalseProbe(self):
id = self.src.add_buffer_probe(self._probe_handler, False)
self.buffer = gst.Buffer()
self.assertEquals(self.buffer.__grefcount__, 1)
self.assertEquals(self.src.push(self.buffer), gst.FLOW_OK)
self.assertEquals(self.buffer.__grefcount__, 1)
self.src.remove_buffer_probe(id)
def testTrueProbe(self):
id = self.src.add_buffer_probe(self._probe_handler, True)
self.buffer = gst.Buffer()
self.assertEquals(self.buffer.__grefcount__, 1)
self.assertEquals(self.src.push(self.buffer), gst.FLOW_NOT_LINKED)
self.assertEquals(self.buffer.__grefcount__, 1)
self.src.remove_buffer_probe(id)
def _probe_handler(self, pad, buffer, ret):
return ret
class PadPushLinkedTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.src = gst.Pad("src", gst.PAD_SRC)
self.sink = gst.Pad("sink", gst.PAD_SINK)
caps = gst.caps_from_string("foo/bar")
self.src.set_caps(caps)
self.sink.set_caps(caps)
self.sink.set_chain_function(self._chain_func)
self.src.set_active(True)
self.sink.set_active(True)
self.src.link(self.sink)
self.buffers = []
def tearDown(self):
self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3)
self.assertEquals(self.src.__gstrefcount__, 1)
self.src.set_caps(None)
del self.src
self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3)
self.assertEquals(self.sink.__gstrefcount__, 1)
self.sink.set_caps(None)
del self.sink
TestCase.tearDown(self)
def _chain_func(self, pad, buffer):
gst.debug('got buffer %r, id %x, with GMO rc %d'% (
buffer, id(buffer), buffer.__grefcount__))
self.buffers.append(buffer)
return gst.FLOW_OK
def testNoProbe(self):
self.buffer = gst.Buffer()
gst.debug('created new buffer %r, id %x' % (
self.buffer, id(self.buffer)))
self.assertEquals(self.buffer.__grefcount__, 1)
gst.debug('pushing buffer on linked pad, no probe')
self.assertEquals(self.src.push(self.buffer), gst.FLOW_OK)
gst.debug('pushed buffer on linked pad, no probe')
# one refcount is held by our scope, another is held on
# self.buffers through _chain_func
self.assertEquals(self.buffer.__grefcount__, 2)
self.assertEquals(len(self.buffers), 1)
self.buffers = None
self.assertEquals(self.buffer.__grefcount__, 1)
def testFalseProbe(self):
id = self.src.add_buffer_probe(self._probe_handler, False)
self.buffer = gst.Buffer()
self.assertEquals(self.buffer.__grefcount__, 1)
self.assertEquals(self.src.push(self.buffer), gst.FLOW_OK)
self.assertEquals(self.buffer.__grefcount__, 1)
self.src.remove_buffer_probe(id)
self.assertEquals(len(self.buffers), 0)
def testTrueProbe(self):
probe_id = self.src.add_buffer_probe(self._probe_handler, True)
self.buffer = gst.Buffer()
self.assertEquals(self.buffer.__grefcount__, 1)
self.assertEquals(self.src.push(self.buffer), gst.FLOW_OK)
# one refcount is held by our scope, another is held on
# self.buffers through _chain_func
self.assertEquals(self.buffer.__grefcount__, 2)
# they are not the same Python object ...
self.failIf(self.buffer is self.buffers[0])
self.failIf(id(self.buffer) == id(self.buffers[0]))
# ... but they wrap the same GstBuffer
self.failUnless(self.buffer == self.buffers[0])
self.assertEquals(repr(self.buffer), repr(self.buffers[0]))
self.src.remove_buffer_probe(probe_id)
self.assertEquals(len(self.buffers), 1)
self.buffers = None
self.assertEquals(self.buffer.__grefcount__, 1)
def _probe_handler(self, pad, buffer, ret):
return ret
# test for event probes with linked pads
class PadPushEventLinkedTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.src = gst.Pad("src", gst.PAD_SRC)
self.sink = gst.Pad("sink", gst.PAD_SINK)
caps = gst.caps_from_string("foo/bar")
self.src.set_caps(caps)
self.sink.set_caps(caps)
self.sink.set_chain_function(self._chain_func)
self.src.set_active(True)
self.sink.set_active(True)
self.src.link(self.sink)
self.events = []
def tearDown(self):
self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3)
self.assertEquals(self.src.__gstrefcount__, 1)
self.src.set_caps(None)
del self.src
self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3)
self.assertEquals(self.sink.__gstrefcount__, 1)
self.sink.set_caps(None)
del self.sink
TestCase.tearDown(self)
def _chain_func(self, pad, buffer):
gst.debug('got buffer %r, id %x, with GMO rc %d'% (
buffer, id(buffer), buffer.__grefcount__))
self.buffers.append(buffer)
return gst.FLOW_OK
def testNoProbe(self):
self.event = gst.event_new_eos()
gst.debug('created new eos %r, id %x' % (
self.event, id(self.event)))
self.assertEquals(self.event.__grefcount__, 1)
gst.debug('pushing event on linked pad, no probe')
self.assertEquals(self.src.push_event(self.event), True)
gst.debug('pushed event on linked pad, no probe')
# one refcount is held by our scope
self.assertEquals(self.event.__grefcount__, 1)
# the event has reffed the src pad as the src of the event
self.assertEquals(self.src.__grefcount__, 2)
# clear it
self.event = None
self.assertEquals(self.src.__grefcount__, 1)
def testFalseProbe(self):
probe_id = self.src.add_event_probe(self._probe_handler, False)
self.event = gst.event_new_eos()
gst.debug('created new eos %r, id %x' % (
self.event, id(self.event)))
self.assertEquals(self.event.__grefcount__, 1)
# a false probe return drops the event and returns False
self.assertEquals(self.src.push_event(self.event), False)
# one ref in our local scope, another in self.events
self.assertEquals(self.event.__grefcount__, 2)
self.assertEquals(self.sink.__grefcount__, 1)
# the event has reffed the src pad as the src of the event
self.assertEquals(self.src.__grefcount__, 2)
# remove the event from existence
self.event = None
self.events = None
self.assertEquals(self.src.__grefcount__, 1)
self.src.remove_buffer_probe(probe_id)
def testTrueProbe(self):
probe_id = self.src.add_event_probe(self._probe_handler, True)
self.event = gst.event_new_eos()
gst.debug('created new eos %r, id %x' % (
self.event, id(self.event)))
self.assertEquals(self.event.__grefcount__, 1)
# a True probe lets it pass
self.assertEquals(self.src.push_event(self.event), True)
# one refcount is held by our scope, another is held on
# self.events through _probe
self.assertEquals(self.event.__grefcount__, 2)
# they are not the same Python object ...
self.failIf(self.event is self.events[0])
self.failIf(id(self.event) == id(self.events[0]))
# ... but they wrap the same GstEvent
self.assertEquals(repr(self.event), repr(self.events[0]))
self.failUnless(self.event == self.events[0])
self.src.remove_buffer_probe(probe_id)
self.assertEquals(len(self.events), 1)
self.events = None
self.assertEquals(self.event.__grefcount__, 1)
# the event has reffed the src pad as the src of the event
self.assertEquals(self.src.__grefcount__, 2)
# clear it
self.event = None
self.assertEquals(self.src.__grefcount__, 1)
def _probe_handler(self, pad, event, ret):
gst.debug("probed, pad %r, event %r" % (pad, event))
self.events.append(event)
return ret
# a test to show that we can link a pad from the probe handler
class PadPushProbeLinkTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.src = gst.Pad("src", gst.PAD_SRC)
self.sink = gst.Pad("sink", gst.PAD_SINK)
caps = gst.caps_from_string("foo/bar")
self.src.set_caps(caps)
self.sink.set_caps(caps)
self.src.set_active(True)
self.sink.set_active(True)
self.sink.set_chain_function(self._chain_func)
self.buffers = []
def tearDown(self):
self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3)
self.assertEquals(self.src.__gstrefcount__, 1)
self.src.set_caps(None)
del self.src
self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3)
self.assertEquals(self.sink.__gstrefcount__, 1)
self.sink.set_caps(None)
del self.sink
TestCase.tearDown(self)
def _chain_func(self, pad, buffer):
self.buffers.append(buffer)
return gst.FLOW_OK
def testProbeLink(self):
id = self.src.add_buffer_probe(self._probe_handler)
self.buffer = gst.Buffer()
self.assertEquals(self.buffer.__grefcount__, 1)
gst.debug('pushing buffer on linked pad, no probe')
self.assertEquals(self.src.push(self.buffer), gst.FLOW_OK)
gst.debug('pushed buffer on linked pad, no probe')
# one refcount is held by our scope, another is held on
# self.buffers through _chain_func
self.assertEquals(self.buffer.__grefcount__, 2)
self.assertEquals(len(self.buffers), 1)
self.buffers = None
self.assertEquals(self.buffer.__grefcount__, 1)
def _probe_handler(self, pad, buffer):
self.src.link(self.sink)
return True
class PadTest(TestCase):
def testConstructor(self):
# first style uses gst_pad_new
gst.debug('creating pad with name src')
pad = gst.Pad("src", gst.PAD_SRC)
self.failUnless(pad)
self.assertEquals(sys.getrefcount(pad), pygobject_2_13 and 2 or 3)
self.assertEquals(pad.__gstrefcount__, 1)
gst.debug('creating pad with no name')
self.failUnless(gst.Pad(None, gst.PAD_SRC))
self.failUnless(gst.Pad(name=None, direction=gst.PAD_SRC))
self.failUnless(gst.Pad(direction=gst.PAD_SRC, name=None))
self.failUnless(gst.Pad(direction=gst.PAD_SRC, name="src"))
# second uses gst_pad_new_from_template
#template = gst.PadTemplate()
class PadPipelineTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.pipeline = gst.parse_launch('fakesrc name=source ! fakesink')
src = self.pipeline.get_by_name('source')
self.srcpad = src.get_pad('src')
def tearDown(self):
del self.pipeline
del self.srcpad
TestCase.tearDown(self)
# FIXME: now that GstQuery is a miniobject with various _new_ factory
# functions, we need to figure out a way to deal with them in python
# def testQuery(self):
# assert self.sink.query(gst.QUERY_TOTAL, gst.FORMAT_BYTES) == -1
# assert self.srcpad.query(gst.QUERY_POSITION, gst.FORMAT_BYTES) == 0
# assert self.srcpad.query(gst.QUERY_POSITION, gst.FORMAT_TIME) == 0
class PadProbePipeTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.pipeline = gst.Pipeline()
self.assertEquals(self.pipeline.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3)
self.fakesrc = gst.element_factory_make('fakesrc')
self.fakesink = gst.element_factory_make('fakesink')
self.assertEquals(self.fakesrc.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(self.fakesrc), pygobject_2_13 and 2 or 3)
self.pipeline.add(self.fakesrc, self.fakesink)
self.assertEquals(self.fakesrc.__gstrefcount__, 2) # added
self.assertEquals(sys.getrefcount(self.fakesrc), pygobject_2_13 and 2 or 3)
self.assertEquals(self.fakesink.__gstrefcount__, 2) # added
self.assertEquals(sys.getrefcount(self.fakesink), pygobject_2_13 and 2 or 3)
self.fakesrc.link(self.fakesink)
self.assertEquals(self.pipeline.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3)
self.assertEquals(self.fakesrc.__gstrefcount__, 2)
self.assertEquals(sys.getrefcount(self.fakesrc), pygobject_2_13 and 2 or 3)
self.assertEquals(self.fakesink.__gstrefcount__, 2)
self.assertEquals(sys.getrefcount(self.fakesink), pygobject_2_13 and 2 or 3)
def tearDown(self):
# Refcount must be either 1 or 2, to allow for a possibly still running
# state-recalculation thread
self.assertTrue (self.pipeline.__gstrefcount__ >= 1 and self.pipeline.__gstrefcount__ <= 2)
self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3)
self.assertEquals(self.fakesrc.__gstrefcount__, 2)
self.assertEquals(sys.getrefcount(self.fakesrc), pygobject_2_13 and 2 or 3)
gst.debug('deleting pipeline')
del self.pipeline
self.gccollect()
self.assertEquals(self.fakesrc.__gstrefcount__, 1) # parent gone
self.assertEquals(self.fakesink.__gstrefcount__, 1) # parent gone
self.assertEquals(sys.getrefcount(self.fakesrc), pygobject_2_13 and 2 or 3)
self.assertEquals(sys.getrefcount(self.fakesink), pygobject_2_13 and 2 or 3)
gst.debug('deleting fakesrc')
del self.fakesrc
self.gccollect()
gst.debug('deleting fakesink')
del self.fakesink
self.gccollect()
TestCase.tearDown(self)
def testFakeSrcProbeOnceKeep(self):
self.fakesrc.set_property('num-buffers', 1)
self.fakesink.set_property('signal-handoffs', True)
self.fakesink.connect('handoff', self._handoff_callback_fakesink)
pad = self.fakesrc.get_pad('src')
id = pad.add_buffer_probe(self._probe_callback_fakesrc)
self._got_fakesrc_buffer = 0
self._got_fakesink_buffer = 0
self.pipeline.set_state(gst.STATE_PLAYING)
while not self._got_fakesrc_buffer:
gst.debug('waiting for fakesrc buffer')
pass
while not self._got_fakesink_buffer:
gst.debug('waiting for fakesink buffer')
pass
gst.debug('got buffers from fakesrc and fakesink')
self.assertEquals(self._got_fakesink_buffer, 1)
pad.remove_buffer_probe(id)
self.pipeline.set_state(gst.STATE_NULL)
def testFakeSrcProbeMany(self):
self.fakesrc.set_property('num-buffers', 1000)
pad = self.fakesrc.get_pad('src')
id = pad.add_buffer_probe(self._probe_callback_fakesrc)
self._got_fakesrc_buffer = 0
self.pipeline.set_state(gst.STATE_PLAYING)
while not self._got_fakesrc_buffer == 1000:
import time
# allow for context switching; a busy loop here locks up the
# streaming thread too much
time.sleep(.0001)
pad.remove_buffer_probe(id)
self.pipeline.set_state(gst.STATE_NULL)
def _probe_callback_fakesrc(self, pad, buffer):
self.failUnless(isinstance(pad, gst.Pad))
self.failUnless(isinstance(buffer, gst.Buffer))
self._got_fakesrc_buffer += 1
gst.debug('fakesrc sent buffer %r, %d total sent' % (
buffer, self._got_fakesrc_buffer))
return True
def _handoff_callback_fakesink(self, sink, buffer, pad):
self.failUnless(isinstance(buffer, gst.Buffer))
self.failUnless(isinstance(pad, gst.Pad))
self._got_fakesink_buffer += 1
gst.debug('fakesink got buffer %r, %d total received' % (
buffer, self._got_fakesrc_buffer))
gst.debug('pad %r, py refcount %d, go rc %d, gst rc %d' % (
pad, sys.getrefcount(pad), pad.__grefcount__, pad.__gstrefcount__))
return True
def testRemovingProbe(self):
self.fakesrc.set_property('num-buffers', 10)
handle = None
self._num_times_called = 0
def buffer_probe(pad, buffer, data):
self._num_times_called += 1
pad.remove_buffer_probe(handle)
return True
pad = self.fakesrc.get_pad('src')
data = []
handle = pad.add_buffer_probe(buffer_probe, data)
self.pipeline.set_state(gst.STATE_PLAYING)
m = self.pipeline.get_bus().poll(gst.MESSAGE_EOS, -1)
assert m
assert self._num_times_called == 1
self.pipeline.set_state(gst.STATE_NULL)
assert sys.getrefcount(buffer_probe) == 2
assert sys.getrefcount(data) == 2
# FIXME: having m going out of scope doesn't seem to be enough
# to get it gc collected, and it keeps a ref to the pipeline.
# Look for a way to not have to do this explicitly
del m
self.gccollect()
class PadRefCountTest(TestCase):
def testAddPad(self):
# add a pad to an element
e = gst.element_factory_make('fakesrc')
self.assertEquals(sys.getrefcount(e), pygobject_2_13 and 2 or 3)
self.assertEquals(e.__gstrefcount__, 1)
gst.debug('creating pad with name mypad')
pad = gst.Pad("mypad", gst.PAD_SRC)
self.failUnless(pad)
self.assertEquals(sys.getrefcount(pad), pygobject_2_13 and 2 or 3)
self.assertEquals(pad.__gstrefcount__, 1)
gst.debug('adding pad to element')
e.add_pad(pad)
self.assertEquals(sys.getrefcount(e), pygobject_2_13 and 2 or 3)
self.assertEquals(e.__gstrefcount__, 1)
self.assertEquals(sys.getrefcount(pad), pygobject_2_13 and 2 or 3)
self.assertEquals(pad.__gstrefcount__, 2) # added to element
gst.debug('deleting element and collecting')
self.gccollect()
del e
if not pygobject_2_13:
# the element will be collected at 'del e' if we're using
# pygobject >= 2.13.0
self.assertEquals(self.gccollect(), 1) # collected the element
self.assertEquals(sys.getrefcount(pad), pygobject_2_13 and 2 or 3)
self.assertEquals(pad.__gstrefcount__, 1) # removed from element
gst.debug('deleting pad and collecting')
del pad
if not pygobject_2_13:
# the pad will be collected at 'del pad' if we're using
# pygobject >= 2.13.0
self.assertEquals(self.gccollect(), 1) # collected the pad
gst.debug('going into teardown')
class PadBlockTest(TestCase):
def testCallbackFlush(self):
# check that the same block callback can be called more than once (weird
# test but it was broken)
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)
for i in xrange(10):
buf = gst.Buffer('ciao')
pad.push(buf)
pad.push_event(gst.event_new_flush_stop())
def testCallbackRefcount(self):
def blocked_cb(pad, blocked):
pad.set_blocked_async(False, unblocked_cb)
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()
@@ -0,0 +1,63 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2008 Edward Hervey <edward.hervey@collabora.co.uk>
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gobject, gst, unittest, TestCase
class Descriptions(TestCase):
def testSourceDescription(self):
assert hasattr(gst.pbutils, 'get_source_description')
self.assertEquals(gst.pbutils.get_source_description("file"),
"FILE protocol source")
def testSinkDescription(self):
assert hasattr(gst.pbutils, 'get_sink_description')
self.assertEquals(gst.pbutils.get_sink_description("file"),
"FILE protocol sink")
def testDecoderDescription(self):
assert hasattr(gst.pbutils, 'get_decoder_description')
self.assertEquals(gst.pbutils.get_decoder_description(gst.caps_from_string("audio/mpeg,mpegversion=1,layer=3")),
'MPEG-1 Layer 3 (MP3) decoder')
def testCodecDescription(self):
assert hasattr(gst.pbutils, 'get_codec_description')
self.assertEquals(gst.pbutils.get_codec_description(gst.caps_from_string("audio/mpeg,mpegversion=1,layer=3")),
'MPEG-1 Layer 3 (MP3)')
def testEncoderDescription(self):
assert hasattr(gst.pbutils, 'get_encoder_description')
self.assertEquals(gst.pbutils.get_encoder_description(gst.caps_from_string("audio/mpeg,mpegversion=1,layer=3")),
'MPEG-1 Layer 3 (MP3) encoder')
def testElementDescription(self):
assert hasattr(gst.pbutils, 'get_element_description')
self.assertEquals(gst.pbutils.get_element_description("something"),
"GStreamer element something")
def testAddCodecDescription(self):
assert hasattr(gst.pbutils, 'add_codec_description_to_tag_list')
# TODO
# Add tests for the other parts of pbutils:
# * missing-plugins
# * install-plugins (and detect if there weren't compiled because of a version
# of plugins-base too low)
@@ -0,0 +1,250 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import time
from common import gst, unittest, TestCase, pygobject_2_13
import gobject
class TestConstruction(TestCase):
def setUp(self):
self.gctrack()
def tearDown(self):
self.gccollect()
self.gcverify()
def testGoodConstructor(self):
name = 'test-pipeline'
pipeline = gst.Pipeline(name)
self.assertEquals(pipeline.__gstrefcount__, 1)
assert pipeline is not None, 'pipeline is None'
self.failUnless(isinstance(pipeline, gst.Pipeline),
'pipeline is not a GstPipline')
assert pipeline.get_name() == name, 'pipelines name is wrong'
self.assertEquals(pipeline.__gstrefcount__, 1)
def testParseLaunch(self):
pipeline = gst.parse_launch('fakesrc ! fakesink')
class Pipeline(TestCase):
def setUp(self):
self.gctrack()
self.pipeline = gst.Pipeline('test-pipeline')
source = gst.element_factory_make('fakesrc', 'source')
source.set_property('num-buffers', 5)
sink = gst.element_factory_make('fakesink', 'sink')
self.pipeline.add(source, sink)
gst.element_link_many(source, sink)
def tearDown(self):
del self.pipeline
self.gccollect()
self.gcverify()
def testRun(self):
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 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')
self.assertEquals(pipeline.__gstrefcount__, 1)
bus = pipeline.get_bus()
self.assertEquals(pipeline.__gstrefcount__, 1)
# one for python and one for the pipeline
self.assertEquals(bus.__gstrefcount__, 2)
del pipeline
if not pygobject_2_13:
self.failUnless(self.gccollect())
self.assertEquals(bus.__gstrefcount__, 1)
class PipelineAndBus(TestCase):
def setUp(self):
TestCase.setUp(self)
self.pipeline = gst.Pipeline('test-pipeline')
source = gst.element_factory_make('fakesrc', 'source')
sink = gst.element_factory_make('fakesink', 'sink')
self.pipeline.add(source, sink)
gst.element_link_many(source, sink)
self.bus = self.pipeline.get_bus()
self.assertEquals(self.bus.__gstrefcount__, 2)
self.handler = self.bus.add_watch(self._message_received)
self.assertEquals(self.bus.__gstrefcount__, 3)
self.assertEquals(self.pipeline.__gstrefcount__, 1)
self.loop = gobject.MainLoop()
def tearDown(self):
# FIXME: fix the refcount issues with the bus/pipeline
# flush the bus to be able to assert on the pipeline refcount
#while self.pipeline.__gstrefcount__ > 1:
self.gccollect()
# one for the pipeline, two for the snake
# three for the watch now shake shake shake but don't you
self.assertEquals(self.bus.__gstrefcount__, 3)
self.failUnless(gobject.source_remove(self.handler))
self.assertEquals(self.bus.__gstrefcount__, 2)
self.gccollect()
gst.debug('THOMAS: pipeline rc %d' % self.pipeline.__gstrefcount__)
#self.assertEquals(self.pipeline.__gstrefcount__, 1)
del self.pipeline
self.gccollect()
#self.assertEquals(self.bus.__gstrefcount__, 2)
del self.bus
self.gccollect()
# the async thread can be holding a ref, Wim is going to work on this
#TestCase.tearDown(self)
def _message_received(self, bus, message):
gst.debug('received message: %s, %s' % (
message.src.get_path_string(), message.type.value_nicks[1]))
t = message.type
if t == gst.MESSAGE_STATE_CHANGED:
old, new, pen = message.parse_state_changed()
gst.debug('%r state change from %r to %r' % (
message.src.get_path_string(), old, new))
if message.src == self.pipeline and new == self.final:
self.loop.quit()
return True
def testPlaying(self):
self.final = gst.STATE_PLAYING
ret = self.pipeline.set_state(gst.STATE_PLAYING)
self.assertEquals(ret, gst.STATE_CHANGE_ASYNC)
# go into a main loop to wait for messages
self.loop.run()
# we go to READY so we get messages; going to NULL would set
# the bus flushing
self.final = gst.STATE_READY
ret = self.pipeline.set_state(gst.STATE_READY)
self.assertEquals(ret, gst.STATE_CHANGE_SUCCESS)
self.loop.run()
# FIXME: not setting to NULL causes a deadlock; we might want to
# fix this in the bindings
self.assertEquals(self.pipeline.set_state(gst.STATE_NULL),
gst.STATE_CHANGE_SUCCESS)
self.assertEquals(self.pipeline.get_state(),
(gst.STATE_CHANGE_SUCCESS, gst.STATE_NULL, gst.STATE_VOID_PENDING))
self.gccollect()
class TestPipeSub(gst.Pipeline):
def do_handle_message(self, message):
self.debug('do_handle_message')
gst.Pipeline.do_handle_message(self, message)
self.type = message.type
gobject.type_register(TestPipeSub)
class TestPipeSubSub(TestPipeSub):
def do_handle_message(self, message):
self.debug('do_handle_message')
TestPipeSub.do_handle_message(self, message)
gobject.type_register(TestPipeSubSub)
# see http://bugzilla.gnome.org/show_bug.cgi?id=577735
class TestSubClass(TestCase):
def setUp(self):
self.gctrack()
def tearDown(self):
self.gccollect()
self.gcverify()
def testSubClass(self):
p = TestPipeSub()
u = gst.element_factory_make('uridecodebin')
self.assertEquals(u.__grefcount__, 1)
self.failIf(getattr(p, 'type', None))
# adding uridecodebin triggers a clock-provide message;
# this message should be dropped, and thus not affect
# the refcount of u beyond the parenting.
p.add(u)
self.assertEquals(getattr(p, 'type', None), gst.MESSAGE_CLOCK_PROVIDE)
self.assertEquals(u.__grefcount__, 2)
del p
self.assertEquals(u.__grefcount__, 1)
def testSubSubClass(self):
# Edward is worried that a subclass of a subclass will screw up
# the refcounting wrt. GST_BUS_DROP
p = TestPipeSubSub()
u = gst.element_factory_make('uridecodebin')
self.assertEquals(u.__grefcount__, 1)
self.failIf(getattr(p, 'type', None))
p.add(u)
self.assertEquals(getattr(p, 'type', None), gst.MESSAGE_CLOCK_PROVIDE)
self.assertEquals(u.__grefcount__, 2)
del p
self.assertEquals(u.__grefcount__, 1)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,68 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import sys
import gc
from common import gst, unittest, TestCase
class RegistryTest(TestCase):
def setUp(self):
self.registry = gst.registry_get_default()
self.plugins = self.registry.get_plugin_list()
TestCase.setUp(self)
def testGetDefault(self):
assert(self.registry)
def testPluginList(self):
names = map(lambda p: p.get_name(), self.plugins)
self.failUnless('staticelements' in names)
def testGetPathList(self):
# FIXME: this returns an empty list; probably due to core;
# examine problem
paths = self.registry.get_path_list()
class RegistryFeatureTest(TestCase):
def setUp(self):
self.registry = gst.registry_get_default()
self.plugins = self.registry.get_plugin_list()
self.efeatures = self.registry.get_feature_list(gst.TYPE_ELEMENT_FACTORY)
self.tfeatures = self.registry.get_feature_list(gst.TYPE_TYPE_FIND_FACTORY)
self.ifeatures = self.registry.get_feature_list(gst.TYPE_INDEX_FACTORY)
TestCase.setUp(self)
def testFeatureList(self):
self.assertRaises(TypeError, self.registry.get_feature_list, "kaka")
elements = map(lambda f: f.get_name(), self.efeatures)
self.failUnless('fakesink' in elements)
typefinds = map(lambda f: f.get_name(), self.tfeatures)
indexers = map(lambda f: f.get_name(), self.ifeatures)
self.failUnless('memindex' in indexers)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,62 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2006 Edward Hervey <edward@fluendo.com>
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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)
# the update flag is deprecated, we cannot check for proper behaviour.
#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()
@@ -0,0 +1,123 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import sys
from common import gst, unittest, TestCase
class StructureTest(TestCase):
def setUp(self):
TestCase.setUp(self)
self.struct = gst.structure_from_string('video/x-raw-yuv,width=10,foo="bar",pixel-aspect-ratio=1/2,framerate=5/1,boolean=(boolean)true')
def testName(self):
assert self.struct.get_name() == 'video/x-raw-yuv'
self.struct.set_name('foobar')
assert self.struct.get_name() == 'foobar'
def testInt(self):
assert self.struct.has_key('width')
assert isinstance(self.struct['width'], int)
assert self.struct['width'] == 10, self.struct['width']
self.struct['width'] = 5
assert self.struct.has_key('width')
assert isinstance(self.struct['width'], int)
assert self.struct['width'] == 5, self.struct['width']
def testString(self):
assert self.struct.has_key('foo')
assert isinstance(self.struct['foo'], unicode)
assert self.struct['foo'] == 'bar', self.struct['foo']
self.struct['foo'] = 'baz'
assert self.struct.has_key('foo')
assert isinstance(self.struct['foo'], unicode)
assert self.struct['foo'] == 'baz', self.struct['foo']
def testBoolean(self):
assert self.struct.has_key('boolean')
assert isinstance(self.struct['boolean'], bool)
assert self.struct['boolean'] == True, self.struct['boolean']
self.struct['boolean'] = False
assert self.struct.has_key('boolean')
assert isinstance(self.struct['boolean'], bool)
assert self.struct['boolean'] == False, self.struct['boolean']
def testCreateInt(self):
self.struct['integer'] = 5
assert self.struct.has_key('integer')
assert isinstance(self.struct['integer'], int)
assert self.struct['integer'] == 5, self.struct['integer']
def testGstValue(self):
s = self.struct
s['fourcc'] = gst.Fourcc('XVID')
assert s['fourcc'].fourcc == 'XVID'
s['frac'] = gst.Fraction(3,4)
assert s['frac'].num == 3
assert s['frac'].denom == 4
s['fracrange'] = gst.FractionRange(gst.Fraction(0,1),
gst.Fraction(25,3))
assert s['fracrange'].low.num == 0
assert s['fracrange'].low.denom == 1
assert s['fracrange'].high.num == 25
assert s['fracrange'].high.denom == 3
s['intrange'] = gst.IntRange(5,21)
assert s['intrange'].low == 5
assert s['intrange'].high == 21
s['doublerange'] = gst.DoubleRange(6.,21.)
assert s['doublerange'].low == 6.
assert s['doublerange'].high == 21.
s['fixedlist'] = (4, 5, 6)
assert isinstance(s['fixedlist'], tuple)
assert s['fixedlist'] == (4, 5, 6)
s['list'] = [4, 5, 6]
assert isinstance(s['list'], list)
assert s['list'] == [4, 5, 6]
s['boolean'] = True
assert isinstance(s['boolean'], bool)
assert s['boolean'] == True
# finally, some recursive tests
s['rflist'] = ([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g'])
assert s['rflist'] == ([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g'])
s['rlist'] = [([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g']), 'h']
assert s['rlist'] == [([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g']), 'h']
def testStructureChange(self):
assert self.struct['framerate'] == gst.Fraction(5, 1)
self.struct['framerate'] = gst.Fraction(10, 1)
assert self.struct['framerate'] == gst.Fraction(10, 1)
self.struct['pixel-aspect-ratio'] = gst.Fraction(4, 2)
assert self.struct['pixel-aspect-ratio'].num == 2
assert self.struct['pixel-aspect-ratio'].denom == 1
def testKeys(self):
k = self.struct.keys()
self.failUnless(k)
self.assertEquals(len(k), 5)
self.failUnless("width" in k)
self.failUnless("foo" in k)
self.failUnless("framerate" in k)
self.failUnless("pixel-aspect-ratio" in k)
self.failUnless("boolean" in k)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,71 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2007 Johan Dahlin
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, TestCase
class TestTagList(TestCase):
def testContains(self):
taglist = gst.TagList()
self.failIf('key' in taglist)
taglist['key'] = 'value'
self.failUnless('key' in taglist)
def testLength(self):
taglist = gst.TagList()
self.assertEqual(len(taglist), 0)
taglist['key1'] = 'value'
taglist['key2'] = 'value'
self.assertEqual(len(taglist), 2)
def testKeys(self):
taglist = gst.TagList()
self.assertEqual(taglist.keys(), [])
taglist['key1'] = 'value'
taglist['key2'] = 'value'
keys = taglist.keys()
keys.sort()
self.assertEqual(keys, ['key1', 'key2'])
def testUnicode(self):
taglist = gst.TagList()
# normal ASCII text
taglist[gst.TAG_ARTIST] = 'Artist'
self.failUnless(isinstance(taglist[gst.TAG_ARTIST], unicode))
self.assertEquals(taglist[gst.TAG_ARTIST], u'Artist')
self.assertEquals(taglist[gst.TAG_ARTIST], 'Artist')
# normal ASCII text as unicode
taglist[gst.TAG_ARTIST] = u'Artist'
self.failUnless(isinstance(taglist[gst.TAG_ARTIST], unicode))
self.assertEquals(taglist[gst.TAG_ARTIST], u'Artist')
self.assertEquals(taglist[gst.TAG_ARTIST], 'Artist')
# real unicode
taglist[gst.TAG_ARTIST] = u'S\xc3\xadgur R\xc3\xb3s'
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'])
@@ -0,0 +1,65 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2008 Alessandro Decina
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, unittest, TestCase, pygobject_2_13
import sys
import time
class TypeFindTest(TestCase):
def testTypeFind(self):
def application_awesome_type_find(typefind, arg1, arg2):
self.failUnlessEqual(arg1, 'arg1')
self.failUnlessEqual(arg2, 'arg2')
data = typefind.peek(0, 5)
self.failUnless(data == '', 'peek out of length??')
data = typefind.peek(0, 0)
self.failUnless(data == '', '0 peek??')
data = typefind.peek(3, 1)
self.failUnless(data == 'M')
data = typefind.peek(0, 4)
self.failUnless(data == 'AWSM')
typefind.suggest(gst.TYPE_FIND_MAXIMUM,
gst.Caps('application/awesome'))
res = gst.type_find_register('application/awesome', gst.RANK_PRIMARY,
application_awesome_type_find, ['.twi'],
gst.Caps('application/awesome'), 'arg1', 'arg2')
self.failUnless(res, 'type_find_register failed')
factory = None
factories = gst.type_find_factory_get_list()
for typefind_factory in factories:
if typefind_factory.get_name() == 'application/awesome':
factory = typefind_factory
break
self.failUnless(factory is not None)
obj = gst.Pad('src', gst.PAD_SRC)
buffer = gst.Buffer('AWSM')
caps, probability = gst.type_find_helper_for_buffer(obj, buffer)
self.failUnlessEqual(str(caps), 'application/awesome')
self.failUnlessEqual(probability, gst.TYPE_FIND_MAXIMUM)
@@ -0,0 +1,53 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from common import gst, unittest, TestCase
class PadTest(TestCase):
def testQuery(self):
# don't run this test if we don't have the libxml2 module
try:
import libxml2
except:
return
xml = gst.XML()
xml.parse_memory("""<?xml version="1.0"?>
<gstreamer xmlns:gst="http://gstreamer.net/gst-core/1.0/">
<gst:element>
<gst:name>test-pipeline</gst:name>
<gst:type>pipeline</gst:type>
<gst:param>
<gst:name>name</gst:name>
<gst:value>test-pipeline</gst:value>
</gst:param>
</gst:element>
</gstreamer>""")
elements = xml.get_topelements()
assert len(elements) == 1
element = elements[0]
assert isinstance(element, gst.Pipeline)
assert element.get_name() == 'test-pipeline'
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,56 @@
#include "pygobject.h"
#include "test-object.h"
#include <gst/gst.h>
#include <glib-object.h>
static PyObject *
_wrap_get_object (PyObject * self)
{
GObject *obj;
obj = g_object_new (TEST_TYPE_OBJECT, NULL);
if (!obj) {
return NULL;
}
return pygobject_new (obj);
}
static PyObject *
_wrap_emit_event (PyObject * self, PyObject * args)
{
PyGObject *obj;
GstEventType event_type = GST_EVENT_UNKNOWN;
GstEvent *event;
if (!PyArg_ParseTuple (args, "O|i", &obj, &event_type))
return NULL;
event = gst_event_new_custom (event_type, NULL);
g_signal_emit_by_name (G_OBJECT (obj->obj), "event", event);
gst_mini_object_unref (GST_MINI_OBJECT (event));
Py_INCREF (Py_None);
return Py_None;
}
static PyMethodDef testhelper_methods[] = {
{"get_object", (PyCFunction) _wrap_get_object, METH_NOARGS},
{"emit_event", (PyCFunction) _wrap_emit_event, METH_VARARGS},
{NULL, NULL}
};
void
inittesthelper ()
{
PyObject *m, *d;
init_pygobject ();
gst_init (NULL, NULL);
m = Py_InitModule ("testhelper", testhelper_methods);
d = PyModule_GetDict (m);
}
@@ -0,0 +1,34 @@
import os
import sys
import imp
class GstOverrideImport:
def find_module(self, fullname, path=None):
if fullname in ('gi.overrides.Gst', 'gi.overrides._gi_gst'):
return self
return None
def load_module(self, name):
if name in sys.modules:
return sys.modules[name]
fp, pathname, description = imp.find_module(name.split('.')[-1], [
os.environ.get('GST_OVERRIDE_SRC_PATH'),
os.environ.get('GST_OVERRIDE_BUILD_PATH'),
])
try:
module = imp.load_module(name, fp, pathname, description)
finally:
if fp:
fp.close()
sys.modules[name] = module
return module
if sys.version_info.major >= 3:
sys.meta_path.insert(0, GstOverrideImport())
else:
import gi.overrides
gi.overrides.__path__.append(os.environ.get('GST_OVERRIDE_SRC_PATH'))
gi.overrides.__path__.append(os.environ.get('GST_OVERRIDE_BUILD_PATH'))
@@ -0,0 +1,526 @@
#
# This is a valgrind suppression file that should be used when using valgrind.
#
# Here's an example of running valgrind:
#
# cd python/dist/src
# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \
# ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network
#
# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER
# to use the preferred suppressions with Py_ADDRESS_IN_RANGE.
#
# If you do not want to recompile Python, you can uncomment
# suppressions for PyObject_Free and PyObject_Realloc.
#
# See Misc/README.valgrind for more information.
# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif
{
ADDRESS_IN_RANGE/Invalid read of size 4
Memcheck:Addr4
fun:Py_ADDRESS_IN_RANGE
}
{
ADDRESS_IN_RANGE/Invalid read of size 4
Memcheck:Value4
fun:Py_ADDRESS_IN_RANGE
}
{
ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64)
Memcheck:Value8
fun:Py_ADDRESS_IN_RANGE
}
{
ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
Memcheck:Cond
fun:Py_ADDRESS_IN_RANGE
}
{
ADDRESS_IN_RANGE/Invalid read of size 4
Memcheck:Addr4
fun:PyObject_Free
}
{
ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64)
Memcheck:Addr8
fun:PyObject_Free
}
{
ADDRESS_IN_RANGE/Invalid read of size 4
Memcheck:Value4
fun:PyObject_Free
}
{
ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64)
Memcheck:Value8
fun:PyObject_Free
}
{
ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
Memcheck:Cond
fun:PyObject_Free
}
{
ADDRESS_IN_RANGE/Invalid read of size 4
Memcheck:Addr4
fun:PyObject_Realloc
}
{
ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64)
Memcheck:Addr8
fun:PyObject_Realloc
}
{
ADDRESS_IN_RANGE/Invalid read of size 4
Memcheck:Value4
fun:PyObject_Realloc
}
{
ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64)
Memcheck:Value8
fun:PyObject_Realloc
}
{
ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
Memcheck:Cond
fun:PyObject_Realloc
}
###
### All the suppressions below are for errors that occur within libraries
### that Python uses. The problems to not appear to be related to Python's
### use of the libraries.
###
{
GDBM problems, see test_gdbm
Memcheck:Param
write(buf)
fun:write
fun:gdbm_open
}
{
Avoid problem in libc on gentoo
Memcheck:Cond
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
}
{
Avoid problem in glibc on gentoo
Memcheck:Addr8
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/libc-2.3.4.so
obj:/lib/ld-2.3.4.so
fun:_dl_open
obj:/lib/libdl-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/libdl-2.3.4.so
fun:dlopen
}
{
Avoid problem in glibc on gentoo
Memcheck:Addr8
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/libc-2.3.4.so
obj:/lib/ld-2.3.4.so
fun:_dl_open
obj:/lib/libdl-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/libdl-2.3.4.so
fun:dlopen
}
{
Avoid problem in glibc on gentoo
Memcheck:Cond
obj:/lib/ld-2.3.4.so
obj:/lib/libc-2.3.4.so
obj:/lib/ld-2.3.4.so
fun:_dl_open
obj:/lib/libdl-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/libdl-2.3.4.so
fun:dlopen
}
{
Avoid problem in glibc on gentoo
Memcheck:Cond
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/libc-2.3.4.so
obj:/lib/ld-2.3.4.so
fun:_dl_open
obj:/lib/libdl-2.3.4.so
obj:/lib/ld-2.3.4.so
obj:/lib/libdl-2.3.4.so
fun:dlopen
}
{
Avoid problems w/readline doing a putenv and leaking on exit
Memcheck:Leak
fun:malloc
fun:xmalloc
fun:sh_set_lines_and_columns
fun:_rl_get_screen_size
fun:_rl_init_terminal_io
obj:/lib/libreadline.so.4.3
fun:rl_initialize
fun:setup_readline
fun:initreadline
fun:_PyImport_LoadDynamicModule
fun:load_module
fun:import_submodule
fun:load_next
fun:import_module_ex
fun:PyImport_ImportModuleEx
}
{
Mysterious leak that seems to deal w/pthreads
Memcheck:Leak
fun:calloc
obj:/lib/ld-2.3.4.so
obj:/lib/ld-2.3.4.so
fun:_dl_allocate_tls
fun:__pthread_initialize_minimal
}
{
Mysterious leak that seems to deal w/pthreads
Memcheck:Leak
fun:memalign
obj:/lib/ld-2.3.4.so
fun:_dl_allocate_tls
fun:__pthread_initialize_minimal
}
###
### These occur from somewhere within the SSL, when running
### test_socket_sll. They are too general to leave on by default.
###
###{
### somewhere in SSL stuff
### Memcheck:Cond
### fun:memset
###}
###{
### somewhere in SSL stuff
### Memcheck:Value4
### fun:memset
###}
###
###{
### somewhere in SSL stuff
### Memcheck:Cond
### fun:MD5_Update
###}
###
###{
### somewhere in SSL stuff
### Memcheck:Value4
### fun:MD5_Update
###}
#
# All of these problems come from using test_socket_ssl
#
{
from test_socket_ssl
Memcheck:Cond
fun:BN_bin2bn
}
{
from test_socket_ssl
Memcheck:Cond
fun:BN_num_bits_word
}
{
from test_socket_ssl
Memcheck:Value4
fun:BN_num_bits_word
}
{
from test_socket_ssl
Memcheck:Cond
fun:BN_mod_exp_mont_word
}
{
from test_socket_ssl
Memcheck:Cond
fun:BN_mod_exp_mont
}
{
from test_socket_ssl
Memcheck:Param
write(buf)
fun:write
obj:/usr/lib/libcrypto.so.0.9.7
}
{
from test_socket_ssl
Memcheck:Cond
fun:RSA_verify
}
{
from test_socket_ssl
Memcheck:Value4
fun:RSA_verify
}
{
from test_socket_ssl
Memcheck:Value4
fun:DES_set_key_unchecked
}
{
from test_socket_ssl
Memcheck:Value4
fun:DES_encrypt2
}
{
from test_socket_ssl
Memcheck:Cond
obj:/usr/lib/libssl.so.0.9.7
}
{
from test_socket_ssl
Memcheck:Value4
obj:/usr/lib/libssl.so.0.9.7
}
{
from test_socket_ssl
Memcheck:Cond
fun:BUF_MEM_grow_clean
}
{
from test_socket_ssl
Memcheck:Cond
fun:memcpy
fun:ssl3_read_bytes
}
{
from test_socket_ssl
Memcheck:Cond
fun:SHA1_Update
}
{
from test_socket_ssl
Memcheck:Value4
fun:SHA1_Update
}
# python init memleak
{
Py_Main memleak
Memcheck:Leak
fun:malloc
fun:PyObject_Malloc
fun:_PyObject_GC_Malloc
fun:_PyObject_GC_*
fun:*
fun:*
fun:*
fun:*
fun:Py_InitializeEx
}
{
Py_Main memleak
Memcheck:Leak
fun:malloc
fun:PyObject_Malloc
fun:_PyObject_GC_Malloc
fun:_PyObject_GC_*
fun:*
fun:*
fun:*
fun:*
fun:*
fun:*
fun:*
fun:Py_InitializeEx
}
{
Py_Main memleak v2
Memcheck:Leak
fun:malloc
fun:_PyObject_GC_Malloc
fun:_PyObject_GC_New
fun:*
fun:*
fun:*
fun:*
fun:*
fun:Py_InitializeEx
}
{
Read compiled module memleak
Memcheck:Leak
fun:malloc
fun:PyObject_Malloc
fun:_PyObject_GC_Malloc
fun:_PyObject_GC_NewVar
fun:*
fun:*
fun:*
fun:*
fun:*
fun:*
fun:*
fun:read_compiled_module
}
{
PyRun_SimpleFileExFlags memleak
Memcheck:Leak
fun:malloc
fun:_PyObject_GC_Malloc
fun:_PyObject_GC_New*
fun:*
fun:*
fun:*
fun:PyRun_SimpleFileExFlags
}
# memleak in update_keyword_args
{
update_keyword_args
Memcheck:Leak
fun:malloc
fun:_PyObject_GC_Malloc
fun:*
fun:*
fun:update_keyword_args
}
# memleaks/conds in import_submodule
{
memleak in import_submodule
Memcheck:Cond
fun:strcpy
fun:find_module
}
{
wrong jump in import_submodule
Memcheck:Cond
fun:find_module
fun:import_submodule
}
{
wrong jump in import_submodule
Memcheck:Cond
fun:find_module
fun:load_package
fun:load_module
fun:import_submodule
}
{
Use of uninitialised value of size 4
Memcheck:Value4
fun:strcpy
fun:find_module
}
## KNOWN MEMORY LEAK in gst_element_state_get_name
## See gstreamer/gst/gstutils.c
{
Known leak in gst_element_state_get_name
Memcheck:Leak
fun:*
fun:*
fun:*
fun:*
fun:g_strdup_printf
fun:gst_element_state_get_name
}
## Suppressions for FC5 64bit
{
Wrong jump in PyImport_ImportModuleEx
Memcheck:Cond
fun:__strcpy_chk
obj:/usr/lib64/libpython2.4.so.1.0
obj:/usr/lib64/libpython2.4.so.1.0
obj:/usr/lib64/libpython2.4.so.1.0
fun:PyImport_ImportModuleEx
}
{
Wrong jump in PyImport_ImportModuleEx
Memcheck:Cond
fun:__strcpy_chk
fun:PyImport_ImportModuleEx
}
{
Wrong jump in PyImport_ImportModuleEx
Memcheck:Cond
fun:__strcpy_chk
obj:/usr/lib64/libpython2.4.so.1.0
obj:/usr/lib64/libpython2.4.so.1.0
fun:PyObject_Call
fun:PyObject_CallFunction
obj:/usr/lib64/libpython2.4.so.1.0
obj:/usr/lib64/libpython2.4.so.1.0
obj:/usr/lib64/libpython2.4.so.1.0
fun:PyImport_ImportModuleEx
}
{
Wrong jump in PyUnicode_Decode
Memcheck:Cond
fun:PyUnicode_Decode
}
@@ -0,0 +1,46 @@
#!/usr/bin/env python
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
# identity.py
# 2016 Marianna S. Buschle <msb@qtec.com>
#
# Simple identity element in python
#
# You can run the example from the source doing from gst-python/:
#
# $ export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:$PWD/plugin:$PWD/examples/plugins
# $ GST_DEBUG=python:4 gst-launch-1.0 fakesrc num-buffers=10 ! identity_py ! fakesink
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstBase', '1.0')
from gi.repository import Gst, GObject, GstBase
Gst.init(None)
#
# Simple Identity element created entirely in python
#
class Identity(GstBase.BaseTransform):
__gstmetadata__ = ('Identity Python','Transform', \
'Simple identity element written in python', 'Marianna S. Buschle')
__gsttemplates__ = (Gst.PadTemplate.new("src",
Gst.PadDirection.SRC,
Gst.PadPresence.ALWAYS,
Gst.Caps.new_any()),
Gst.PadTemplate.new("sink",
Gst.PadDirection.SINK,
Gst.PadPresence.ALWAYS,
Gst.Caps.new_any()))
def __init__(self):
self.transformed = False
def do_transform_ip(self, buffer):
self.transformed = True
return Gst.FlowReturn.OK
GObject.type_register(Identity)
__gstelementfactory__ = ("test_identity_py", Gst.Rank.NONE, Identity)
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2002 David I. Lehn
# Copyright (C) 2004 Johan Dahlin
# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import os
import sys
import unittest
def _testcases(filenames):
"""Yield testcases out of filenames."""
for filename in filenames:
if filename.endswith(".py"):
yield filename[:-3]
def _tests_suite():
"""Pick which tests to run."""
testcase = os.getenv("TESTCASE")
if testcase:
testcases = [testcase]
else:
testcases = _testcases(sys.argv[1:])
loader = unittest.TestLoader()
return loader.loadTestsFromNames(testcases)
def setup():
return
if __name__ == "__main__":
setup()
# Set verbosity.
descriptions = 1
verbosity = 1
if 'VERBOSE' in os.environ:
descriptions = 2
verbosity = 2
suite = _tests_suite()
if not list(suite):
raise Exception("No tests found")
# Run the tests.
testRunner = unittest.TextTestRunner(descriptions=descriptions,
verbosity=verbosity)
result = testRunner.run(suite)
if result.failures or result.errors:
sys.exit(1)
@@ -0,0 +1,116 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# Copyright (C) 2009 Thomas Vander Stichele
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import sys
import overrides_hack
overrides_hack
from common import TestCase, unittest
from gi.repository import Gst
class TimeArgsTest(TestCase):
def testNoneTime(self):
self.assertRaises(TypeError, Gst.TIME_ARGS, None)
def testStringTime(self):
self.assertRaises(TypeError, Gst.TIME_ARGS, "String")
def testClockTimeNone(self):
self.assertEquals(Gst.TIME_ARGS(Gst.CLOCK_TIME_NONE), 'CLOCK_TIME_NONE')
def testOneSecond(self):
self.assertEquals(Gst.TIME_ARGS(Gst.SECOND), '0:00:01.000000000')
class TestNotInitialized(TestCase):
def testNotInitialized(self):
if sys.version_info >= (3, 0):
assert_type = Gst.NotInitialized
else:
assert_type = TypeError
with self.assertRaises(assert_type):
Gst.Caps.from_string("audio/x-raw")
with self.assertRaises(assert_type):
Gst.Structure.from_string("audio/x-raw")
with self.assertRaises(assert_type):
Gst.ElementFactory.make("identity", None)
def testNotDeinitialized(self):
Gst.init(None)
assert(Gst.Caps.from_string("audio/x-raw"))
assert(Gst.Structure.from_string("audio/x-raw"))
assert(Gst.ElementFactory.make("identity", None))
Gst.deinit()
if sys.version_info >= (3, 0):
assert_type = Gst.NotInitialized
else:
assert_type = TypeError
with self.assertRaises(assert_type):
Gst.Caps.from_string("audio/x-raw")
with self.assertRaises(assert_type):
Gst.Structure.from_string("audio/x-raw")
with self.assertRaises(assert_type):
Gst.ElementFactory.make("identity", None)
class TestStructure(TestCase):
def test_new(self):
Gst.init(None)
test = Gst.Structure('test', test=1)
self.assertEqual(test['test'], 1)
test = Gst.Structure('test,test=1')
self.assertEqual(test['test'], 1)
class TestBin(TestCase):
def test_add_pad(self):
Gst.init(None)
self.assertEqual(Gst.ElementFactory.make("bin", None).sinkpads, [])
class TestBufferMap(TestCase):
def test_map_unmap_manual(self):
Gst.init(None)
buf = Gst.Buffer.new_wrapped([42])
info = buf.map(Gst.MapFlags.READ | Gst.MapFlags.WRITE)
self.assertEqual(info.data[0], 42)
buf.unmap(info)
with self.assertRaises(ValueError):
info.data[0]
def test_map_unmap_context(self):
Gst.init(None)
buf = Gst.Buffer.new_wrapped([42])
with buf.map(Gst.MapFlags.READ | Gst.MapFlags.WRITE) as info:
self.assertEqual(info.data[0], 42)
with self.assertRaises(ValueError):
info.data[0]
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,42 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2007 Johan Dahlin
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import overrides_hack
overrides_hack
from common import TestCase, unittest
import gi
gi.require_version("Gst", "1.0")
from gi.repository import Gst
class TestPlugin(TestCase):
def testLoad(self):
Gst.init(None)
p = Gst.parse_launch ("fakesrc ! test_identity_py name=id ! fakesink")
assert p.get_by_name("id").transformed == False
p.set_state(Gst.State.PLAYING)
p.get_state(Gst.CLOCK_TIME_NONE)
p.set_state(Gst.State.NULL)
assert p.get_by_name("id").transformed == True
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,402 @@
# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4
#
# gst-python - Python bindings for GStreamer
# Copyright (C) 2007 Johan Dahlin
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import overrides_hack
overrides_hack
from common import TestCase
import unittest, sys
import gi
gi.require_version("Gst", "1.0")
from gi.repository import Gst
Gst.init(None)
Gst.DoubleRange = Gst.DoubleRange
class TestDoubleRange(TestCase):
def testConstructor(self):
Gst.init(None)
Gst.DoubleRange = Gst.DoubleRange(1.2, 3.4)
self.assertEqual(r.start, 1.2)
self.assertEqual(r.stop, 3.4)
self.assertRaises(TypeError, Gst.DoubleRange, {}, 2)
self.assertRaises(TypeError, Gst.DoubleRange, 2, ())
self.assertRaises(TypeError, Gst.DoubleRange, 2, 1)
self.assertRaises(TypeError, Gst.DoubleRange)
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.DoubleRange(1,2)), '<Gst.DoubleRange [1.0,2.0]>')
def testGetValue(self):
Gst.init(None)
st = Gst.Structure.new_empty("video/x-raw")
st["range"] = Gst.DoubleRange(1,2)
value = st["range"]
self.assertEqual(value.start, 1.0)
self.assertEqual(value.stop, 2.0)
class TestFraction(TestCase):
def testConstructor(self):
Gst.init(None)
frac = Gst.Fraction(1, 2)
self.assertEqual(frac.num, 1)
self.assertEqual(frac.denom, 2)
frac = Gst.Fraction(1)
self.assertEqual(frac.num, 1)
self.assertEqual(frac.denom, 1)
self.assertRaises(TypeError, Gst.Fraction)
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.Fraction(1, 2)), '<Gst.Fraction 1/2>')
def testEqNe(self):
Gst.init(None)
frac = Gst.Fraction(1, 2)
self.assertEqual(frac, frac)
self.assertEqual(Gst.Fraction(1, 2), Gst.Fraction(1, 2))
self.assertEqual(Gst.Fraction(2, 4), Gst.Fraction(1, 2))
self.assertNotEqual(Gst.Fraction(1, 3), Gst.Fraction(1, 2))
self.assertNotEqual(Gst.Fraction(2, 1), Gst.Fraction(1, 2))
def testMul(self):
Gst.init(None)
self.assertEqual(Gst.Fraction(1, 2) * Gst.Fraction(1, 2), Gst.Fraction(1, 4))
self.assertEqual(Gst.Fraction(2, 3) * Gst.Fraction(4, 5), Gst.Fraction(8, 15))
self.assertEqual(Gst.Fraction(1, 3) * Gst.Fraction(4), Gst.Fraction(4, 3))
self.assertEqual(Gst.Fraction(1, 3) * 4, Gst.Fraction(4, 3))
def testRMul(self):
Gst.init(None)
self.assertEqual(2 * Gst.Fraction(1, 2), Gst.Fraction(1))
self.assertEqual(4 * Gst.Fraction(1, 2), Gst.Fraction(2))
self.assertEqual(-10 * Gst.Fraction(1, 2), Gst.Fraction(-5))
def testDiv(self):
Gst.init(None)
self.assertEqual(Gst.Fraction(1, 3) / Gst.Fraction(1, 4), Gst.Fraction(4, 3))
self.assertEqual(Gst.Fraction(2, 3) / Gst.Fraction(4, 5), Gst.Fraction(10, 12))
self.assertEqual(Gst.Fraction(1, 3) / Gst.Fraction(4), Gst.Fraction(1, 12))
self.assertEqual(Gst.Fraction(1, 3) / 4, Gst.Fraction(1, 12))
self.assertEqual(Gst.Fraction(1, 3) / 2, Gst.Fraction(1, 6))
self.assertEqual(Gst.Fraction(1, 5) / -4, Gst.Fraction(1, -20))
def testRDiv(self):
Gst.init(None)
self.assertEqual(2 / Gst.Fraction(1, 3), Gst.Fraction(6, 1))
self.assertEqual(-4 / Gst.Fraction(1, 5), Gst.Fraction(-20, 1))
def testFloat(self):
Gst.init(None)
self.assertEqual(float(Gst.Fraction(1, 2)), 0.5)
def testPropertyMarshalling(self):
Gst.init(None)
obj = Gst.ElementFactory.make("rawvideoparse")
if not obj:
obj = Gst.ElementFactory.make("rawvideoparse")
if not obj:
# no (raw)videoparse and I don't know of any elements in core or -base using
# fraction properties. Skip this test.
return
value = obj.props.framerate
self.assertEqual(value.num, 25)
self.assertEqual(value.denom, 1)
obj.props.framerate = Gst.Fraction(2, 1)
value = obj.props.framerate
self.assertEqual(value.num, 2)
self.assertEqual(value.denom, 1)
def bad():
obj.props.framerate = 1
self.assertRaises(TypeError, bad)
value = obj.props.framerate
self.assertEqual(value.num, 2)
self.assertEqual(value.denom, 1)
def testGetFractionValue(self):
Gst.init(None)
st = Gst.Structure.from_string("video/x-raw,framerate=10/1")[0]
value = st["framerate"]
self.assertEqual(value.num, 10)
self.assertEqual(value.denom, 1)
class TestFractionRange(TestCase):
def testConstructor(self):
Gst.init(None)
r = Gst.FractionRange(Gst.Fraction(1, 30), Gst.Fraction(1, 2))
self.assertEqual(r.start, Gst.Fraction(1, 30))
self.assertEqual(r.stop, Gst.Fraction(1, 2))
self.assertRaises(TypeError, Gst.FractionRange, Gst.Fraction(1, 2), Gst.Fraction(1, 30))
self.assertRaises(TypeError, Gst.FractionRange, 2, Gst.Fraction(1, 2))
self.assertRaises(TypeError, Gst.FractionRange, Gst.Fraction(1, 2), 2)
self.assertRaises(TypeError, Gst.FractionRange)
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.FractionRange(Gst.Fraction(1,30), Gst.Fraction(1,2))),
'<Gst.FractionRange [1/30,1/2]>')
def testGetValue(self):
Gst.init(None)
st = Gst.Structure.new_empty("video/x-raw")
st["range"] = Gst.FractionRange(Gst.Fraction(1, 30), Gst.Fraction(1, 2))
value = st["range"]
self.assertEqual(value.start, Gst.Fraction(1, 30))
self.assertEqual(value.stop, Gst.Fraction(1, 2))
class TestDoubleRange(TestCase):
def testConstructor(self):
Gst.init(None)
r = Gst.DoubleRange(1.2, 3.4)
self.assertEqual(r.start, 1.2)
self.assertEqual(r.stop, 3.4)
self.assertRaises(TypeError, Gst.DoubleRange, {}, 2)
self.assertRaises(TypeError, Gst.DoubleRange, 2, ())
self.assertRaises(TypeError, Gst.DoubleRange, 2, 1)
self.assertRaises(TypeError, Gst.DoubleRange)
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.DoubleRange(1,2)), '<Gst.DoubleRange [1.0,2.0]>')
def testGetValue(self):
Gst.init(None)
st = Gst.Structure.new_empty("video/x-raw")
st["range"] = Gst.DoubleRange(1,2)
value = st["range"]
self.assertEqual(value.start, 1.0)
self.assertEqual(value.stop, 2.0)
class TestInt64Range(TestCase):
@unittest.skipUnless(sys.version_info >= (3, 0), "requires Python 3")
def testConstructor(self):
Gst.init(None)
r = Gst.Int64Range(range(0, 10, 2))
self.assertEqual(r.range, range(0, 10, 2))
self.assertRaises(TypeError, Gst.Int64Range, range(1, 10, 2))
self.assertRaises(TypeError, Gst.Int64Range, range(0, 9, 2))
self.assertRaises(TypeError, Gst.Int64Range, range(10, 0))
self.assertRaises(TypeError, Gst.Int64Range, 1)
self.assertRaises(TypeError, Gst.Int64Range)
@unittest.skipUnless(sys.version_info >= (3, 0), "requires Python 3")
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.Int64Range(range(0, 10, 2))), '<Gst.Int64Range [0,10,2]>')
@unittest.skipUnless(sys.version_info >= (3, 0), "requires Python 3")
def testGetValue(self):
Gst.init(None)
st = Gst.Structure.new_empty("video/x-raw")
st["range"] = Gst.Int64Range(range(0, 10, 2))
value = st["range"]
self.assertEqual(value, range(0, 10, 2))
class TestValueArray(TestCase):
def testConstructor(self):
Gst.init(None)
a = Gst.ValueArray((1,2,3))
self.assertEqual(a.array, [1,2,3])
self.assertRaises(TypeError, Gst.ValueArray, 1)
self.assertRaises(TypeError, Gst.ValueArray)
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.ValueArray([1,2,3])), '<Gst.ValueArray <1,2,3>>')
def testPropertyMarshalling(self):
Gst.init(None)
obj = Gst.ElementFactory.make("rawvideoparse")
if not obj:
# no rawvideoparse and I don't know of any elements in core or -base using
# fraction properties. Skip this test.
return
value = obj.props.plane_strides
self.assertEqual(value[0], 320)
self.assertEqual(value[1], 160)
self.assertEqual(value[2], 160)
obj.props.plane_strides = Gst.ValueArray([640,320,320])
value = obj.props.plane_strides
self.assertEqual(value[0], 640)
self.assertEqual(value[1], 320)
self.assertEqual(value[2], 320)
def bad():
obj.props.plane_strides = 1
self.assertRaises(TypeError, bad)
value = obj.props.plane_strides
self.assertEqual(value[0], 640)
self.assertEqual(value[1], 320)
self.assertEqual(value[2], 320)
def testGetValue(self):
Gst.init(None)
st = Gst.Structure.new_empty("video/x-raw")
st["array"] = Gst.ValueArray([Gst.Fraction(1, 30), Gst.Fraction(1, 2)])
value = st["array"]
st["array"] = Gst.ValueArray(value)
self.assertEqual(value[0], Gst.Fraction(1, 30))
self.assertEqual(value[1], Gst.Fraction(1, 2))
st["matrix"] = Gst.ValueArray([Gst.ValueArray([0, 1]), Gst.ValueArray([-1, 0])])
value = st["matrix"]
self.assertEqual(value[0][0], 0)
self.assertEqual(value[0][1], 1)
self.assertEqual(value[1][0], -1)
self.assertEqual(value[1][1], 0)
class TestValueList(TestCase):
def testConstructor(self):
Gst.init(None)
a = Gst.ValueList((1,2,3))
self.assertEqual(a.array, [1,2,3])
self.assertRaises(TypeError, Gst.ValueList, 1)
self.assertRaises(TypeError, Gst.ValueList)
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.ValueList([1,2,3])), '<Gst.ValueList {1,2,3}>')
def testGetValue(self):
Gst.init(None)
st = Gst.Structure.new_empty("video/x-raw")
st["framerate"] = Gst.ValueList([Gst.Fraction(1, 30), Gst.Fraction(1, 2)])
value = st["framerate"]
self.assertEqual(value[0], Gst.Fraction(1, 30))
self.assertEqual(value[1], Gst.Fraction(1, 2))
st["matrix"] = Gst.ValueList([Gst.ValueList([0, 1]), Gst.ValueList([-1 ,0])])
value = st["matrix"]
self.assertEqual(value[0][0], 0)
self.assertEqual(value[0][1], 1)
self.assertEqual(value[1][0], -1)
self.assertEqual(value[1][1], 0)
class TestIntRange(TestCase):
@unittest.skipUnless(sys.version_info >= (3, 0), "requires Python 3")
def testConstructor(self):
Gst.init(None)
r = Gst.IntRange(range(0, 10, 2))
self.assertEqual(r.range, range(0, 10, 2))
self.assertRaises(TypeError, Gst.IntRange, range(1, 10, 2))
self.assertRaises(TypeError, Gst.IntRange, range(0, 9, 2))
self.assertRaises(TypeError, Gst.IntRange, range(10, 0))
self.assertRaises(TypeError, Gst.IntRange, 1)
self.assertRaises(TypeError, Gst.IntRange)
@unittest.skipUnless(sys.version_info >= (3, 0), "requires Python 3")
def testRepr(self):
Gst.init(None)
self.assertEqual(repr(Gst.IntRange(range(0, 10, 2))), '<Gst.IntRange [0,10,2]>')
@unittest.skipUnless(sys.version_info >= (3, 0), "requires Python 3")
def testGetValue(self):
Gst.init(None)
st = Gst.Structure.new_empty("video/x-raw")
st["range"] = Gst.IntRange(range(0, 10, 2))
value = st["range"]
self.assertEqual(value, range(0, 10, 2))
class TestBitmask(TestCase):
def testConstructor(self):
Gst.init(None)
r = Gst.Bitmask(1 << 5)
self.assertEqual(r, 1 << 5)
def testGetValue(self):
Gst.init(None)
self.assertEqual(Gst.Structure('test,test=(bitmask)0x20')['test'], 1 << 5)
def testStr(self):
Gst.init(None)
r = Gst.Bitmask(1 << 5)
if sys.version_info >= (3, 0):
self.assertEqual(str(r), '0x20')
else:
self.assertEqual(str(r), '0x20L')