Update
This commit is contained in:
@@ -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')
|
||||
Reference in New Issue
Block a user