mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
Backport from 0.8 branch and added new .defs file from GStreamer 0.9
Original commit message from CVS: Backport from 0.8 branch and added new .defs file from GStreamer 0.9
This commit is contained in:
parent
f2997e137d
commit
c68afb5f53
35 changed files with 5033 additions and 2786 deletions
347
ChangeLog
347
ChangeLog
|
@ -1,3 +1,350 @@
|
|||
2005-06-17 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* Backport of bugfixes/new features from 0.8 branch to HEAD
|
||||
|
||||
* gst/gst.defs:
|
||||
* gst/gst-types.defs:
|
||||
New defs files generated from 0.9 GStreamer
|
||||
|
||||
PORTING-TODO will follow
|
||||
|
||||
2005-06-17 Andy Wingo <wingo@pobox.com>
|
||||
|
||||
* gst/gstcaps.override (_wrap_gst_caps_tp_richcompare): Increment
|
||||
the refcount of the return value in all cases, even for Py_True
|
||||
and Py_False. Lines of code per day hovering around 1.3.
|
||||
|
||||
2005-06-14 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* gst/gstcaps.override: (_wrap_gst_caps_tp_str):
|
||||
reverting previous fix, was incorrect
|
||||
|
||||
* configure.ac:
|
||||
0.8.1.2 pre-release
|
||||
|
||||
* gst/gst.override: (probe_handler_marshal):
|
||||
bye bye probe memleak
|
||||
|
||||
2005-06-14 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* gst/Makefile.am: (defs_DATA) (GST_OVERRIDES):
|
||||
* gst/gst.defs:
|
||||
* gst/gst.override:
|
||||
* gst/gst-extrafuncs.defs:
|
||||
* gst/gstbuffer.override:
|
||||
* gst/gstevent.override:
|
||||
* gst/gst-types.defs: (Buffer) (Event):
|
||||
Added support for element flags (list, set, unset)
|
||||
Added gst.Buffer duration field
|
||||
Added gst.Event fields
|
||||
|
||||
2005-06-14 Andy Wingo <wingo@pobox.com>
|
||||
|
||||
* gst/gstcaps.override (_wrap_gst_caps_tp_richcompare): Fixes for
|
||||
== and != when the second arg is not a caps.
|
||||
|
||||
* testsuite/test_caps.py (CapsTest.testComparisons): Fix name.
|
||||
|
||||
2005-06-14 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* gst/gstcaps.override: (_wrap_gst_caps_tp_str):
|
||||
proper repr of GstCaps : <GstCaps at <adress> : '<caps.to_string>'>
|
||||
|
||||
2005-06-09 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* examples/gst/gstfile.py: (Discoverer.discover):
|
||||
whoops, pipeline was being run twice :)
|
||||
|
||||
2005-06-09 Zaheer Abbas Merali <zaheerabbas at merali dot org>
|
||||
|
||||
* examples/gst/gstfile.py: fix typo
|
||||
|
||||
2005-06-08 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* examples/gst/Makefile.am:
|
||||
* examples/gst/gstfile.py:
|
||||
renamed gst-file.py to gstfile.py and made the Discoverer class useable
|
||||
in other applications/scripts
|
||||
|
||||
* examples/gst/audioconcat.py:
|
||||
Example application that uses the Discoverer and the gnonlin elements to
|
||||
concatenate several audio files to one single one
|
||||
|
||||
2005-06-07 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* examples/gst/Makefile.am:
|
||||
* examples/gst/gst-file.py:
|
||||
New example that shows how to use gst-python in an object-oriented way,
|
||||
and how to override existing methods
|
||||
|
||||
2005-06-02 Edward Hervey <edward@fluendo.com>
|
||||
|
||||
* gst/gstbuffer.override (_wrap_gst_buffer_set_data):
|
||||
gcc 4.x bugfixes
|
||||
|
||||
2005-05-04 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/gst.defs:
|
||||
factory.create doesn't need a name
|
||||
* gst/gst.override:
|
||||
implement tp_str and tp_repr gst.Object and gst.PluginFeature
|
||||
* gst/gstelement.override:
|
||||
implement factory.get_pad_templates and make element.link_pads
|
||||
take NULL, pads or strings as the pad argument
|
||||
* gst/gstpad.override:
|
||||
implement tp_getattr for GstPadTemplate
|
||||
|
||||
2005-05-03 Zaheer Abbas Merali <zaheerabbas at merali dot org>
|
||||
|
||||
* gst/pygstvalue.c: (pygst_value_from_pyobject):
|
||||
stupid, stupid, stupid
|
||||
|
||||
2005-05-03 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/gstcaps.override:
|
||||
fix uninitialized warning and refator function
|
||||
|
||||
2005-05-03 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/pygstvalue.c:
|
||||
* gst/gst-argtypes.c:
|
||||
* gst/gst.override:
|
||||
define NO_IMPORT_PYGOBJECT to have a correct extern declaration
|
||||
reenable _pygst_element_init and ifdef it correctly
|
||||
* gst/arg-types.py:
|
||||
check errors
|
||||
* gst/gstcaps.override:
|
||||
- remove list append functionality. Sets don't support the +
|
||||
operator
|
||||
- implement richcompare and coerce, nonzero, or, xor and subtract
|
||||
number functions
|
||||
* testsuite/test_caps.py:
|
||||
add tests for the new stuff
|
||||
|
||||
2005-05-03 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* testsuite/Makefile.am:
|
||||
* testsuite/common.py:
|
||||
rework common so that it behaves a bit more sanely
|
||||
make the inner workings more clear
|
||||
|
||||
2005-05-03 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* configure.ac:
|
||||
add Wall and Werror just like other modules
|
||||
* gst/gst.override:
|
||||
* gst/gstelement.override:
|
||||
fix compile problems for Wall Werror
|
||||
* testsuite/common.py:
|
||||
* Makefile.am:
|
||||
* gst/Makefile.am:
|
||||
* gst/ltihooks.py:
|
||||
* ltihooks.py:
|
||||
move ltihooks to root; having it in gst was a bad hack and
|
||||
breaks distcheck
|
||||
|
||||
2005-05-03 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* testsuite/common.py: ltihooks only needed for uninstalled (?)
|
||||
|
||||
2005-05-03 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* testsuite/runtests.py: a much nicer way of getting all the tests
|
||||
|
||||
2005-05-03 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* testsuite/Makefile.am:
|
||||
run tests with GST_DEBUG=*:0 so they don't produce any debugging
|
||||
output
|
||||
* testsuite/test_element.py:
|
||||
don't disable stderr
|
||||
* gst/gstbuffer.override:
|
||||
initialize size correctly
|
||||
|
||||
2005-05-03 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* testsuite/runtests.py: also return exit code 1 in case of errors
|
||||
|
||||
2005-05-02 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* testsuite/common.py: Added case for 64bit-system that don't have
|
||||
the dl module
|
||||
|
||||
2005-05-02 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/Makefile.am:
|
||||
running the code generator depends on the files it uses
|
||||
* gst/arg-types.py:
|
||||
add GstCaps parsing
|
||||
* gst/gstelement.override:
|
||||
make element.link take an optional caps parameter, deprecate
|
||||
element.link_filtered
|
||||
* testsuite/test_caps.py:
|
||||
replace caps.get_strcuture(i) calls with caps[i], the deprecation
|
||||
warnings are annoying
|
||||
|
||||
2005-05-01 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* testsuite/test_interface.py:
|
||||
do not do stuff in a testsuite that isn't guaranteed to be there.
|
||||
could do with some way of detecting and skipping.
|
||||
|
||||
2005-05-01 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/gst-types.c:
|
||||
remove, it's called gst-argtypes.c these days
|
||||
* gst/common.h:
|
||||
* gst/gst-argtypes.c: (pygst_caps_from_pyobject):
|
||||
add function to transform a PyObject to a GstCaps*
|
||||
* gst/gstcaps.override:
|
||||
implement more sequence functions, deprecate caps.get_structure() in
|
||||
favour of caps[i] and make the structure-by-reference stuff work
|
||||
* gst/gststructure.override:
|
||||
make structures from caps work by reference but don't die a horrible
|
||||
death if the caps get removed before the structure is
|
||||
* testsuite/Makefile.am:
|
||||
run with G_DEBUG=fatal_warnings so we crash on g_warnings in C code
|
||||
* testsuite/test_caps.py:
|
||||
add some checks
|
||||
|
||||
2005-04-30 Benjamin Otte <otte@gnome.org>
|
||||
|
||||
* gst/gst.override:
|
||||
pyg_register_class_init is new API, so only use it when available.
|
||||
If not available gst.element_register won't work either, but I just
|
||||
won't care about that right now.
|
||||
|
||||
2005-04-30 Benjamin Otte <otte@gnome.org>
|
||||
|
||||
* gst/arg-types.py:
|
||||
ref the GstData we get in conversions as pygst_data_from_pyobject
|
||||
doesn't do that
|
||||
* gst/gst-types.c: (pygst_data_from_pyobject),
|
||||
(pygst_data_to_pyobject), (PyGstData_from_value),
|
||||
(PyGstData_to_value):
|
||||
make GstData <=> GValue conversions use the correct G_VALUE_TYPE and
|
||||
don't copy the values, but just ref them. Avoids mad buffer copying
|
||||
* gst/common.h:
|
||||
include GstData <=> PyObject conversion funcs
|
||||
* gst/gst.override:
|
||||
- wrap gst.element_register
|
||||
- add _pygst_get_plugin to query the plugin used by Python.
|
||||
Necessary preparation for a Python plugin loader. Returns NULL if
|
||||
no plugin, in that case gst.element_register registers the element
|
||||
as part of the running app.
|
||||
- add a class initializer for gst.Element subtypes, that checks the
|
||||
variables __gsttemplates__ and __gstdetails__ and makes the correct
|
||||
gst_element_class_set_element_details and
|
||||
gst_element_class_add_pad_templates calls from them. Note: This
|
||||
has issues when virtual methods are enabled.
|
||||
- add _pygst_element_check_error. This functions checks if Python
|
||||
code raised an exception and if so calls gst_element_error on the
|
||||
element and clears the error. Very useful in
|
||||
loop/chain/get-functions
|
||||
* gst/gstbuffer.override:
|
||||
- implement buffer.copy_on_write()
|
||||
- implement sq_(ass_)[item|slice] functions for GstBuffer
|
||||
- fix PyBufferProcs to allow writing when buffer is writable
|
||||
* gst/gstpad.override:
|
||||
- wrap gst.Pad to call gst_pad_new or gst_pad_new_from_template
|
||||
automatically based on arguments
|
||||
- don't attach private pad data to the element private, use
|
||||
g_object_set_data instead
|
||||
- make attaching functions to pads use closures. Allows garbage
|
||||
collecting pads where handlers have been set
|
||||
- fix _repr function to only print parent element's name if parent
|
||||
exists
|
||||
* gst/gstmodule.c: (init_gst):
|
||||
register GstData <=> GValue conversion
|
||||
|
||||
2005-04-28 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/gstbuffer.override:
|
||||
Let's unref the buffer we created - prevents gst.Buffer from leaking
|
||||
|
||||
2005-04-27 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/gstbuffer.override:
|
||||
throw TypeError if bufsize < data size. Fixes testsuite
|
||||
|
||||
2005-04-26 Johan Dahlin <jdahlin@async.com.br>
|
||||
|
||||
* testsuite/runtests.py: Return exit code 1 if we have any failures
|
||||
|
||||
2005-04-26 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/gstbuffer.override:
|
||||
make Buffer() not use memory it doesn't own
|
||||
* testsuite/test_buffer.py:
|
||||
check that it doesn't
|
||||
|
||||
2005-04-19 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* gst/gststructure.override: (_wrap_gst_structure_get_double):
|
||||
Forgot to convert the returned value to a PyFloat...
|
||||
|
||||
2005-04-19 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* gst/gststructure.override: (_wrap_gst_structure_get_double):
|
||||
Added overriding function for getting double values from a gst.Structure
|
||||
|
||||
2005-04-16 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* configure.ac: bumped back required version of pygtk; we can backport
|
||||
or copy over the code generator for what we need
|
||||
|
||||
2005-04-16 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
|
||||
* configure.ac:
|
||||
Bump GStreamer core requirement to 0.8.9 for
|
||||
gst_pad_set_active_recursive.
|
||||
|
||||
* gst/gst.defs:
|
||||
Wrap gst_pad_set_active_recursive
|
||||
|
||||
2005-04-14 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* gst/gst.defs:
|
||||
Added definitions for methods of GstObject, GstElement, GstBin and Clock
|
||||
so you can create derived classes with more functionnalities.
|
||||
|
||||
* configure.ac: (ACLOCAL):
|
||||
bumped required version of PYGTK to 2.6.0
|
||||
|
||||
2005-04-14 Andy Wingo <wingo@pobox.com>
|
||||
|
||||
* gst/__init__.py (Value, Fourcc, IntRange, DoubleRange)
|
||||
(Fraction): New classes.
|
||||
|
||||
* gst/gst.override (_wrap_gst_tag_list_get)
|
||||
(_wrap_gst_tag_list_get_value_index)
|
||||
(tag_foreach_func_dict)
|
||||
(_wrap_gst_tag_list_subscript): Use gstvalue procs.
|
||||
(init): Initialize the pygstvalue stuff (which involves accessing
|
||||
definitions from gst/__init__.py).
|
||||
|
||||
* gst/gststructure.override (_wrap_gst_structure_ass_subscript):
|
||||
Just use the pygstvalue functions to do conversion. As it is right
|
||||
now, it's an incompatible change with the previous behavior,
|
||||
because it doesn't try to parse field values like "(fourcc)XVID".
|
||||
We can restore that previous behaviour if there is a need for it.
|
||||
(_wrap_gst_structure_subscript): Use gstvalue functions to do the
|
||||
conversion.
|
||||
|
||||
* gst/Makefile.am: Add in pygstvalue.[ch].
|
||||
|
||||
* gst/pygstvalue.h:
|
||||
* gst/pygstvalue.c: New files.
|
||||
(pygst_value_as_pyobject): Wraps pyg_value_as_pyobject, handling
|
||||
gstvalues as well.
|
||||
(pygst_value_init_for_pyobject): Sniffs a pyobject for a type and
|
||||
initializes a GValue appropriately.
|
||||
(pygst_value_from_pyobject): Wraps pyg_value_from_pyobject,
|
||||
handling gvalues as well.
|
||||
|
||||
* testsuite/test_struct.py (StructureTest.testStructureChange)
|
||||
(StructureTest.testGstValue): Add some tests for GstValue wrapping.
|
||||
|
||||
2005-04-25 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
|
||||
* gst/gstbuffer.override:
|
||||
|
|
|
@ -11,6 +11,7 @@ SUBDIRS = \
|
|||
DIST_SUBDIRS = $(UNCONDDIRS) docs
|
||||
|
||||
EXTRA_DIST = \
|
||||
ltihooks.py \
|
||||
gst-python.spec.in \
|
||||
gst-python.spec \
|
||||
README-docs \
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 495d6e30b3e513aebbc98467707c609c49ea654d
|
||||
Subproject commit d6e46b214fac0ecb46010ff522af2f7653e1c18e
|
16
configure.ac
16
configure.ac
|
@ -26,7 +26,8 @@ dnl required versions of other packages
|
|||
AC_SUBST(PYGTK_REQ, 2.4.0)
|
||||
AC_SUBST(GLIB_REQ, 2.0.0)
|
||||
AC_SUBST(GTK_REQ, 2.0.0)
|
||||
AC_SUBST(GST_REQ, 0.8.8.1)
|
||||
AC_SUBST(GST_REQ, 0.8.9)
|
||||
|
||||
|
||||
AC_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
|
@ -145,6 +146,19 @@ esac])
|
|||
|
||||
AM_CONDITIONAL(BUILD_DOCS, test "x$BUILD_DOCS" = "xyes")
|
||||
|
||||
dnl decide on error flags
|
||||
dnl if we support -Wall, set it unconditionally
|
||||
AS_COMPILER_FLAG(-Wall,
|
||||
PYGST_ERROR_CFLAGS="-Wall",
|
||||
PYGST_ERROR_CFLAGS="")
|
||||
dnl if we're in nano >= 1, add -Werror if supported
|
||||
if test "x$GST_CVS" = "xyes"
|
||||
then
|
||||
AS_COMPILER_FLAG(-Werror, PYGST_ERROR_CFLAGS="$PYGST_ERROR_CFLAGS -Werror")
|
||||
fi
|
||||
|
||||
PYGST_CFLAGS="$PYGST_ERROR_CFLAGS"
|
||||
AC_SUBST(PYGST_CFLAGS)
|
||||
|
||||
dnl add debugging options ...
|
||||
changequote(,)dnl
|
||||
|
|
|
@ -6,6 +6,8 @@ examples_DATA = \
|
|||
filesrc.py \
|
||||
gst123 \
|
||||
play.py \
|
||||
vorbisplay.py
|
||||
vorbisplay.py \
|
||||
gstfile.py \
|
||||
audioconcat.py
|
||||
|
||||
EXTRA_DIST = $(examples_DATA)
|
||||
|
|
128
examples/gst/audioconcat.py
Normal file
128
examples/gst/audioconcat.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# audio concat tool
|
||||
# takes in one or more audio files and creates one audio file of the combination
|
||||
|
||||
# Uses the gnonlin elements (http://gnonlin.sf.net/)
|
||||
|
||||
import os
|
||||
import sys
|
||||
import gobject
|
||||
import gst
|
||||
|
||||
from gstfile import Discoverer, time_to_string
|
||||
|
||||
class AudioSource(gst.Bin):
|
||||
"""A bin for audio sources with proper audio converters"""
|
||||
|
||||
def __init__(self, filename, caps):
|
||||
gst.Bin.__init__(self)
|
||||
self.filename = filename
|
||||
self.outcaps = caps
|
||||
|
||||
self.filesrc = gst.element_factory_make("filesrc")
|
||||
self.filesrc.set_property("location", self.filename)
|
||||
self.dbin = gst.element_factory_make("decodebin")
|
||||
self.ident = gst.element_factory_make("identity")
|
||||
self.audioconvert = gst.element_factory_make("audioconvert")
|
||||
self.audioscale = gst.element_factory_make("audioscale")
|
||||
|
||||
self.add_many(self.filesrc, self.dbin, self.ident,
|
||||
self.audioconvert, self.audioscale)
|
||||
self.filesrc.link(self.dbin)
|
||||
self.audioconvert.link(self.audioscale)
|
||||
self.audioscale.link(self.ident, caps)
|
||||
self.add_ghost_pad(self.ident.get_pad("src"), "src")
|
||||
|
||||
self.dbin.connect("new-decoded-pad", self._new_decoded_pad_cb)
|
||||
|
||||
def _new_decoded_pad_cb(self, dbin, pad, is_last):
|
||||
if not "audio" in pad.get_caps().to_string():
|
||||
return
|
||||
pad.link(self.audioconvert.get_pad("sink"))
|
||||
|
||||
gobject.type_register(AudioSource)
|
||||
|
||||
class AudioConcat(gst.Thread):
|
||||
"""A Gstreamer thread that concatenates a series of audio files to another audio file"""
|
||||
|
||||
def __init__(self, infiles, outfile, audioenc="rawvorbisenc", muxer="oggmux"):
|
||||
gst.Thread.__init__(self)
|
||||
self.infiles = infiles
|
||||
self.outfile = outfile
|
||||
self.audioenc = gst.element_factory_make(audioenc)
|
||||
if not self.audioenc:
|
||||
raise NameError, str(audioenc + " audio encoder is not available")
|
||||
self.muxer = gst.element_factory_make(muxer)
|
||||
if not self.muxer:
|
||||
raise NameError, str(muxer + " muxer is not available")
|
||||
self.filesink = gst.element_factory_make("filesink")
|
||||
self.filesink.set_property("location", self.outfile)
|
||||
|
||||
self.timeline = gst.element_factory_make("gnltimeline")
|
||||
self.audiocomp = gst.element_factory_make("gnlcomposition", "audiocomp")
|
||||
|
||||
self.audioconvert = gst.element_factory_make("audioconvert")
|
||||
self.add_many(self.timeline, self.audioconvert,
|
||||
self.audioenc, self.muxer, self.filesink)
|
||||
|
||||
## identity perfect stream check !
|
||||
identity = gst.element_factory_make("identity")
|
||||
identity.set_property("check-perfect", True)
|
||||
self.add(identity)
|
||||
|
||||
#self.audioconvert.link(self.audioenc)
|
||||
if not self.audioconvert.link(identity):
|
||||
print "couldn't link audioconv -> ident"
|
||||
if not identity.link(self.audioenc):
|
||||
print "couldn't link ident -> audioenc"
|
||||
self.audioenc.link(self.muxer)
|
||||
self.muxer.link(self.filesink)
|
||||
|
||||
self.timeline.add(self.audiocomp)
|
||||
|
||||
caps = gst.caps_from_string("audio/x-raw-int,channels=2,rate=44100,depth=16")
|
||||
pos = 0L
|
||||
for infile in self.infiles:
|
||||
d = Discoverer(infile)
|
||||
if not d.audiolength:
|
||||
continue
|
||||
print "file", infile, "has length", time_to_string(d.audiolength)
|
||||
asource = AudioSource(infile, caps)
|
||||
gnlsource = gst.element_factory_make("gnlsource")
|
||||
gnlsource.set_property("element", asource)
|
||||
gnlsource.set_property("media-start", 0L)
|
||||
gnlsource.set_property("media-stop", d.audiolength)
|
||||
gnlsource.set_property("start", pos)
|
||||
gnlsource.set_property("stop", pos + d.audiolength)
|
||||
self.audiocomp.add(gnlsource)
|
||||
pos += d.audiolength
|
||||
|
||||
self.timeline.get_pad("src_audiocomp").link(self.audioconvert.get_pad("sink"))
|
||||
timelineprobe = gst.Probe(False, self.timelineprobe)
|
||||
self.timeline.get_pad("src_audiocomp").add_probe(timelineprobe)
|
||||
|
||||
def timelineprobe(self, probe, data):
|
||||
if isinstance(data, gst.Buffer):
|
||||
print "timeline outputs buffer", data.timestamp, data.duration
|
||||
else:
|
||||
print "timeline ouputs event", data.type
|
||||
return True
|
||||
|
||||
gobject.type_register(AudioConcat)
|
||||
|
||||
def eos_cb(pipeline):
|
||||
sys.exit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
print "Usage : %s <input file(s)> <output file>" % sys.argv[0]
|
||||
print "\tCreates an ogg file from all the audio input files"
|
||||
sys.exit()
|
||||
if not gst.element_factory_make("gnltimeline"):
|
||||
print "You need the gnonlin elements installed (http://gnonlin.sf.net/)"
|
||||
sys.exit()
|
||||
concat = AudioConcat(sys.argv[1:-1], sys.argv[-1])
|
||||
concat.connect("eos", eos_cb)
|
||||
concat.set_state(gst.STATE_PLAYING)
|
||||
gst.main()
|
241
examples/gst/gstfile.py
Normal file
241
examples/gst/gstfile.py
Normal file
|
@ -0,0 +1,241 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# gstfile.py
|
||||
# (c) 2005 Edward Hervey <edward at fluendo dot com>
|
||||
# Discovers and prints out multimedia information of files
|
||||
|
||||
# This example shows how to use gst-python:
|
||||
# _ in an object-oriented way (Discoverer class)
|
||||
# _ subclassing a gst.Pipeline
|
||||
# _ and overidding existing methods (do_iterate())
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import gobject
|
||||
import gst
|
||||
|
||||
def time_to_string(value):
|
||||
"""
|
||||
transform a value in nanoseconds into a human-readable string
|
||||
"""
|
||||
ms = value / gst.MSECOND
|
||||
sec = ms / 1000
|
||||
ms = ms % 1000
|
||||
min = sec / 60
|
||||
sec = sec % 60
|
||||
return "%2dm %2ds %3d" % (min, sec, ms)
|
||||
|
||||
|
||||
class Discoverer(gst.Pipeline):
|
||||
"""
|
||||
Discovers information about files
|
||||
"""
|
||||
mimetype = None
|
||||
|
||||
audiocaps = {}
|
||||
videocaps = {}
|
||||
|
||||
videowidth = 0
|
||||
videoheight = 0
|
||||
videorate = 0
|
||||
|
||||
audiofloat = False
|
||||
audiorate = 0
|
||||
audiodepth = 0
|
||||
audiowidth = 0
|
||||
audiochannels = 0
|
||||
|
||||
audiolength = 0L
|
||||
videolength = 0L
|
||||
|
||||
is_video = False
|
||||
is_audio = False
|
||||
|
||||
otherstreams = []
|
||||
|
||||
finished = False
|
||||
tags = {}
|
||||
|
||||
|
||||
def __init__(self, filename):
|
||||
gobject.GObject.__init__(self)
|
||||
|
||||
self.mimetype = None
|
||||
|
||||
self.audiocaps = {}
|
||||
self.videocaps = {}
|
||||
|
||||
self.videowidth = 0
|
||||
self.videoheight = 0
|
||||
self.videorate = 0
|
||||
|
||||
self.audiofloat = False
|
||||
self.audiorate = 0
|
||||
self.audiodepth = 0
|
||||
self.audiowidth = 0
|
||||
self.audiochannels = 0
|
||||
|
||||
self.audiolength = 0L
|
||||
self.videolength = 0L
|
||||
|
||||
self.is_video = False
|
||||
self.is_audio = False
|
||||
|
||||
self.otherstreams = []
|
||||
|
||||
self.finished = False
|
||||
self.tags = {}
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
self.finished = True
|
||||
return
|
||||
|
||||
# the initial elements of the pipeline
|
||||
self.src = gst.element_factory_make("filesrc")
|
||||
self.src.set_property("location", filename)
|
||||
self.src.set_property("blocksize", 1000000)
|
||||
self.dbin = gst.element_factory_make("decodebin")
|
||||
self.add_many(self.src, self.dbin)
|
||||
self.src.link(self.dbin)
|
||||
self.typefind = self.dbin.get_by_name("typefind")
|
||||
|
||||
# callbacks
|
||||
self.typefind.connect("have-type", self._have_type_cb)
|
||||
self.dbin.connect("new-decoded-pad", self._new_decoded_pad_cb)
|
||||
self.dbin.connect("unknown-type", self._unknown_type_cb)
|
||||
self.dbin.connect("found-tag", self._found_tag_cb)
|
||||
|
||||
self.discover()
|
||||
|
||||
def discover(self):
|
||||
"""iterate on ourself to find the information on the given file"""
|
||||
if self.finished:
|
||||
return
|
||||
self.set_state(gst.STATE_PLAYING)
|
||||
while 1:
|
||||
if not self.iterate():
|
||||
break
|
||||
self.set_state(gst.STATE_NULL)
|
||||
self.finished = True
|
||||
|
||||
def print_info(self):
|
||||
"""prints out the information on the given file"""
|
||||
if not self.finished:
|
||||
self.discover()
|
||||
if not self.mimetype:
|
||||
print "Unknown media type"
|
||||
return
|
||||
print "Mime Type :\t", self.mimetype
|
||||
if not self.is_video and not self.is_audio:
|
||||
return
|
||||
print "Length :\t", time_to_string(max(self.audiolength, self.videolength))
|
||||
print "\tAudio:", time_to_string(self.audiolength), "\tVideo:", time_to_string(self.videolength)
|
||||
if self.is_video:
|
||||
print "Video :"
|
||||
print "\t%d x %d @ %.2f fps" % (self.videowidth,
|
||||
self.videoheight,
|
||||
self.videorate)
|
||||
if self.tags.has_key("video-codec"):
|
||||
print "\tCodec :", self.tags.pop("video-codec")
|
||||
if self.is_audio:
|
||||
print "Audio :"
|
||||
if self.audiofloat:
|
||||
print "\t%d channels(s) : %dHz @ %dbits (float)" % (self.audiochannels,
|
||||
self.audiorate,
|
||||
self.audiowidth)
|
||||
else:
|
||||
print "\t%d channels(s) : %dHz @ %dbits (int)" % (self.audiochannels,
|
||||
self.audiorate,
|
||||
self.audiodepth)
|
||||
if self.tags.has_key("audio-codec"):
|
||||
print "\tCodec :", self.tags.pop("audio-codec")
|
||||
for stream in self.otherstreams:
|
||||
if not stream == self.mimetype:
|
||||
print "Other unsuported Multimedia stream :", stream
|
||||
if self.tags:
|
||||
print "Additional information :"
|
||||
for tag in self.tags.keys():
|
||||
print "%20s :\t" % tag, self.tags[tag]
|
||||
|
||||
def _unknown_type_cb(self, dbin, pad, caps):
|
||||
self.otherstreams.append(caps.to_string())
|
||||
|
||||
def _have_type_cb(self, typefind, prob, caps):
|
||||
self.mimetype = caps.to_string()
|
||||
|
||||
def _notify_caps_cb(self, pad, args):
|
||||
caps = pad.get_negotiated_caps()
|
||||
if not caps:
|
||||
return
|
||||
# the caps are fixed
|
||||
# We now get the total length of that stream
|
||||
length = pad.get_peer().query(gst.QUERY_TOTAL, gst.FORMAT_TIME)
|
||||
# We store the caps and length in the proper location
|
||||
if "audio" in caps.to_string():
|
||||
self.audiocaps = caps
|
||||
self.audiolength = length
|
||||
self.audiorate = caps[0]["rate"]
|
||||
self.audiowidth = caps[0]["width"]
|
||||
self.audiochannels = caps[0]["channels"]
|
||||
if "x-raw-float" in caps.to_string():
|
||||
self.audiofloat = True
|
||||
else:
|
||||
self.audiodepth = caps[0]["depth"]
|
||||
if (not self.is_video) or self.videocaps:
|
||||
self.finished = True
|
||||
elif "video" in caps.to_string():
|
||||
self.videocaps = caps
|
||||
self.videolength = length
|
||||
self.videowidth = caps[0]["width"]
|
||||
self.videoheight = caps[0]["height"]
|
||||
self.videorate = caps[0]["framerate"]
|
||||
if (not self.is_audio) or self.audiocaps:
|
||||
self.finished = True
|
||||
|
||||
def _new_decoded_pad_cb(self, dbin, pad, is_last):
|
||||
# Does the file contain got audio or video ?
|
||||
if "audio" in pad.get_caps().to_string():
|
||||
self.is_audio = True
|
||||
elif "video" in pad.get_caps().to_string():
|
||||
self.is_video = True
|
||||
if is_last and not self.is_video and not self.is_audio:
|
||||
self.finished = True
|
||||
return
|
||||
# we connect a fakesink to the new pad...
|
||||
fakesink = gst.element_factory_make("fakesink")
|
||||
self.add(fakesink)
|
||||
sinkpad = fakesink.get_pad("sink")
|
||||
# ... and connect a callback for when the caps are fixed
|
||||
sinkpad.connect("notify::caps", self._notify_caps_cb)
|
||||
pad.link(sinkpad)
|
||||
fakesink.set_state(gst.STATE_PLAYING)
|
||||
|
||||
def _found_tag_cb(self, dbin, source, tags):
|
||||
self.tags.update(tags)
|
||||
|
||||
def do_iterate(self):
|
||||
# this overrides the GstBin 'iterate' method
|
||||
# if we have finished discovering we stop the iteration
|
||||
if self.finished:
|
||||
return False
|
||||
# else we call the parent class method
|
||||
return gst.Pipeline.do_iterate(self)
|
||||
|
||||
gobject.type_register(Discoverer)
|
||||
|
||||
def main(args):
|
||||
if len(args) < 2:
|
||||
print 'usage: %s files...' % args[0]
|
||||
return 2
|
||||
|
||||
if len(args[1:]) > 1:
|
||||
for filename in args[1:]:
|
||||
print "File :", filename
|
||||
Discoverer(filename).print_info()
|
||||
print "\n"
|
||||
else:
|
||||
Discoverer(args[1]).print_info()
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
|
@ -1,4 +1,4 @@
|
|||
common_cflags = $(PYGTK_CFLAGS) $(GST_CFLAGS) -fno-strict-aliasing
|
||||
common_cflags = $(PYGTK_CFLAGS) $(GST_CFLAGS) $(PYGST_CFLAGS) -fno-strict-aliasing
|
||||
common_libadd = $(GST_LIBS)
|
||||
common_ldflags = -module -avoid-version
|
||||
|
||||
|
@ -22,20 +22,22 @@ else
|
|||
play_lib =
|
||||
endif
|
||||
|
||||
defs_DATA = gst-types.defs
|
||||
defs_DATA = gst-types.defs \
|
||||
gst-extrafuncs.defs
|
||||
defsdir = $(pkgdatadir)/2.0/defs
|
||||
|
||||
noinst_HEADERS = common.h
|
||||
noinst_HEADERS = common.h pygstvalue.h
|
||||
|
||||
INCLUDES = $(PYTHON_INCLUDES)
|
||||
EXTRA_DIST = $(defs_DATA) common.h arg-types.py ltihooks.py
|
||||
EXTRA_DIST = $(defs_DATA) common.h arg-types.py
|
||||
PYGTK_DEFSDIR = @PYGTK_DEFSDIR@
|
||||
GEN_FILES = arg-types.py gst-types.defs
|
||||
|
||||
# GStreamer bindings
|
||||
_gst_la_CFLAGS = $(common_cflags)
|
||||
_gst_la_LIBADD = $(common_libadd)
|
||||
_gst_la_LDFLAGS = $(common_ldflags) -export-symbols-regex init_gst
|
||||
_gst_la_SOURCES = gst-argtypes.c gstmodule.c
|
||||
_gst_la_SOURCES = gst-argtypes.c gstmodule.c pygstvalue.c
|
||||
nodist__gst_la_SOURCES = gst.c
|
||||
GST_OVERRIDES = \
|
||||
gst.override \
|
||||
|
@ -43,13 +45,14 @@ GST_OVERRIDES = \
|
|||
gstbuffer.override \
|
||||
gstcaps.override \
|
||||
gstelement.override \
|
||||
gstevent.override \
|
||||
gstpad.override \
|
||||
gststructure.override
|
||||
|
||||
GST_DEFS = gst.defs gst-types.defs
|
||||
GST_DEFS = gst.defs gst-types.defs gst-extrafuncs.defs
|
||||
CLEANFILES = gst.c
|
||||
EXTRA_DIST += $(GST_DEFS) $(GST_OVERRIDES)
|
||||
gst.c: $(GST_DEFS) $(GST_OVERRIDES)
|
||||
gst.c: $(GST_DEFS) $(GST_OVERRIDES) $(GEN_FILES)
|
||||
|
||||
# gst-play bindings
|
||||
play_la_CFLAGS = $(common_cflags) $(GST_PLAY_CFLAGS)
|
||||
|
@ -61,7 +64,7 @@ PLAY_OVERRIDES = play.override
|
|||
PLAY_DEFS = play.defs
|
||||
CLEANFILES += play.c
|
||||
EXTRA_DIST += $(PLAY_DEFS) $(PLAY_OVERRIDES)
|
||||
play.c: $(PLAY_DEFS) $(PLAY_OVERRIDES)
|
||||
play.c: $(PLAY_DEFS) $(PLAY_OVERRIDES) $(GEN_FILES)
|
||||
|
||||
# GStreamer interfaces bindings
|
||||
interfaces_la_CFLAGS = $(common_cflags) $(GST_INTERFACES_CFLAGS)
|
||||
|
@ -73,9 +76,9 @@ INTERFACES_OVERRIDES = interfaces.override xoverlay.override
|
|||
INTERFACES_DEFS = interfaces.defs xoverlay.defs xwindowlistener.defs
|
||||
CLEANFILES += interfaces.c
|
||||
EXTRA_DIST += $(INTERFACES_DEFS) $(INTERFACES_OVERRIDES)
|
||||
interfaces.c: $(INTERFACES_DEFS) $(INTERFACES_OVERRIDES)
|
||||
interfaces.c: $(INTERFACES_DEFS) $(INTERFACES_OVERRIDES) $(GEN_FILES)
|
||||
|
||||
.defs.c:
|
||||
.defs.c:
|
||||
(cd $(srcdir) \
|
||||
&& $(PYGTK_CODEGEN) \
|
||||
--load-types $(srcdir)/arg-types.py \
|
||||
|
|
|
@ -36,4 +36,40 @@ try:
|
|||
except ImportError:
|
||||
pass
|
||||
|
||||
class Value:
|
||||
def __init__(self, type):
|
||||
assert type in ('fourcc', 'intrange', 'doublerange', 'fraction')
|
||||
self.type = type
|
||||
|
||||
class Fourcc(Value):
|
||||
def __init__(self, string):
|
||||
Value.__init__(self, 'fourcc')
|
||||
self.fourcc = string
|
||||
def __repr__(self):
|
||||
return '<gst.Fourcc %s>' % self.fourcc
|
||||
|
||||
class IntRange(Value):
|
||||
def __init__(self, low, high):
|
||||
Value.__init__(self, 'intrange')
|
||||
self.low = low
|
||||
self.high = high
|
||||
def __repr__(self):
|
||||
return '<gst.IntRange [%d, %d]>' % (self.low, self.high)
|
||||
|
||||
class DoubleRange(Value):
|
||||
def __init__(self, low, high):
|
||||
Value.__init__(self, 'doublerange')
|
||||
self.low = low
|
||||
self.high = high
|
||||
def __repr__(self):
|
||||
return '<gst.DoubleRange [%f, %f]>' % (self.low, self.high)
|
||||
|
||||
class Fraction(Value):
|
||||
def __init__(self, num, denom):
|
||||
Value.__init__(self, 'fraction')
|
||||
self.num = num
|
||||
self.denom = denom
|
||||
def __repr__(self):
|
||||
return '<gst.Fraction %d/%d>' % (self.num, self.denom)
|
||||
|
||||
from _gst import *
|
||||
|
|
|
@ -26,13 +26,15 @@ from argtypes import UInt64Arg, Int64Arg, PointerArg, ArgMatcher, ArgType, match
|
|||
|
||||
class GstDataPtrArg(ArgType):
|
||||
normal = (' if (!pygst_data_from_pyobject(py_%(name)s, &%(name)s))\n'
|
||||
' return NULL;\n')
|
||||
' return NULL;\n'
|
||||
' gst_data_ref (%(name)s);\n')
|
||||
null = (' if (py_%(name)s == Py_None)\n'
|
||||
' %(name)s = NULL;\n'
|
||||
' else if (pyst_data_from_pyobject(py_%(name)s, %(name)s_rect))\n'
|
||||
' %(name)s = &%(name)s_rect;\n'
|
||||
' else\n'
|
||||
' return NULL;\n')
|
||||
' return NULL;\n'
|
||||
' gst_data_ref (%(name)s);\n')
|
||||
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||
if pnull:
|
||||
info.varlist.add('GstData', pname + '_data')
|
||||
|
@ -84,7 +86,7 @@ class XmlNodeArg(ArgType):
|
|||
info.add_parselist('O', ['&py'+pname], [pname])
|
||||
info.arglist.append(pname)
|
||||
self.names["name"] = pname
|
||||
info.codebefore.append(self.parm %self.names)
|
||||
info.codebefore.append(self.parm % self.names)
|
||||
info.codeafter.append(self.parmp % self.names);
|
||||
def write_return(self, ptype, ownsreturn, info):
|
||||
info.varlist.add('PyObject', '*xml = _gst_get_libxml2_module()')
|
||||
|
@ -101,12 +103,66 @@ class XmlDocArg(XmlNodeArg):
|
|||
"xptr":"xmlDocPtr",
|
||||
"xwrap":"libxml_xmlDocPtrWrap"}
|
||||
|
||||
class GstCapsArg(ArgType):
|
||||
"""GstCaps node generator"""
|
||||
|
||||
before = (' %(name)s = pygst_caps_from_pyobject (py_%(name)s, %(namecopy)s);\n'
|
||||
' if (PyErr_Occurred())\n'
|
||||
' return NULL;\n')
|
||||
beforenull = (' if (py_%(name)s == Py_None)\n'
|
||||
' %(name)s = NULL;\n'
|
||||
' else\n'
|
||||
' ' + before)
|
||||
after = (' if (%(name)s && %(name)s_is_copy)\n'
|
||||
' gst_caps_free (%(name)s);\n')
|
||||
|
||||
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||
if ptype == 'const-GstCaps*':
|
||||
self.write_const_param(pname, pdflt, pnull, info)
|
||||
elif ptype == 'GstCaps*':
|
||||
self.write_normal_param(pname, pdflt, pnull, info)
|
||||
else:
|
||||
raise RuntimeError, "write_param not implemented for %s" % ptype
|
||||
def write_const_param(self, pname, pdflt, pnull, info):
|
||||
info.varlist.add('PyObject', '*py_'+pname)
|
||||
info.varlist.add('GstCaps', '*'+pname)
|
||||
info.varlist.add('gboolean', pname+'_is_copy')
|
||||
info.add_parselist('O', ['&py_'+pname], [pname])
|
||||
info.arglist.append(pname)
|
||||
if pnull:
|
||||
info.codebefore.append (self.beforenull % { 'name' : pname, 'namecopy' : '&'+pname+'_is_copy' })
|
||||
else:
|
||||
info.codebefore.append (self.before % { 'name' : pname, 'namecopy' : '&'+pname+'_is_copy' })
|
||||
info.codeafter.append (self.after % { 'name' : pname, 'namecopy' : '&'+pname+'_is_copy' })
|
||||
def write_normal_param(self, pname, pdflt, pnull, info):
|
||||
info.varlist.add('PyObject', '*py_'+pname)
|
||||
info.varlist.add('GstCaps', '*'+pname)
|
||||
info.add_parselist('O', ['&py_'+pname], [pname])
|
||||
info.arglist.append(pname)
|
||||
if pnull:
|
||||
info.codebefore.append (self.beforenull % { 'name' : pname, 'namecopy' : 'NULL' })
|
||||
else:
|
||||
info.codebefore.append (self.before % { 'name' : pname, 'namecopy' : 'NULL' })
|
||||
|
||||
def write_return(self, ptype, ownsreturn, info):
|
||||
if ptype == 'GstCaps*':
|
||||
info.varlist.add('GstCaps', '*ret')
|
||||
copyval = 'FALSE'
|
||||
elif ptype == 'const-GstCaps*':
|
||||
info.varlist.add('const GstCaps', '*ret')
|
||||
copyval = 'TRUE'
|
||||
else:
|
||||
raise RuntimeError, "write_return not implemented for %s" % ptype
|
||||
info.codeafter.append(' return pyg_boxed_new (GST_TYPE_CAPS, ret, '+copyval+', TRUE);')
|
||||
|
||||
matcher.register('GstData*', GstDataPtrArg())
|
||||
matcher.register('GstClockTime', UInt64Arg())
|
||||
matcher.register('GstClockTimeDiff', Int64Arg())
|
||||
matcher.register('xmlNodePtr', XmlNodeArg())
|
||||
matcher.register('xmlDocPtr', XmlDocArg())
|
||||
matcher.register('GstCaps', GstCapsArg()) #FIXME: does this work?
|
||||
matcher.register('GstCaps*', GstCapsArg()) #FIXME: does this work?
|
||||
matcher.register('const-GstCaps*', GstCapsArg())
|
||||
|
||||
arg = PointerArg('gpointer', 'G_TYPE_POINTER')
|
||||
matcher.register('GstClockID', arg)
|
||||
|
|
16
gst/common.h
16
gst/common.h
|
@ -23,6 +23,7 @@
|
|||
#define __COMMON_H__
|
||||
|
||||
#include <Python.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "pygobject.h"
|
||||
|
||||
|
@ -32,14 +33,21 @@
|
|||
|
||||
typedef struct {
|
||||
PyGObject *pad;
|
||||
PyObject *link_function;
|
||||
PyObject *event_function;
|
||||
PyObject *chain_function;
|
||||
PyObject *get_function;
|
||||
GClosure *link_function;
|
||||
GClosure *event_function;
|
||||
GClosure *chain_function;
|
||||
GClosure *get_function;
|
||||
GClosure *getcaps_function;
|
||||
} PyGstPadPrivate;
|
||||
|
||||
typedef struct {
|
||||
PyObject *func, *data;
|
||||
} PyGstCustomNotify;
|
||||
|
||||
/* from gst-types.c */
|
||||
gboolean pygst_data_from_pyobject(PyObject *object, GstData **data);
|
||||
PyObject *pygst_data_to_pyobject(GstData *data);
|
||||
GstCaps *pygst_caps_from_pyobject (PyObject *object, gboolean *copy);
|
||||
|
||||
|
||||
#endif /* __COMMON_H__ */
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
* Author: Johan Dahlin <johan@gnome.org>
|
||||
*/
|
||||
|
||||
/* define this for all source files that don't run init_pygobject()
|
||||
* before including pygobject.h */
|
||||
#define NO_IMPORT_PYGOBJECT
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "common.h"
|
||||
|
||||
|
@ -61,6 +65,44 @@ PyGstData_to_value(GValue *value, PyObject *object)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This function will return a copy, unless the following is all TRUE:
|
||||
* - The given PyObject contains a GstCaps already
|
||||
* - The copy parameter is non-NULL
|
||||
* - New years is the first of January
|
||||
* If copy is non-NULL, it is set to TRUE if a copy was made.
|
||||
* If the PyObject could not be converted to a caps, a TypeError is raised
|
||||
* and NULL is returned.
|
||||
*/
|
||||
GstCaps *
|
||||
pygst_caps_from_pyobject (PyObject *object, gboolean *copy)
|
||||
{
|
||||
if (pyg_boxed_check(object, GST_TYPE_CAPS)) {
|
||||
GstCaps *caps = pyg_boxed_get(object, GstCaps);
|
||||
if (copy) {
|
||||
*copy = FALSE;
|
||||
return caps;
|
||||
} else {
|
||||
return gst_caps_copy (caps);
|
||||
}
|
||||
} else if (pyg_boxed_check(object, GST_TYPE_STRUCTURE)) {
|
||||
GstStructure *structure = pyg_boxed_get(object, GstStructure);
|
||||
if (copy)
|
||||
*copy = TRUE;
|
||||
return gst_caps_new_full (gst_structure_copy (structure), NULL);
|
||||
} else if (PyString_Check (object)) {
|
||||
GstCaps *caps = gst_caps_from_string (PyString_AsString (object));
|
||||
if (!caps) {
|
||||
PyErr_SetString(PyExc_TypeError, "could not convert string to GstCaps");
|
||||
return NULL;
|
||||
}
|
||||
if (copy)
|
||||
*copy = TRUE;
|
||||
return caps;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "could not convert to GstCaps");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_pygst_register_boxed_types(PyObject *moddict)
|
||||
{
|
||||
|
|
25
gst/gst-extrafuncs.defs
Normal file
25
gst/gst-extrafuncs.defs
Normal file
|
@ -0,0 +1,25 @@
|
|||
; -*- scheme -*-
|
||||
|
||||
(define-method flags
|
||||
(of-object "GstElement")
|
||||
(c-name "GST_FLAGS")
|
||||
(return-type "GstElementFlags")
|
||||
)
|
||||
|
||||
(define-method set_flag
|
||||
(of-object "GstObject")
|
||||
(c-name "GST_FLAG_SET")
|
||||
(return-type "none")
|
||||
(parameters
|
||||
'("GstObjectFlags" "flags")
|
||||
)
|
||||
)
|
||||
|
||||
(define-method unset_flag
|
||||
(of-object "GstObject")
|
||||
(c-name "GST_FLAG_UNSET")
|
||||
(return-type "none")
|
||||
(parameters
|
||||
'("GstObjectFlags" "flag")
|
||||
)
|
||||
)
|
|
@ -1,70 +0,0 @@
|
|||
/* gst-python
|
||||
* Copyright (C) 2004 Johan Dahlin
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Johan Dahlin <johan@gnome.org>
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <pygobject.h>
|
||||
|
||||
gboolean
|
||||
pygst_data_from_pyobject(PyObject *object, GstData **data)
|
||||
{
|
||||
if (pyg_boxed_check(object, GST_TYPE_DATA)) {
|
||||
*data = pyg_boxed_get(object, GstData);
|
||||
return TRUE;
|
||||
} else if (pyg_boxed_check(object, GST_TYPE_BUFFER)) {
|
||||
*data = GST_DATA (pyg_boxed_get(object, GstBuffer));
|
||||
return TRUE;
|
||||
} else if (pyg_boxed_check(object, GST_TYPE_EVENT)) {
|
||||
*data = GST_DATA (pyg_boxed_get(object, GstEvent));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyErr_SetString(PyExc_TypeError, "could not convert to GstData");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyGstData_from_value(const GValue *value)
|
||||
{
|
||||
GstData *data = (GstData *)g_value_get_boxed(value);
|
||||
|
||||
return pyg_boxed_new(GST_TYPE_DATA, data, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
PyGstData_to_value(GValue *value, PyObject *object)
|
||||
{
|
||||
GstData* data;
|
||||
|
||||
if (!pygst_data_from_pyobject(object, &data))
|
||||
return -1;
|
||||
|
||||
g_value_set_boxed(value, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_pygst_register_boxed_types(PyObject *moddict)
|
||||
{
|
||||
pyg_register_boxed_custom(GST_TYPE_DATA,
|
||||
PyGstData_from_value,
|
||||
PyGstData_to_value);
|
||||
}
|
|
@ -6,9 +6,6 @@
|
|||
(parent "GObject")
|
||||
(c-name "GstObject")
|
||||
(gtype-id "GST_TYPE_OBJECT")
|
||||
(fields
|
||||
'("guint32" "flags")
|
||||
)
|
||||
)
|
||||
|
||||
(define-object Index
|
||||
|
@ -39,6 +36,13 @@
|
|||
(gtype-id "GST_TYPE_CLOCK")
|
||||
)
|
||||
|
||||
(define-object Bus
|
||||
(in-module "Gst")
|
||||
(parent "GstObject")
|
||||
(c-name "GstBus")
|
||||
(gtype-id "GST_TYPE_BUS")
|
||||
)
|
||||
|
||||
(define-object Pad
|
||||
(in-module "Gst")
|
||||
(parent "GstObject")
|
||||
|
@ -46,13 +50,6 @@
|
|||
(gtype-id "GST_TYPE_PAD")
|
||||
)
|
||||
|
||||
(define-object GhostPad
|
||||
(in-module "Gst")
|
||||
(parent "GstPad")
|
||||
(c-name "GstGhostPad")
|
||||
(gtype-id "GST_TYPE_GHOST_PAD")
|
||||
)
|
||||
|
||||
(define-object PadTemplate
|
||||
(in-module "Gst")
|
||||
(parent "GstObject")
|
||||
|
@ -95,13 +92,6 @@
|
|||
(gtype-id "GST_TYPE_QUEUE")
|
||||
)
|
||||
|
||||
(define-object RealPad
|
||||
(in-module "Gst")
|
||||
(parent "GstPad")
|
||||
(c-name "GstRealPad")
|
||||
(gtype-id "GST_TYPE_REAL_PAD")
|
||||
)
|
||||
|
||||
(define-object Registry
|
||||
(in-module "Gst")
|
||||
(parent "GObject")
|
||||
|
@ -130,11 +120,11 @@
|
|||
(gtype-id "GST_TYPE_SYSTEM_CLOCK")
|
||||
)
|
||||
|
||||
(define-object Thread
|
||||
(define-object Task
|
||||
(in-module "Gst")
|
||||
(parent "GstBin")
|
||||
(c-name "GstThread")
|
||||
(gtype-id "GST_TYPE_THREAD")
|
||||
(parent "GstObject")
|
||||
(c-name "GstTask")
|
||||
(gtype-id "GST_TYPE_TASK")
|
||||
)
|
||||
|
||||
(define-object TypeFindFactory
|
||||
|
@ -151,69 +141,49 @@
|
|||
(gtype-id "GST_TYPE_XML")
|
||||
)
|
||||
|
||||
::
|
||||
:: MiniObject types
|
||||
::
|
||||
|
||||
(define-object Buffer
|
||||
(in-module "Gst")
|
||||
(parent "GstMiniObject")
|
||||
(c-name "GstBuffer")
|
||||
(gtype-id "GST_TYPE_BUFFER")
|
||||
)
|
||||
|
||||
(define-object Event
|
||||
(in-module "Gst")
|
||||
(parent "GstMiniObject")
|
||||
(c-name "GstEvent")
|
||||
(gtype-id "GST_TYPE_EVENT")
|
||||
)
|
||||
|
||||
(define-object Message
|
||||
(in-module "Gst")
|
||||
(parent "GstMiniObject")
|
||||
(c-name "GstMessage")
|
||||
(gtype-id "GST_TYPE_MESSAGE")
|
||||
)
|
||||
|
||||
(define-object Query
|
||||
(in-module "Gst")
|
||||
(parent "GstMiniObject")
|
||||
(c-name "GstQuery")
|
||||
(gtype-id "GST_TYPE_QUERY")
|
||||
)
|
||||
|
||||
|
||||
;;
|
||||
;; Boxed types
|
||||
;;
|
||||
|
||||
(define-boxed Buffer
|
||||
(in-module "Gst")
|
||||
(c-name "GstBuffer")
|
||||
(gtype-id "GST_TYPE_BUFFER")
|
||||
(copy-func "gst_buffer_copy")
|
||||
(release-func "gst_data_unref")
|
||||
(fields
|
||||
;; GstData fields
|
||||
'("GType" "data_type")
|
||||
'("guint16" "flags")
|
||||
|
||||
;; GstBuffer fields
|
||||
'("guint" "size")
|
||||
'("guint" "maxsize")
|
||||
'("guint64" "offset")
|
||||
'("guint64" "offset_end")
|
||||
'("GstClockTime" "timestamp")
|
||||
)
|
||||
)
|
||||
|
||||
(define-boxed Caps
|
||||
(in-module "Gst")
|
||||
(c-name "GstCaps")
|
||||
(gtype-id "GST_TYPE_CAPS")
|
||||
)
|
||||
|
||||
(define-boxed Probe
|
||||
(in-module "Gst")
|
||||
(c-name "GstProbe")
|
||||
(gtype-id "GST_TYPE_PROBE")
|
||||
)
|
||||
|
||||
; Defined in arg-types.py
|
||||
;(define-boxed Data
|
||||
; (in-module "Gst")
|
||||
; (c-name "GstData")
|
||||
; (gtype-id "GST_TYPE_DATA")
|
||||
; (copy-func "gst_data_copy")
|
||||
; (release-func "gst_data_free")
|
||||
;)
|
||||
|
||||
(define-boxed Event
|
||||
(in-module "Gst")
|
||||
(c-name "GstEvent")
|
||||
(gtype-id "GST_TYPE_EVENT")
|
||||
)
|
||||
|
||||
(define-boxed GError
|
||||
(in-module "Gst")
|
||||
(c-name "GError")
|
||||
(gtype-id "GST_TYPE_G_ERROR")
|
||||
(copy-func "g_error_copy")
|
||||
(release-func "g_error_free")
|
||||
(fields
|
||||
'("GQuark" "domain")
|
||||
'("gint" "code")
|
||||
'("gchar*" "message"))
|
||||
)
|
||||
|
||||
(define-boxed Plugin
|
||||
(in-module "Gst")
|
||||
(parent "GObject")
|
||||
|
@ -235,7 +205,6 @@
|
|||
(gtype-id "GST_TYPE_TAG_LIST")
|
||||
)
|
||||
|
||||
|
||||
;; Enumerations and flags ...
|
||||
|
||||
(define-enum BinFlags
|
||||
|
@ -243,37 +212,59 @@
|
|||
(c-name "GstBinFlags")
|
||||
(gtype-id "GST_TYPE_BIN_FLAGS")
|
||||
(values
|
||||
'("flag-manager" "GST_BIN_FLAG_MANAGER")
|
||||
'("self-schedulable" "GST_BIN_SELF_SCHEDULABLE")
|
||||
'("flag-prefer-cothreads" "GST_BIN_FLAG_PREFER_COTHREADS")
|
||||
'("flag-fixed-clock" "GST_BIN_FLAG_FIXED_CLOCK")
|
||||
'("flag-last" "GST_BIN_FLAG_LAST")
|
||||
'("t" "GST_BIN_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum BufferFlag
|
||||
(define-flags BufferFlag
|
||||
(in-module "Gst")
|
||||
(c-name "GstBufferFlag")
|
||||
(gtype-id "GST_TYPE_BUFFER_FLAG")
|
||||
(values
|
||||
'("readonly" "GST_BUFFER_READONLY")
|
||||
'("subbuffer" "GST_BUFFER_SUBBUFFER")
|
||||
'("original" "GST_BUFFER_ORIGINAL")
|
||||
'("dontfree" "GST_BUFFER_DONTFREE")
|
||||
'("key-unit" "GST_BUFFER_KEY_UNIT")
|
||||
'("dontkeep" "GST_BUFFER_DONTKEEP")
|
||||
'("flag-last" "GST_BUFFER_FLAG_LAST")
|
||||
'("readonly" "GST_BUFFER_FLAG_READONLY")
|
||||
'("original" "GST_BUFFER_FLAG_ORIGINAL")
|
||||
'("preroll" "GST_BUFFER_FLAG_PREROLL")
|
||||
'("discont" "GST_BUFFER_FLAG_DISCONT")
|
||||
'("in-caps" "GST_BUFFER_FLAG_IN_CAPS")
|
||||
'("gap" "GST_BUFFER_FLAG_GAP")
|
||||
'("delta-unit" "GST_BUFFER_FLAG_DELTA_UNIT")
|
||||
'("last" "GST_BUFFER_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum ClockEntryStatus
|
||||
(define-enum BusFlags
|
||||
(in-module "Gst")
|
||||
(c-name "GstClockEntryStatus")
|
||||
(gtype-id "GST_TYPE_CLOCK_ENTRY_STATUS")
|
||||
(c-name "GstBusFlags")
|
||||
(gtype-id "GST_TYPE_BUS_FLAGS")
|
||||
(values
|
||||
'("ok" "GST_CLOCK_ENTRY_OK")
|
||||
'("early" "GST_CLOCK_ENTRY_EARLY")
|
||||
'("restart" "GST_CLOCK_ENTRY_RESTART")
|
||||
'("ushing" "GST_BUS_FLUSHING")
|
||||
'("ag-last" "GST_BUS_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum BusSyncReply
|
||||
(in-module "Gst")
|
||||
(c-name "GstBusSyncReply")
|
||||
(gtype-id "GST_TYPE_BUS_SYNC_REPLY")
|
||||
(values
|
||||
'("drop" "GST_BUS_DROP")
|
||||
'("pass" "GST_BUS_PASS")
|
||||
'("async" "GST_BUS_ASYNC")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum ClockReturn
|
||||
(in-module "Gst")
|
||||
(c-name "GstClockReturn")
|
||||
(gtype-id "GST_TYPE_CLOCK_RETURN")
|
||||
(values
|
||||
'("ok" "GST_CLOCK_OK")
|
||||
'("early" "GST_CLOCK_EARLY")
|
||||
'("unscheduled" "GST_CLOCK_UNSCHEDULED")
|
||||
'("busy" "GST_CLOCK_BUSY")
|
||||
'("badtime" "GST_CLOCK_BADTIME")
|
||||
'("error" "GST_CLOCK_ERROR")
|
||||
'("unsupported" "GST_CLOCK_UNSUPPORTED")
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -287,19 +278,6 @@
|
|||
)
|
||||
)
|
||||
|
||||
(define-enum ClockReturn
|
||||
(in-module "Gst")
|
||||
(c-name "GstClockReturn")
|
||||
(gtype-id "GST_TYPE_CLOCK_RETURN")
|
||||
(values
|
||||
'("stopped" "GST_CLOCK_STOPPED")
|
||||
'("timeout" "GST_CLOCK_TIMEOUT")
|
||||
'("early" "GST_CLOCK_EARLY")
|
||||
'("error" "GST_CLOCK_ERROR")
|
||||
'("unsupported" "GST_CLOCK_UNSUPPORTED")
|
||||
)
|
||||
)
|
||||
|
||||
(define-flags ClockFlags
|
||||
(in-module "Gst")
|
||||
(c-name "GstClockFlags")
|
||||
|
@ -310,29 +288,6 @@
|
|||
'("do-periodic-sync" "GST_CLOCK_FLAG_CAN_DO_PERIODIC_SYNC")
|
||||
'("do-periodic-async" "GST_CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC")
|
||||
'("set-resolution" "GST_CLOCK_FLAG_CAN_SET_RESOLUTION")
|
||||
'("set-speed" "GST_CLOCK_FLAG_CAN_SET_SPEED")
|
||||
)
|
||||
)
|
||||
|
||||
(define-flags CPUFlags
|
||||
(in-module "Gst")
|
||||
(c-name "GstCPUFlags")
|
||||
(gtype-id "GST_TYPE_CPU_FLAGS")
|
||||
(values
|
||||
'("mmx" "GST_CPU_FLAG_MMX")
|
||||
'("sse" "GST_CPU_FLAG_SSE")
|
||||
'("mmxext" "GST_CPU_FLAG_MMXEXT")
|
||||
'("3dnow" "GST_CPU_FLAG_3DNOW")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum DataFlags
|
||||
(in-module "Gst")
|
||||
(c-name "GstDataFlags")
|
||||
(gtype-id "GST_TYPE_DATA_FLAGS")
|
||||
(values
|
||||
'("readonly" "GST_DATA_READONLY")
|
||||
'("flag-last" "GST_DATA_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -341,17 +296,10 @@
|
|||
(c-name "GstElementFlags")
|
||||
(gtype-id "GST_TYPE_ELEMENT_FLAGS")
|
||||
(values
|
||||
'("complex" "GST_ELEMENT_COMPLEX")
|
||||
'("decoupled" "GST_ELEMENT_DECOUPLED")
|
||||
'("thread-suggested" "GST_ELEMENT_THREAD_SUGGESTED")
|
||||
'("infinite-loop" "GST_ELEMENT_INFINITE_LOOP")
|
||||
'("new-loopfunc" "GST_ELEMENT_NEW_LOOPFUNC")
|
||||
'("event-aware" "GST_ELEMENT_EVENT_AWARE")
|
||||
'("use-threadsafe-properties" "GST_ELEMENT_USE_THREADSAFE_PROPERTIES")
|
||||
'("scheduler-private1" "GST_ELEMENT_SCHEDULER_PRIVATE1")
|
||||
'("scheduler-private2" "GST_ELEMENT_SCHEDULER_PRIVATE2")
|
||||
'("locked-state" "GST_ELEMENT_LOCKED_STATE")
|
||||
'("in-error" "GST_ELEMENT_IN_ERROR")
|
||||
'("is-sink" "GST_ELEMENT_IS_SINK")
|
||||
'("flag-last" "GST_ELEMENT_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
@ -442,17 +390,11 @@
|
|||
'("unknown" "GST_EVENT_UNKNOWN")
|
||||
'("eos" "GST_EVENT_EOS")
|
||||
'("flush" "GST_EVENT_FLUSH")
|
||||
'("empty" "GST_EVENT_EMPTY")
|
||||
'("discontinuous" "GST_EVENT_DISCONTINUOUS")
|
||||
'("qos" "GST_EVENT_QOS")
|
||||
'("seek" "GST_EVENT_SEEK")
|
||||
'("seek-segment" "GST_EVENT_SEEK_SEGMENT")
|
||||
'("segment-done" "GST_EVENT_SEGMENT_DONE")
|
||||
'("size" "GST_EVENT_SIZE")
|
||||
'("rate" "GST_EVENT_RATE")
|
||||
'("filler" "GST_EVENT_FILLER")
|
||||
'("ts-offset" "GST_EVENT_TS_OFFSET")
|
||||
'("interrupt" "GST_EVENT_INTERRUPT")
|
||||
'("navigation" "GST_EVENT_NAVIGATION")
|
||||
'("tag" "GST_EVENT_TAG")
|
||||
)
|
||||
|
@ -548,6 +490,7 @@
|
|||
(values
|
||||
'("none" "GST_ASSOCIATION_FLAG_NONE")
|
||||
'("key-unit" "GST_ASSOCIATION_FLAG_KEY_UNIT")
|
||||
'("delta-unit" "GST_ASSOCIATION_FLAG_DELTA_UNIT")
|
||||
'("last" "GST_ASSOCIATION_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
@ -615,14 +558,71 @@
|
|||
)
|
||||
)
|
||||
|
||||
(define-enum IteratorResult
|
||||
(in-module "Gst")
|
||||
(c-name "GstIteratorResult")
|
||||
(gtype-id "GST_TYPE_ITERATOR_RESULT")
|
||||
(values
|
||||
'("done" "GST_ITERATOR_DONE")
|
||||
'("ok" "GST_ITERATOR_OK")
|
||||
'("resync" "GST_ITERATOR_RESYNC")
|
||||
'("error" "GST_ITERATOR_ERROR")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum IteratorItem
|
||||
(in-module "Gst")
|
||||
(c-name "GstIteratorItem")
|
||||
(gtype-id "GST_TYPE_ITERATOR_ITEM")
|
||||
(values
|
||||
'("skip" "GST_ITERATOR_ITEM_SKIP")
|
||||
'("pass" "GST_ITERATOR_ITEM_PASS")
|
||||
'("end" "GST_ITERATOR_ITEM_END")
|
||||
)
|
||||
)
|
||||
|
||||
(define-flags MessageType
|
||||
(in-module "Gst")
|
||||
(c-name "GstMessageType")
|
||||
(gtype-id "GST_TYPE_MESSAGE_TYPE")
|
||||
(values
|
||||
'("unknown" "GST_MESSAGE_UNKNOWN")
|
||||
'("eos" "GST_MESSAGE_EOS")
|
||||
'("error" "GST_MESSAGE_ERROR")
|
||||
'("warning" "GST_MESSAGE_WARNING")
|
||||
'("info" "GST_MESSAGE_INFO")
|
||||
'("tag" "GST_MESSAGE_TAG")
|
||||
'("buffering" "GST_MESSAGE_BUFFERING")
|
||||
'("state-changed" "GST_MESSAGE_STATE_CHANGED")
|
||||
'("step-done" "GST_MESSAGE_STEP_DONE")
|
||||
'("new-clock" "GST_MESSAGE_NEW_CLOCK")
|
||||
'("structure-change" "GST_MESSAGE_STRUCTURE_CHANGE")
|
||||
'("stream-status" "GST_MESSAGE_STREAM_STATUS")
|
||||
'("application" "GST_MESSAGE_APPLICATION")
|
||||
'("any" "GST_MESSAGE_ANY")
|
||||
)
|
||||
)
|
||||
|
||||
(define-flags MiniObjectFlags
|
||||
(in-module "Gst")
|
||||
(c-name "GstMiniObjectFlags")
|
||||
(gtype-id "GST_TYPE_MINI_OBJECT_FLAGS")
|
||||
(values
|
||||
'("readonly" "GST_MINI_OBJECT_FLAG_READONLY")
|
||||
'("static" "GST_MINI_OBJECT_FLAG_STATIC")
|
||||
'("last" "GST_MINI_OBJECT_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum ObjectFlags
|
||||
(in-module "Gst")
|
||||
(c-name "GstObjectFlags")
|
||||
(gtype-id "GST_TYPE_OBJECT_FLAGS")
|
||||
(values
|
||||
'("destroyed" "GST_DESTROYED")
|
||||
'("floating" "GST_FLOATING")
|
||||
'("object-flag-last" "GST_OBJECT_FLAG_LAST")
|
||||
'("disposing" "GST_OBJECT_DISPOSING")
|
||||
'("destroyed" "GST_OBJECT_DESTROYED")
|
||||
'("floating" "GST_OBJECT_FLOATING")
|
||||
'("flag-last" "GST_OBJECT_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -631,10 +631,39 @@
|
|||
(c-name "GstPadLinkReturn")
|
||||
(gtype-id "GST_TYPE_PAD_LINK_RETURN")
|
||||
(values
|
||||
'("nosched" "GST_PAD_LINK_NOSCHED")
|
||||
'("noformat" "GST_PAD_LINK_NOFORMAT")
|
||||
'("refused" "GST_PAD_LINK_REFUSED")
|
||||
'("delayed" "GST_PAD_LINK_DELAYED")
|
||||
'("wrong-direction" "GST_PAD_LINK_WRONG_DIRECTION")
|
||||
'("was-linked" "GST_PAD_LINK_WAS_LINKED")
|
||||
'("ok" "GST_PAD_LINK_OK")
|
||||
'("done" "GST_PAD_LINK_DONE")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum FlowReturn
|
||||
(in-module "Gst")
|
||||
(c-name "GstFlowReturn")
|
||||
(gtype-id "GST_TYPE_FLOW_RETURN")
|
||||
(values
|
||||
'("ok" "GST_FLOW_OK")
|
||||
'("resend" "GST_FLOW_RESEND")
|
||||
'("error" "GST_FLOW_ERROR")
|
||||
'("not-connected" "GST_FLOW_NOT_CONNECTED")
|
||||
'("not-negotiated" "GST_FLOW_NOT_NEGOTIATED")
|
||||
'("wrong-state" "GST_FLOW_WRONG_STATE")
|
||||
'("unexpected" "GST_FLOW_UNEXPECTED")
|
||||
'("not-supported" "GST_FLOW_NOT_SUPPORTED")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum ActivateMode
|
||||
(in-module "Gst")
|
||||
(c-name "GstActivateMode")
|
||||
(gtype-id "GST_TYPE_ACTIVATE_MODE")
|
||||
(values
|
||||
'("none" "GST_ACTIVATE_NONE")
|
||||
'("push" "GST_ACTIVATE_PUSH")
|
||||
'("pull" "GST_ACTIVATE_PULL")
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -654,8 +683,10 @@
|
|||
(c-name "GstPadFlags")
|
||||
(gtype-id "GST_TYPE_PAD_FLAGS")
|
||||
(values
|
||||
'("disabled" "GST_PAD_DISABLED")
|
||||
'("negotiating" "GST_PAD_NEGOTIATING")
|
||||
'("blocked" "GST_PAD_BLOCKED")
|
||||
'("flushing" "GST_PAD_FLUSHING")
|
||||
'("in-getcaps" "GST_PAD_IN_GETCAPS")
|
||||
'("in-setcaps" "GST_PAD_IN_SETCAPS")
|
||||
'("flag-last" "GST_PAD_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
@ -696,6 +727,16 @@
|
|||
)
|
||||
)
|
||||
|
||||
(define-enum PipelineFlags
|
||||
(in-module "Gst")
|
||||
(c-name "GstPipelineFlags")
|
||||
(gtype-id "GST_TYPE_PIPELINE_FLAGS")
|
||||
(values
|
||||
'("fixed-clock" "GST_PIPELINE_FLAG_FIXED_CLOCK")
|
||||
'("last" "GST_PIPELINE_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum PluginError
|
||||
(in-module "Gst")
|
||||
(c-name "GstPluginError")
|
||||
|
@ -720,6 +761,9 @@
|
|||
'("start" "GST_QUERY_START")
|
||||
'("segment-end" "GST_QUERY_SEGMENT_END")
|
||||
'("rate" "GST_QUERY_RATE")
|
||||
'("seeking" "GST_QUERY_SEEKING")
|
||||
'("convert" "GST_QUERY_CONVERT")
|
||||
'("formats" "GST_QUERY_FORMATS")
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -754,20 +798,7 @@
|
|||
(c-name "GstSchedulerFlags")
|
||||
(gtype-id "GST_TYPE_SCHEDULER_FLAGS")
|
||||
(values
|
||||
'("fixed-clock" "GST_SCHEDULER_FLAG_FIXED_CLOCK")
|
||||
'("last" "GST_SCHEDULER_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
(define-enum SchedulerState
|
||||
(in-module "Gst")
|
||||
(c-name "GstSchedulerState")
|
||||
(gtype-id "GST_TYPE_SCHEDULER_STATE")
|
||||
(values
|
||||
'("none" "GST_SCHEDULER_STATE_NONE")
|
||||
'("running" "GST_SCHEDULER_STATE_RUNNING")
|
||||
'("stopped" "GST_SCHEDULER_STATE_STOPPED")
|
||||
'("error" "GST_SCHEDULER_STATE_ERROR")
|
||||
'("t" "GST_SCHEDULER_FLAG_LAST")
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -800,15 +831,14 @@
|
|||
)
|
||||
)
|
||||
|
||||
(define-enum ThreadState
|
||||
(define-enum TaskState
|
||||
(in-module "Gst")
|
||||
(c-name "GstThreadState")
|
||||
(gtype-id "GST_TYPE_THREAD_STATE")
|
||||
(c-name "GstTaskState")
|
||||
(gtype-id "GST_TYPE_TASK_STATE")
|
||||
(values
|
||||
'("state-spinning" "GST_THREAD_STATE_SPINNING")
|
||||
'("state-reaping" "GST_THREAD_STATE_REAPING")
|
||||
'("mutex-locked" "GST_THREAD_MUTEX_LOCKED")
|
||||
'("flag-last" "GST_THREAD_FLAG_LAST")
|
||||
'("started" "GST_TASK_STARTED")
|
||||
'("stopped" "GST_TASK_STOPPED")
|
||||
'("paused" "GST_TASK_PAUSED")
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -859,14 +889,15 @@
|
|||
)
|
||||
)
|
||||
|
||||
(define-enum Result
|
||||
(define-enum Rank
|
||||
(in-module "Gst")
|
||||
(c-name "GstResult")
|
||||
(gtype-id "GST_TYPE_RESULT")
|
||||
(c-name "GstRank")
|
||||
(gtype-id "GST_TYPE_RANK")
|
||||
(values
|
||||
'("ok" "GST_RESULT_OK")
|
||||
'("nok" "GST_RESULT_NOK")
|
||||
'("not-impl" "GST_RESULT_NOT_IMPL")
|
||||
'("none" "GST_RANK_NONE")
|
||||
'("marginal" "GST_RANK_MARGINAL")
|
||||
'("secondary" "GST_RANK_SECONDARY")
|
||||
'("primary" "GST_RANK_PRIMARY")
|
||||
)
|
||||
)
|
||||
|
||||
|
|
4335
gst/gst.defs
4335
gst/gst.defs
File diff suppressed because it is too large
Load diff
289
gst/gst.override
289
gst/gst.override
|
@ -22,6 +22,10 @@
|
|||
*/
|
||||
%%
|
||||
headers
|
||||
/* define this for all source files that don't run init_pygobject()
|
||||
* before including pygobject.h */
|
||||
#define NO_IMPORT_PYGOBJECT
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
@ -36,7 +40,13 @@ headers
|
|||
#include <gst/gsttaginterface.h>
|
||||
#include <gst/gstprobe.h>
|
||||
|
||||
extern gboolean pygst_data_from_pyobject (PyObject *object, GstData **data);
|
||||
#include "pygstvalue.h"
|
||||
|
||||
/* These headers have been included directly to get around multiple
|
||||
* GetAttrString calls */
|
||||
#include <compile.h>
|
||||
#include <frameobject.h>
|
||||
|
||||
PyObject *PyGstExc_LinkError = NULL;
|
||||
|
||||
GSList *mainloops = NULL;
|
||||
|
@ -65,16 +75,161 @@ _pygst_main(void)
|
|||
g_main_loop_run (loop);
|
||||
}
|
||||
|
||||
/* This function checks if a former Python code threw an exception and if
|
||||
* so, transforms this exception into an error on the given GstElement.
|
||||
* This allows code run on the element to just raise an exception instead of
|
||||
* returning GStreamer specific return values.
|
||||
* The exception is cleared afterwards.
|
||||
*/
|
||||
gboolean
|
||||
_pygst_element_check_error (GstElement *element)
|
||||
{
|
||||
PyObject *type, *value, *traceback, *lineno, *msg, *typemsg;
|
||||
PyFrameObject *frame;
|
||||
|
||||
if (!PyErr_Occurred())
|
||||
return FALSE;
|
||||
|
||||
PyErr_Fetch (&type, &value, &traceback);
|
||||
if (traceback) {
|
||||
frame = (PyFrameObject *) PyObject_GetAttrString (traceback, "tb_frame");
|
||||
lineno = PyObject_GetAttrString (traceback, "tb_lineno");
|
||||
} else {
|
||||
frame = NULL;
|
||||
lineno = NULL;
|
||||
}
|
||||
msg = PyObject_Str (value);
|
||||
typemsg = PyObject_Str (type);
|
||||
if (msg && PyString_Check (msg)) {
|
||||
gst_element_error_full (element, GST_LIBRARY_ERROR,
|
||||
GST_LIBRARY_ERROR_FAILED,
|
||||
g_strdup (PyString_AsString (msg)),
|
||||
typemsg ? g_strconcat (PyString_AsString (typemsg),
|
||||
": ", PyString_AsString (msg), NULL)
|
||||
: g_strdup (PyString_AsString (msg)),
|
||||
frame ? PyString_AsString(frame->f_code->co_filename) : "???",
|
||||
frame ? PyString_AsString(frame->f_code->co_name) : "???",
|
||||
lineno ? PyInt_AsLong (lineno) : 0);
|
||||
} else {
|
||||
gst_element_error_full (element, GST_LIBRARY_ERROR,
|
||||
GST_LIBRARY_ERROR_TOO_LAZY,
|
||||
NULL, NULL,
|
||||
frame ? PyString_AsString(frame->f_code->co_filename) : "???",
|
||||
frame ? PyString_AsString(frame->f_code->co_name) : "???",
|
||||
lineno ? PyInt_AsLong (lineno) : 0);
|
||||
}
|
||||
|
||||
PyErr_Clear ();
|
||||
Py_XDECREF (frame);
|
||||
Py_XDECREF (lineno);
|
||||
Py_DECREF (msg);
|
||||
Py_DECREF (typemsg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef pyg_register_class_init
|
||||
PyTypeObject PyGstPadTemplate_Type;
|
||||
static int
|
||||
add_templates (gpointer gclass, PyObject *templates)
|
||||
{
|
||||
gint i, len;
|
||||
PyGObject *templ;
|
||||
|
||||
if (pygobject_check(templates, &PyGstPadTemplate_Type)) {
|
||||
gst_element_class_add_pad_template (gclass, GST_PAD_TEMPLATE (pygobject_get (templates)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!PyTuple_Check(templates)) {
|
||||
PyErr_SetString(PyExc_TypeError, "__gsttemplates__ attribute neither a tuple nor a GstPadTemplate!");
|
||||
return -1;
|
||||
}
|
||||
len = PyTuple_Size(templates);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
templ = (PyGObject*) PyTuple_GetItem(templates, i);
|
||||
if (!pygobject_check(templ, &PyGstPadTemplate_Type)) {
|
||||
PyErr_SetString(PyExc_TypeError, "entries for __gsttemplates__ must be of type GstPadTemplate");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
templ = (PyGObject*) PyTuple_GetItem(templates, i);
|
||||
gst_element_class_add_pad_template (gclass, GST_PAD_TEMPLATE (templ->obj));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_pygst_element_set_details (gpointer gclass, PyObject *details)
|
||||
{
|
||||
GstElementDetails gstdetails = { 0, };
|
||||
|
||||
if (!PyTuple_Check (details)) {
|
||||
PyErr_SetString(PyExc_TypeError, "__gstdetails__ must be a tuple");
|
||||
return -1;
|
||||
}
|
||||
if (PyTuple_Size (details) != 4) {
|
||||
PyErr_SetString(PyExc_TypeError, "__gstdetails__ must be contain 4 elements");
|
||||
return -1;
|
||||
}
|
||||
if (!PyArg_ParseTuple (details, "ssss", &gstdetails.longname, &gstdetails.klass,
|
||||
&gstdetails.description, &gstdetails.author)) {
|
||||
PyErr_SetString (PyExc_TypeError, "__gstdetails__ must be contain 4 strings");
|
||||
return -1;
|
||||
}
|
||||
gst_element_class_set_details (gclass, &gstdetails);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_pygst_element_init (gpointer gclass, PyTypeObject *pyclass)
|
||||
{
|
||||
PyObject *templates, *details;
|
||||
|
||||
templates = PyDict_GetItemString(pyclass->tp_dict, "__gsttemplates__");
|
||||
if (templates) {
|
||||
if (add_templates(gclass, templates) != 0)
|
||||
return -1;
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
details = PyDict_GetItemString(pyclass->tp_dict, "__gstdetails__");
|
||||
if (details) {
|
||||
if (_pygst_element_set_details (gclass, details) != 0)
|
||||
return -1;
|
||||
PyDict_DelItemString(pyclass->tp_dict, "__gstdetails__");
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
%%
|
||||
include
|
||||
gstbin.override
|
||||
gstbuffer.override
|
||||
gstcaps.override
|
||||
gstelement.override
|
||||
gstevent.override
|
||||
gstpad.override
|
||||
gststructure.override
|
||||
%%
|
||||
init
|
||||
{
|
||||
/* FIXME: new in pygtk-2.6 */
|
||||
#ifdef pyg_register_class_init
|
||||
pyg_register_class_init (GST_TYPE_ELEMENT, _pygst_element_init);
|
||||
#endif
|
||||
if (!pygst_value_init())
|
||||
return;
|
||||
}
|
||||
%%
|
||||
modulename gst
|
||||
%%
|
||||
|
@ -126,7 +281,7 @@ tag_foreach_func_dict (const GstTagList *list,
|
|||
|
||||
for (i = 0; i < count; i++) {
|
||||
gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(list), tag, i);
|
||||
value = pyg_value_as_pyobject(gvalue, TRUE);
|
||||
value = pygst_value_as_pyobject(gvalue, TRUE);
|
||||
key = g_strdup (tag);
|
||||
PyDict_SetItemString(dict, key, value);
|
||||
g_free (key);
|
||||
|
@ -184,7 +339,7 @@ _wrap_gst_tag_list_subscript(PyGObject *self, PyObject *py_key)
|
|||
} else if (count == 1) {
|
||||
const GValue *gvalue;
|
||||
gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
|
||||
v = pyg_value_as_pyobject(gvalue, TRUE);
|
||||
v = pygst_value_as_pyobject(gvalue, TRUE);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
|
||||
}
|
||||
|
@ -235,7 +390,7 @@ _wrap_gst_tag_list_get(PyGObject *self, PyObject *args)
|
|||
PyErr_SetString(PyExc_KeyError, key);
|
||||
} else if (count == 1) {
|
||||
gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
|
||||
val = pyg_value_as_pyobject(gvalue, TRUE);
|
||||
val = pygst_value_as_pyobject(gvalue, TRUE);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
|
||||
}
|
||||
|
@ -338,7 +493,73 @@ _wrap_gst_tag_list_get_value_index (PyGObject *self,
|
|||
tag,
|
||||
index);
|
||||
|
||||
return pyg_value_as_pyobject(gvalue, FALSE);
|
||||
return pygst_value_as_pyobject(gvalue, FALSE);
|
||||
}
|
||||
%%
|
||||
override-slot GstObject.tp_repr
|
||||
static PyObject *
|
||||
_wrap_gst_object_tp_repr(PyObject *self)
|
||||
{
|
||||
gchar *repr;
|
||||
PyObject *ret;
|
||||
GstObject *object = GST_OBJECT (pygobject_get (self));
|
||||
|
||||
repr = g_strdup_printf ("<%s object (%s) at 0x%lx>",
|
||||
self->ob_type->tp_name,
|
||||
GST_OBJECT_NAME(object) ? GST_OBJECT_NAME(object) : "unnamed",
|
||||
(long)self);
|
||||
ret = PyString_FromString(repr);
|
||||
g_free (repr);
|
||||
return ret;
|
||||
}
|
||||
%%
|
||||
override-slot GstObject.tp_str
|
||||
static PyObject *
|
||||
_wrap_gst_object_tp_str(PyObject *self)
|
||||
{
|
||||
gchar *repr, *path;
|
||||
PyObject *ret;
|
||||
GstObject *object = GST_OBJECT (pygobject_get (self));
|
||||
|
||||
path = gst_object_get_path_string (object);
|
||||
repr = g_strdup_printf ("%s (%s)",
|
||||
path, self->ob_type->tp_name);
|
||||
ret = PyString_FromString(repr);
|
||||
g_free (repr);
|
||||
g_free (path);
|
||||
return ret;
|
||||
}
|
||||
%%
|
||||
override-slot GstPluginFeature.tp_repr
|
||||
static PyObject *
|
||||
_wrap_gst_plugin_feature_tp_repr(PyObject *self)
|
||||
{
|
||||
gchar *repr;
|
||||
PyObject *ret;
|
||||
GstPluginFeature *feature = GST_PLUGIN_FEATURE (pygobject_get (self));
|
||||
|
||||
repr = g_strdup_printf ("<%s %s @ 0x%lx>",
|
||||
self->ob_type->tp_name, gst_plugin_feature_get_name (feature),
|
||||
(long) self);
|
||||
ret = PyString_FromString(repr);
|
||||
g_free (repr);
|
||||
return ret;
|
||||
}
|
||||
%%
|
||||
override-slot GstPluginFeature.tp_str
|
||||
static PyObject *
|
||||
_wrap_gst_plugin_feature_tp_str(PyObject *self)
|
||||
{
|
||||
gchar *repr;
|
||||
PyObject *ret;
|
||||
GstPluginFeature *feature = GST_PLUGIN_FEATURE (pygobject_get (self));
|
||||
|
||||
repr = g_strdup_printf ("<%s %s (%d)>",
|
||||
self->ob_type->tp_name, gst_plugin_feature_get_name (feature),
|
||||
gst_plugin_feature_get_rank (feature));
|
||||
ret = PyString_FromString(repr);
|
||||
g_free (repr);
|
||||
return ret;
|
||||
}
|
||||
%%
|
||||
override gst_type_find_factory_get_caps noargs
|
||||
|
@ -627,6 +848,7 @@ probe_handler_marshal(GstProbe *probe, GstData **data, gpointer user_data)
|
|||
PyGILState_STATE state;
|
||||
PyObject *callback, *args;
|
||||
PyObject *ret;
|
||||
PyObject *py_data;
|
||||
PyObject *py_user_data;
|
||||
gboolean res;
|
||||
gint len, i;
|
||||
|
@ -637,10 +859,17 @@ probe_handler_marshal(GstProbe *probe, GstData **data, gpointer user_data)
|
|||
|
||||
py_user_data = (PyObject *) user_data;
|
||||
|
||||
if (GST_IS_BUFFER(*data))
|
||||
py_data = pyg_boxed_new(GST_TYPE_BUFFER, *data, TRUE, TRUE);
|
||||
else if (GST_IS_EVENT(*data))
|
||||
py_data = pyg_boxed_new(GST_TYPE_EVENT, *data, TRUE, TRUE);
|
||||
else
|
||||
py_data = pyg_boxed_new(GST_TYPE_DATA, *data, TRUE, TRUE);
|
||||
|
||||
callback = PyTuple_GetItem(py_user_data, 0);
|
||||
args = Py_BuildValue("(NN)",
|
||||
pyg_boxed_new(GST_TYPE_PROBE, probe, TRUE, TRUE),
|
||||
pyg_boxed_new(GST_TYPE_DATA, *data, TRUE, TRUE));
|
||||
py_data);
|
||||
|
||||
len = PyTuple_Size(py_user_data);
|
||||
for (i = 1; i < len; ++i) {
|
||||
|
@ -657,6 +886,7 @@ probe_handler_marshal(GstProbe *probe, GstData **data, gpointer user_data)
|
|||
res = PyObject_IsTrue(ret);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
Py_DECREF(args);
|
||||
pyg_gil_state_release(state);
|
||||
|
||||
return res;
|
||||
|
@ -765,3 +995,50 @@ _wrap_gst_plugin_get_version(PyGObject *self)
|
|||
g_strfreev(items);
|
||||
return tuple;
|
||||
}
|
||||
%%
|
||||
override gst_element_register kwargs
|
||||
|
||||
static GstPlugin *
|
||||
_pygst_get_plugin(void)
|
||||
{
|
||||
PyObject *dict = NULL, *module = NULL, *pyplugin = NULL;
|
||||
GstPlugin *ret;
|
||||
|
||||
if (!(module = PyImport_ImportModule ("gst")))
|
||||
goto err;
|
||||
if (!(dict = PyModule_GetDict (module)))
|
||||
goto err;
|
||||
if (!(pyplugin = PyDict_GetItemString (dict, "__plugin__")))
|
||||
goto err;
|
||||
ret = pyg_boxed_get (pyplugin, GstPlugin);
|
||||
|
||||
Py_DECREF (module);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
Py_XDECREF (module);
|
||||
PyErr_Clear ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_wrap_gst_element_register(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "type", "elementname", "rank", NULL };
|
||||
PyObject *py_type = NULL;
|
||||
guint rank = GST_RANK_NONE;
|
||||
char *elementname = NULL;
|
||||
int ret;
|
||||
GType type;
|
||||
|
||||
/* FIXME: can we make the name optional, too? Anyone know a good default? */
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os|I:element_register", kwlist,
|
||||
&py_type, &elementname, &rank))
|
||||
return NULL;
|
||||
if ((type = pyg_type_from_object(py_type)) == 0)
|
||||
return NULL;
|
||||
|
||||
ret = gst_element_register(_pygst_get_plugin(), elementname, rank, type);
|
||||
return PyBool_FromLong(ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ headers
|
|||
static int gst_buffer_getreadbuffer (PyGObject *self,
|
||||
int index,
|
||||
const void **ptr);
|
||||
static int gst_buffer_length (PyGObject *self);
|
||||
static int gst_buffer_getwritebuf (PyGObject *self,
|
||||
int index,
|
||||
const void **ptr);
|
||||
|
@ -42,7 +41,7 @@ _wrap_gst_buffer_new(PyGBoxed *self, PyObject *args, PyObject *kwargs)
|
|||
{
|
||||
static char *kwlist[] = { "data", "buffer_size", NULL };
|
||||
char *data = NULL;
|
||||
int size;
|
||||
int size = 0;
|
||||
int buf_size = -1;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|z#i:GstBuffer.__init__", kwlist,
|
||||
|
@ -53,10 +52,16 @@ _wrap_gst_buffer_new(PyGBoxed *self, PyObject *args, PyObject *kwargs)
|
|||
PyErr_SetString(PyExc_TypeError, "buffer size must be >= 0");
|
||||
return -1;
|
||||
}
|
||||
if (buf_size < 0)
|
||||
buf_size = size;
|
||||
if (buf_size < size) {
|
||||
PyErr_SetString(PyExc_TypeError, "buffer size must be >= data size");
|
||||
return -1;
|
||||
}
|
||||
self->gtype = GST_TYPE_BUFFER;
|
||||
self->free_on_dealloc = FALSE;
|
||||
self->free_on_dealloc = TRUE;
|
||||
|
||||
self->boxed = gst_buffer_new_and_alloc(buf_size > size ? buf_size : size);
|
||||
self->boxed = gst_buffer_new_and_alloc(buf_size);
|
||||
|
||||
if (!self->boxed) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "could not create GstBuffer object");
|
||||
|
@ -77,7 +82,7 @@ static PyObject*
|
|||
_wrap_gst_buffer_get_data(PyObject *self)
|
||||
{
|
||||
GstBuffer *buf = pyg_boxed_get(self, GstBuffer);
|
||||
return PyString_FromStringAndSize(GST_BUFFER_DATA(buf),
|
||||
return PyString_FromStringAndSize((gchar *) GST_BUFFER_DATA(buf),
|
||||
GST_BUFFER_SIZE(buf));
|
||||
}
|
||||
%%
|
||||
|
@ -103,7 +108,7 @@ _wrap_gst_buffer_set_data(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
return NULL;
|
||||
}
|
||||
GST_BUFFER_SIZE(buf) = PyString_Size(data);
|
||||
GST_BUFFER_DATA(buf) = g_new0(char, GST_BUFFER_SIZE(buf));
|
||||
GST_BUFFER_DATA(buf) = (guint8 *) g_new0(char, GST_BUFFER_SIZE(buf));
|
||||
|
||||
memcpy(GST_BUFFER_DATA(buf),
|
||||
PyString_AsString(data),
|
||||
|
@ -174,12 +179,33 @@ _wrap_gst_buffer__set_timestamp(PyGBoxed *self, PyObject *value, void *closure)
|
|||
return 0;
|
||||
}
|
||||
%%
|
||||
override-attr GstBuffer.duration
|
||||
static PyObject *
|
||||
_wrap_gst_buffer__get_duration(PyGObject *self, void *closure)
|
||||
{
|
||||
return PyInt_FromLong(GST_BUFFER(self->obj)->duration);
|
||||
}
|
||||
static int
|
||||
_wrap_gst_buffer__set_duration(PyGBoxed *self, PyObject *value, void *closure)
|
||||
{
|
||||
gint val;
|
||||
|
||||
val = PyInt_AsLong(value);
|
||||
if (PyErr_Occurred())
|
||||
return -1;
|
||||
|
||||
pyg_boxed_get(self, GstBuffer)->duration = val;
|
||||
return 0;
|
||||
}
|
||||
%%
|
||||
override-slot GstBuffer.tp_str
|
||||
static PyObject *
|
||||
_wrap_gst_buffer_tp_str(PyGObject *self)
|
||||
{
|
||||
return PyString_FromStringAndSize(GST_BUFFER_DATA(self->obj),
|
||||
GST_BUFFER_SIZE(self->obj));
|
||||
GstBuffer *buf = pyg_boxed_get(self, GstBuffer);
|
||||
|
||||
return PyString_FromStringAndSize((const gchar*) GST_BUFFER_DATA(buf),
|
||||
(gint) GST_BUFFER_SIZE(buf));
|
||||
}
|
||||
%%
|
||||
override-slot GstBuffer.tp_as_buffer
|
||||
|
@ -193,64 +219,164 @@ static PyBufferProcs _wrap_gst_buffer_tp_as_buffer = {
|
|||
static int
|
||||
gst_buffer_getreadbuffer(PyGObject *self, int index, const void **ptr)
|
||||
{
|
||||
GstBuffer *buf = pyg_boxed_get(self, GstBuffer);
|
||||
|
||||
if ( index != 0 ) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"accessing non-existent GstBuffer segment");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ptr = GST_BUFFER_DATA(self->obj);
|
||||
return GST_BUFFER_SIZE(self->obj);
|
||||
*ptr = GST_BUFFER_DATA(buf);
|
||||
return GST_BUFFER_SIZE(buf);
|
||||
}
|
||||
|
||||
static int
|
||||
gst_buffer_getsegcount(PyGObject *self, int *lenp)
|
||||
{
|
||||
GstBuffer *buf = pyg_boxed_get(self, GstBuffer);
|
||||
|
||||
if (lenp)
|
||||
*lenp = GST_BUFFER_SIZE(self->obj);
|
||||
*lenp = GST_BUFFER_SIZE(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
gst_buffer_getcharbuf(PyGObject *self, int index, const char **ptr)
|
||||
{
|
||||
return gst_buffer_getreadbuffer (self, index, (const void **) ptr);
|
||||
}
|
||||
|
||||
static int
|
||||
gst_buffer_getwritebuf(PyGObject *self, int index, const void **ptr)
|
||||
{
|
||||
GstBuffer *buf = pyg_boxed_get(self, GstBuffer);
|
||||
|
||||
if ( index != 0 ) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"accessing non-existent GstBuffer segment");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ptr = GST_BUFFER_DATA(self->obj);
|
||||
return GST_BUFFER_SIZE(self->obj);
|
||||
}
|
||||
if (!gst_buffer_is_writable (buf)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"buffer is not writable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
gst_buffer_getwritebuf(PyGObject *self, int index, const void **ptr)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Cannot use GstBuffer as modifiable buffer");
|
||||
return -1;
|
||||
*ptr = GST_BUFFER_DATA(buf);
|
||||
return GST_BUFFER_SIZE(buf);
|
||||
}
|
||||
|
||||
%%
|
||||
override-slot GstBuffer.tp_as_sequence
|
||||
/* FIXME: should buffer parts be buffers or strings? */
|
||||
|
||||
static int
|
||||
pygst_buffer_length(PyObject *self)
|
||||
{
|
||||
return GST_BUFFER_SIZE(pygobject_get (self));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pygst_buffer_slice(PyObject *self, int start, int end)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (pygobject_get (self));
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end < 0)
|
||||
end = 0;
|
||||
if (end > GST_BUFFER_SIZE(buf))
|
||||
end = GST_BUFFER_SIZE(buf);
|
||||
|
||||
if (end <= start) {
|
||||
PyErr_SetString(PyExc_IndexError, "buffer index out of range");
|
||||
return NULL;
|
||||
}
|
||||
return PyString_FromStringAndSize((gchar *) GST_BUFFER_DATA (buf) + start, end - start);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pygst_buffer_item(PyObject *self, int index)
|
||||
{
|
||||
return pygst_buffer_slice (self, index, index + 1);
|
||||
}
|
||||
|
||||
static int
|
||||
pygst_buffer_ass_slice (PyObject *self, int start, int end, PyObject *val)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (pygobject_get (self));
|
||||
const void *data;
|
||||
int len;
|
||||
|
||||
if (!gst_buffer_is_writable (buf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "buffer is not writable");
|
||||
return -1;
|
||||
}
|
||||
/* FIXME: policy? */
|
||||
if (start < 0 || end <= start || end > GST_BUFFER_SIZE (buf)) {
|
||||
PyErr_SetString(PyExc_IndexError, "buffer index out of range");
|
||||
return -1;
|
||||
}
|
||||
end -= start;
|
||||
if (PyObject_AsReadBuffer(val, &data, &len))
|
||||
return -1;
|
||||
if (len > end)
|
||||
len = end;
|
||||
memcpy (GST_BUFFER_DATA (buf) + start, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pygst_buffer_ass_item (PyObject *self, int index, PyObject *val)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (pygobject_get (self));
|
||||
const void *data;
|
||||
int len;
|
||||
|
||||
if (!gst_buffer_is_writable (buf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "buffer is not writable");
|
||||
return -1;
|
||||
}
|
||||
if (index < 0 || index > GST_BUFFER_SIZE (buf)) {
|
||||
PyErr_SetString(PyExc_IndexError, "buffer index out of range");
|
||||
return -1;
|
||||
}
|
||||
if (PyObject_AsReadBuffer(val, &data, &len))
|
||||
return -1;
|
||||
/* FIXME: how do we handle this? */
|
||||
if (len > GST_BUFFER_SIZE (buf) - index)
|
||||
len = GST_BUFFER_SIZE (buf) - index;
|
||||
memcpy (GST_BUFFER_DATA (buf) + index, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PySequenceMethods _wrap_gst_buffer_tp_as_sequence = {
|
||||
(inquiry)gst_buffer_length, /* sq_length */
|
||||
pygst_buffer_length, /* sq_length */
|
||||
NULL, /* sq_concat */
|
||||
NULL, /* sq_repeat */
|
||||
NULL, /* sq_item */
|
||||
NULL, /* sq_slice */
|
||||
NULL, /* sq_ass_item */
|
||||
NULL, /* sq_ass_slice */
|
||||
pygst_buffer_item, /* sq_item */
|
||||
pygst_buffer_slice, /* sq_slice */
|
||||
pygst_buffer_ass_item, /* sq_ass_item */
|
||||
pygst_buffer_ass_slice, /* sq_ass_slice */
|
||||
NULL, /* sq_contains */
|
||||
NULL, /* sq_inplace_concat */
|
||||
NULL, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
static int
|
||||
gst_buffer_length(PyGObject *self)
|
||||
%%
|
||||
define GstBuffer.copy_on_write
|
||||
static PyObject *
|
||||
_wrap_gst_buffer_copy_on_write (PyObject *self)
|
||||
{
|
||||
return GST_BUFFER_SIZE(self->obj);
|
||||
GstBuffer *buf = pyg_boxed_get(self, GstBuffer);
|
||||
|
||||
if (gst_buffer_is_writable (buf)) {
|
||||
Py_INCREF (self);
|
||||
return self;
|
||||
}
|
||||
buf = gst_buffer_copy (buf);
|
||||
self = pyg_boxed_new (GST_TYPE_BUFFER, buf, FALSE, TRUE);
|
||||
return self;
|
||||
}
|
||||
|
||||
/* %%
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* -*- Mode: C; c-basic-offset: 4 -*- */
|
||||
/* gst-python
|
||||
* Copyright (C) 2005 Johan Dahlin
|
||||
* 2005 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -18,13 +19,78 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Johan Dahlin <johan@gnome.org>
|
||||
* Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
%%
|
||||
headers
|
||||
/* This is a (hopefully) smart hack to allow access to a caps'
|
||||
* structures without falling into traps when the caps get destroyed
|
||||
* before the structures get.
|
||||
* This Hash Table uses the structure PyObjects as keys and the caps
|
||||
* PyObjects as values. No clue if this is a fast data structure but it
|
||||
* probably doesn't matter anyway.
|
||||
*/
|
||||
static GHashTable *structure_caps_map = NULL;
|
||||
|
||||
static void
|
||||
pygst_caps_map_add (PyObject *structure, PyObject *caps)
|
||||
{
|
||||
/* we can't have free_on_dealloc stuff in here */
|
||||
g_assert (((PyGBoxed *)structure)->free_on_dealloc == FALSE);
|
||||
g_hash_table_insert (structure_caps_map, structure, caps);
|
||||
}
|
||||
|
||||
static void
|
||||
pygst_caps_map_remove_structure (PyObject *structure)
|
||||
{
|
||||
g_hash_table_remove (structure_caps_map, structure);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match)
|
||||
{
|
||||
PyGBoxed *boxed = structure;
|
||||
|
||||
if (match != caps)
|
||||
return FALSE;
|
||||
|
||||
/* we can't have free_on_dealloc stuff in here */
|
||||
g_assert (boxed->free_on_dealloc == FALSE);
|
||||
boxed->boxed = gst_structure_copy (boxed->boxed);
|
||||
boxed->free_on_dealloc = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pygst_caps_map_modified (PyObject *caps)
|
||||
{
|
||||
g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps);
|
||||
}
|
||||
|
||||
%%
|
||||
init
|
||||
structure_caps_map = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
%%
|
||||
ignore
|
||||
gst_caps_new_simple
|
||||
gst_caps_new_full
|
||||
gst_caps_set_simple
|
||||
%%
|
||||
override gst_caps_get_structure kwargs
|
||||
static PyObject *pygst_caps_sq_item(PyObject *self, int i);
|
||||
static PyObject *
|
||||
_wrap_gst_caps_get_structure(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "index", NULL };
|
||||
int index;
|
||||
|
||||
if (PyErr_Warn(PyExc_DeprecationWarning, "caps.get_structure(i) is deprecated, use caps[i]") < 0)
|
||||
return NULL;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:GstCaps.get_structure", kwlist, &index))
|
||||
return NULL;
|
||||
return pygst_caps_sq_item (self, index);
|
||||
}
|
||||
%%
|
||||
override gst_caps_new_empty kwargs
|
||||
static int
|
||||
_wrap_gst_caps_new_empty(PyGBoxed *self, PyObject *args, PyObject *kwargs)
|
||||
|
@ -40,89 +106,325 @@ _wrap_gst_caps_new_empty(PyGBoxed *self, PyObject *args, PyObject *kwargs)
|
|||
if (len == 0) {
|
||||
/* 0 length creates a new empty caps */
|
||||
self->boxed = gst_caps_new_empty();
|
||||
goto beach;
|
||||
} else if (len == 1) {
|
||||
/* 1 length is either a string or a structure */
|
||||
item = PyTuple_GetItem(args, 0);
|
||||
if (PyString_Check(item)) {
|
||||
self->boxed = gst_caps_from_string(PyString_AsString(item));
|
||||
goto beach;
|
||||
} else if (!pyg_boxed_check(item, GST_TYPE_STRUCTURE)) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument must be a string or a GstStructure");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* it's either one GstStructure or several whatevers */
|
||||
self->boxed = gst_caps_new_empty();
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
item = PyTuple_GetItem(args, i);
|
||||
if (!pyg_boxed_check(item, GST_TYPE_STRUCTURE))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "argument must be a GstStructure");
|
||||
gst_caps_free(self->boxed);
|
||||
return -1;
|
||||
/* 1 length is either a string or a structure */
|
||||
self->boxed = pygst_caps_from_pyobject (item, NULL);
|
||||
} else {
|
||||
/* it's multiple arguments that can all be made to caps */
|
||||
GstCaps *append;
|
||||
self->boxed = gst_caps_new_empty();
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
item = PyTuple_GetItem(args, i);
|
||||
append = pygst_caps_from_pyobject (item, NULL);
|
||||
if (!append) {
|
||||
gst_caps_free (self->boxed);
|
||||
self->boxed = NULL;
|
||||
break;
|
||||
}
|
||||
gst_caps_append (self->boxed, append);
|
||||
}
|
||||
gst_caps_append_structure(self->boxed, pyg_boxed_get(item, GstStructure));
|
||||
}
|
||||
|
||||
beach:
|
||||
if (!self->boxed) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "could not create GstCaps object");
|
||||
PyErr_SetString(PyExc_TypeError, "wrong arguemntes when creating GstCaps object");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
%%
|
||||
override gst_caps_get_structure kwargs
|
||||
static PyObject *
|
||||
_wrap_gst_caps_get_structure(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "index", NULL };
|
||||
int index;
|
||||
GstStructure *ret;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:GstCaps.get_structure", kwlist, &index))
|
||||
return NULL;
|
||||
ret = gst_caps_get_structure(pyg_boxed_get(self, GstCaps), index);
|
||||
|
||||
/* pyg_boxed_new handles NULL checking */
|
||||
return pyg_boxed_new(GST_TYPE_STRUCTURE, ret, FALSE, FALSE);
|
||||
%%
|
||||
override-slot GstCaps.tp_richcompare
|
||||
|
||||
static gboolean
|
||||
pygst_caps_is_true_subset (GstCaps *caps1, GstCaps *caps2)
|
||||
{
|
||||
GstCaps *tmp;
|
||||
gboolean ret;
|
||||
|
||||
/* order is important here */
|
||||
if (gst_caps_is_any (caps1))
|
||||
return FALSE;
|
||||
if (gst_caps_is_any (caps2))
|
||||
return TRUE;
|
||||
if (gst_caps_is_empty (caps2))
|
||||
return FALSE;
|
||||
if (gst_caps_is_empty (caps1))
|
||||
return TRUE;
|
||||
|
||||
tmp = gst_caps_subtract (caps1, caps2);
|
||||
ret = gst_caps_is_empty (tmp);
|
||||
gst_caps_free (tmp);
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
tmp = gst_caps_subtract (caps2, caps1);
|
||||
ret = gst_caps_is_empty (tmp);
|
||||
gst_caps_free (tmp);
|
||||
return !ret;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_wrap_gst_caps_tp_richcompare (PyObject *py_caps1, PyObject *py_caps2, int comparison)
|
||||
{
|
||||
GstCaps *caps1, *caps2;
|
||||
gboolean caps2_is_copy;
|
||||
PyObject *ret;
|
||||
|
||||
caps1 = pyg_boxed_get (py_caps1, GstCaps);
|
||||
caps2 = pygst_caps_from_pyobject (py_caps2, &caps2_is_copy);
|
||||
if (PyErr_Occurred()) {
|
||||
/* the second arg is not a caps */
|
||||
switch (comparison) {
|
||||
case Py_EQ:
|
||||
PyErr_Clear();
|
||||
ret = Py_False;
|
||||
Py_INCREF (ret);
|
||||
return ret;
|
||||
case Py_NE:
|
||||
PyErr_Clear();
|
||||
ret = Py_True;
|
||||
Py_INCREF (ret);
|
||||
return ret;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (comparison) {
|
||||
case Py_LT:
|
||||
ret = pygst_caps_is_true_subset (caps1, caps2) ? Py_True : Py_False;
|
||||
break;
|
||||
case Py_LE:
|
||||
ret = gst_caps_is_subset (caps1, caps2) ? Py_True : Py_False;
|
||||
break;
|
||||
case Py_NE:
|
||||
ret = gst_caps_is_equal (caps1, caps2) ? Py_False : Py_True;
|
||||
break;
|
||||
case Py_EQ:
|
||||
ret = gst_caps_is_equal (caps1, caps2) ? Py_True : Py_False;
|
||||
break;
|
||||
case Py_GE:
|
||||
ret = gst_caps_is_subset (caps2, caps1) ? Py_True : Py_False;
|
||||
break;
|
||||
case Py_GT:
|
||||
ret = pygst_caps_is_true_subset (caps2, caps1) ? Py_True : Py_False;
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString (PyExc_RuntimeError, "invalid comparison operation");
|
||||
if (caps2 && caps2_is_copy)
|
||||
gst_caps_free (caps2);
|
||||
return NULL;
|
||||
}
|
||||
if (caps2 && caps2_is_copy)
|
||||
gst_caps_free (caps2);
|
||||
|
||||
Py_INCREF (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
%%
|
||||
override-slot GstCaps.tp_as_number
|
||||
|
||||
/* In this number code, we mimic the Python set.Set datatype.
|
||||
* The same operations are supported. If you want to have an operation
|
||||
* supported for caps, add it to Python's Set type first.
|
||||
*/
|
||||
#define BINARY_FUNC(name,func) \
|
||||
static PyObject * \
|
||||
name (PyObject *py_caps1, PyObject *py_caps2) \
|
||||
{ \
|
||||
GstCaps *caps1, *caps2, *ret; \
|
||||
gboolean caps2_is_copy; \
|
||||
\
|
||||
caps1 = pyg_boxed_get (py_caps1, GstCaps); \
|
||||
caps2 = pygst_caps_from_pyobject (py_caps2, &caps2_is_copy); \
|
||||
if (PyErr_Occurred()) \
|
||||
return NULL; \
|
||||
ret = func (caps1, caps2); \
|
||||
if (caps2 && caps2_is_copy) \
|
||||
gst_caps_free (caps2); \
|
||||
return pyg_boxed_new (GST_TYPE_CAPS, ret, FALSE, TRUE); \
|
||||
}
|
||||
|
||||
BINARY_FUNC (pygst_caps_nb_subtract, gst_caps_subtract)
|
||||
BINARY_FUNC (pygst_caps_nb_and, gst_caps_intersect)
|
||||
BINARY_FUNC (pygst_caps_nb_or, gst_caps_union)
|
||||
static GstCaps *
|
||||
pygst_caps_xor (const GstCaps *caps1, const GstCaps *caps2)
|
||||
{
|
||||
GstCaps *intersect, *_union, *ret;
|
||||
intersect = gst_caps_intersect (caps1, caps2);
|
||||
_union = gst_caps_union (caps1, caps2);
|
||||
ret = gst_caps_subtract (_union, intersect);
|
||||
gst_caps_free (_union);
|
||||
gst_caps_free (intersect);
|
||||
gst_caps_do_simplify (ret);
|
||||
return ret;
|
||||
}
|
||||
BINARY_FUNC (pygst_caps_nb_xor, pygst_caps_xor)
|
||||
|
||||
static int
|
||||
pygst_caps_nb_nonzero (PyObject *py_caps)
|
||||
{
|
||||
GstCaps *caps = pyg_boxed_get (py_caps, GstCaps);
|
||||
|
||||
if (gst_caps_is_empty (caps))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pygst_caps_nb_coerce (PyObject **py_caps1, PyObject **py_caps2)
|
||||
{
|
||||
GstCaps *caps1, *caps2 = NULL;
|
||||
gboolean caps1_is_copy, caps2_is_copy;
|
||||
|
||||
caps1 = pygst_caps_from_pyobject (*py_caps1, &caps1_is_copy);
|
||||
if (!caps1)
|
||||
goto error;
|
||||
caps2 = pygst_caps_from_pyobject (*py_caps2, &caps2_is_copy);
|
||||
if (!caps2)
|
||||
goto error;
|
||||
/* if they're not copies, they're caps already */
|
||||
if (caps1_is_copy)
|
||||
*py_caps1 = pyg_boxed_new (GST_TYPE_CAPS, caps1, FALSE, TRUE);
|
||||
else
|
||||
Py_INCREF (*py_caps1);
|
||||
if (caps2_is_copy)
|
||||
*py_caps2 = pyg_boxed_new (GST_TYPE_CAPS, caps2, FALSE, TRUE);
|
||||
else
|
||||
Py_INCREF (*py_caps2);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
g_assert (PyErr_Occurred ());
|
||||
PyErr_Clear ();
|
||||
if (caps1 && !caps1_is_copy)
|
||||
gst_caps_free (caps1);
|
||||
if (caps2 && !caps2_is_copy)
|
||||
gst_caps_free (caps2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static PyNumberMethods _wrap_gst_caps_tp_as_number = {
|
||||
0, /* nb_add */
|
||||
pygst_caps_nb_subtract, /* nb_subtract */
|
||||
0, /* nb_multiply */
|
||||
0, /* nb_divide */
|
||||
0, /* nb_remainder */
|
||||
0, /* nb_divmod */
|
||||
0, /* nb_power */
|
||||
0, /* nb_negative */
|
||||
0, /* nb_positive */
|
||||
0, /* nb_absolute */
|
||||
pygst_caps_nb_nonzero, /* nb_nonzero */
|
||||
0, /* nb_invert */
|
||||
0, /* nb_lshift */
|
||||
0, /* nb_rshift */
|
||||
pygst_caps_nb_and, /* nb_and */
|
||||
pygst_caps_nb_xor, /* nb_xor */
|
||||
pygst_caps_nb_or, /* nb_or */
|
||||
pygst_caps_nb_coerce, /* nb_coerce */
|
||||
0, /* nb_int */
|
||||
0, /* nb_long */
|
||||
0, /* nb_float */
|
||||
0, /* nb_oct */
|
||||
0, /* nb_hex */
|
||||
0, /* nb_inplace_add */
|
||||
0, /* nb_inplace_subtract */
|
||||
0, /* nb_inplace_multiply */
|
||||
0, /* nb_inplace_divide */
|
||||
0, /* nb_inplace_remainder */
|
||||
0, /* nb_inplace_power */
|
||||
0, /* nb_inplace_lshift */
|
||||
0, /* nb_inplace_rshift */
|
||||
0, /* nb_inplace_and */
|
||||
0, /* nb_inplace_xor */
|
||||
0, /* nb_inplace_or */
|
||||
0, /* nb_floor_divide */
|
||||
0, /* nb_true_divide */
|
||||
0, /* nb_inplace_floor_divide */
|
||||
0, /* nb_inplace_true_divide */
|
||||
};
|
||||
%%
|
||||
override-slot GstCaps.tp_as_sequence
|
||||
static int
|
||||
caps_length(PyGObject *self)
|
||||
pygst_caps_sq_length(PyObject *self)
|
||||
{
|
||||
return gst_caps_get_size((GstCaps*)self->obj);
|
||||
GstCaps *caps = pyg_boxed_get (self, GstCaps);
|
||||
return gst_caps_get_size(caps);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
caps_item(PyGObject *self, int i)
|
||||
|
||||
pygst_caps_sq_item(PyObject *self, int i)
|
||||
{
|
||||
GstCaps *caps = pyg_boxed_get (self, GstCaps);
|
||||
GstStructure *structure;
|
||||
PyObject *ret;
|
||||
|
||||
if (i < 0 || i >= gst_caps_get_size((GstCaps*)self->obj)) {
|
||||
if (i < 0 || i >= gst_caps_get_size(caps)) {
|
||||
PyErr_SetString(PyExc_IndexError, "list index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
structure = gst_caps_get_structure((GstCaps*)self->obj, i);
|
||||
return pyg_boxed_new(GST_TYPE_STRUCTURE, structure, TRUE, TRUE);
|
||||
structure = gst_caps_get_structure(caps, i);
|
||||
|
||||
/* pyg_boxed_new handles NULL checking */
|
||||
ret = pyg_boxed_new(GST_TYPE_STRUCTURE,
|
||||
gst_caps_get_structure(pyg_boxed_get(self, GstCaps), i),
|
||||
FALSE, FALSE);
|
||||
if (ret)
|
||||
pygst_caps_map_add (ret, self);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* FIXME: This syntax sucks */
|
||||
static PyObject *
|
||||
pygst_caps_sq_slice(PyObject *self, int start, int end)
|
||||
{
|
||||
GstCaps *caps = pyg_boxed_get (self, GstCaps);
|
||||
GstCaps *ret = gst_caps_new_empty ();
|
||||
int i;
|
||||
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end > gst_caps_get_size (caps))
|
||||
end = gst_caps_get_size (caps);
|
||||
|
||||
for (i = start; i < end; i++)
|
||||
gst_caps_append_structure (ret, gst_structure_copy (gst_caps_get_structure (caps, i)));
|
||||
|
||||
return pyg_boxed_new(GST_TYPE_CAPS, ret, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static PySequenceMethods _wrap_gst_caps_tp_as_sequence = {
|
||||
(inquiry)caps_length, /* mp_length */
|
||||
NULL,
|
||||
NULL,
|
||||
(intargfunc)caps_item,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
pygst_caps_sq_length,
|
||||
NULL, /* not allowed for sets, use | instead of + */
|
||||
NULL, /* doesn't make sense, because it'd still be the same */
|
||||
pygst_caps_sq_item,
|
||||
pygst_caps_sq_slice,
|
||||
NULL, /* doesn't make sense, you can only append */
|
||||
NULL, /* doesn't make sense, you can only append */
|
||||
NULL, /* doesn't make sense really, unless you use is_subset */
|
||||
NULL, /* not allowed for sets, use | instead of + */
|
||||
NULL /* doesn't make sense, because it'd still be the same */
|
||||
};
|
||||
%%
|
||||
override-slot GstCaps.tp_dealloc
|
||||
static void
|
||||
_wrap_gst_caps_tp_dealloc (PyObject *self)
|
||||
{
|
||||
PyGBoxed *boxed = (PyGBoxed *) self;
|
||||
|
||||
if (boxed->free_on_dealloc && boxed->boxed) {
|
||||
pygst_caps_map_modified (self);
|
||||
gst_caps_free (boxed->boxed);
|
||||
}
|
||||
|
||||
self->ob_type->tp_free((PyObject *)self);
|
||||
}
|
||||
%%
|
||||
override-slot GstCaps.tp_str
|
||||
static PyObject *
|
||||
_wrap_gst_caps_tp_str(PyGObject *self)
|
||||
|
|
|
@ -188,14 +188,23 @@ override gst_element_link kwargs
|
|||
static PyObject *
|
||||
_wrap_gst_element_link(PyGObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "dest", NULL };
|
||||
static char *kwlist[] = { "dest", "filtercaps", NULL };
|
||||
PyGObject *dest;
|
||||
PyObject *py_caps = NULL;
|
||||
int ret;
|
||||
GstCaps *caps = NULL;
|
||||
gboolean caps_is_copy;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:GstElement.link",
|
||||
kwlist, &PyGstElement_Type, &dest))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O:GstElement.link",
|
||||
kwlist, &PyGstElement_Type, &dest, &py_caps))
|
||||
return NULL;
|
||||
ret = gst_element_link(GST_ELEMENT(self->obj), GST_ELEMENT(dest->obj));
|
||||
if (py_caps == NULL)
|
||||
caps = NULL;
|
||||
else
|
||||
caps = pygst_caps_from_pyobject (py_caps, &caps_is_copy);
|
||||
ret = gst_element_link_filtered(GST_ELEMENT(self->obj), GST_ELEMENT(dest->obj), caps);
|
||||
if (caps && caps_is_copy)
|
||||
gst_caps_free (caps);
|
||||
if (!ret) {
|
||||
PyErr_Format(PyGstExc_LinkError,
|
||||
"failed to link %s with %s",
|
||||
|
@ -212,52 +221,47 @@ static PyObject *
|
|||
_wrap_gst_element_link_filtered(PyGObject *self, PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "dest", "filtercaps", NULL };
|
||||
PyGObject *dest;
|
||||
PyObject *py_filtercaps;
|
||||
int ret;
|
||||
GstCaps *filtercaps = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O!O:GstElement.link_filtered",
|
||||
kwlist, &PyGstElement_Type,
|
||||
&dest, &py_filtercaps))
|
||||
return NULL;
|
||||
if (pyg_boxed_check(py_filtercaps, GST_TYPE_CAPS))
|
||||
filtercaps = pyg_boxed_get(py_filtercaps, GstCaps);
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "filtercaps should be a GstCaps");
|
||||
return NULL;
|
||||
}
|
||||
ret = gst_element_link_filtered(GST_ELEMENT(self->obj),
|
||||
GST_ELEMENT(dest->obj),
|
||||
filtercaps);
|
||||
if (!ret) {
|
||||
PyErr_Format(PyGstExc_LinkError,
|
||||
"failed to link %s with %s",
|
||||
GST_ELEMENT_NAME(self->obj),
|
||||
GST_ELEMENT_NAME(dest->obj));
|
||||
return NULL;
|
||||
}
|
||||
return PyBool_FromLong(ret);
|
||||
|
||||
if (PyErr_Warn(PyExc_DeprecationWarning, "element.link_filtered is deprecated, use element.link") < 0)
|
||||
return NULL;
|
||||
return _wrap_gst_element_link (self, args, kwargs);
|
||||
}
|
||||
|
||||
%%
|
||||
override gst_element_link_pads kwargs
|
||||
static gboolean
|
||||
pad_name_from_object (PyObject *object, const gchar **name)
|
||||
{
|
||||
if (object == Py_None) {
|
||||
*name = NULL;
|
||||
return TRUE;
|
||||
} else if (PyString_Check (object)) {
|
||||
*name = PyString_AsString (object);
|
||||
return TRUE;
|
||||
} else if (pygobject_check (object, &PyGstPad_Type)) {
|
||||
*name = gst_object_get_name (GST_OBJECT (pygobject_get (object)));
|
||||
return TRUE;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "argument could not be converted to a pad");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_wrap_gst_element_link_pads(PyGObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "srcpadname", "dest", "destpadname", NULL };
|
||||
char *srcpadname, *destpadname;
|
||||
const char *srcpadname, *destpadname;
|
||||
PyGObject *dest;
|
||||
PyObject *srcpad, *destpad;
|
||||
int ret;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"sO!s:GstElement.link_pads", kwlist,
|
||||
&srcpadname, &PyGstElement_Type, &dest,
|
||||
&destpadname))
|
||||
"OO!O:GstElement.link_pads", kwlist,
|
||||
&srcpad, &PyGstElement_Type, &dest,
|
||||
&destpad))
|
||||
return NULL;
|
||||
if (!pad_name_from_object (srcpad, &srcpadname) ||
|
||||
!pad_name_from_object (destpad, &destpadname))
|
||||
return NULL;
|
||||
ret = gst_element_link_pads(GST_ELEMENT(self->obj), srcpadname,
|
||||
GST_ELEMENT(dest->obj), destpadname);
|
||||
if (!ret) {
|
||||
|
@ -374,3 +378,19 @@ _wrap_gst_element_send_event(PyGObject *self, PyObject *args, PyObject *kwargs)
|
|||
return PyBool_FromLong(ret);
|
||||
|
||||
}
|
||||
%%
|
||||
override gst_element_factory_get_pad_templates
|
||||
static PyObject *
|
||||
_wrap_gst_element_factory_get_pad_templates(PyGObject *self)
|
||||
{
|
||||
const GList *pads;
|
||||
PyObject *list;
|
||||
|
||||
pads = gst_element_factory_get_pad_templates(GST_ELEMENT_FACTORY(self->obj));
|
||||
|
||||
list = PyList_New(0);
|
||||
for (; pads; pads = g_list_next (pads))
|
||||
PyList_Append(list, pygobject_new(pads->data));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
49
gst/gstevent.override
Normal file
49
gst/gstevent.override
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* -*- Mode: C; ; c-file-style: "python" -*- */
|
||||
/* gst-python
|
||||
* Copyright (C) 2005 Edward Hervey
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Johan Dahlin <johan@gnome.org>
|
||||
*/
|
||||
%%
|
||||
override-attr GstEvent.data_type
|
||||
static PyObject*
|
||||
_wrap_gst_event__get_data_type(PyGObject *self, void *closure)
|
||||
{
|
||||
return pyg_type_wrapper_new(GST_DATA_TYPE(GST_DATA(self->obj)));
|
||||
}
|
||||
%%
|
||||
override-attr GstEvent.flags
|
||||
static PyObject*
|
||||
_wrap_gst_event__get_flags(PyGObject *self, void *closure)
|
||||
{
|
||||
return PyInt_FromLong(GST_DATA_FLAGS(self->obj));
|
||||
}
|
||||
%%
|
||||
override-attr GstEvent.type
|
||||
static PyObject*
|
||||
_wrap_gst_event__get_type(PyGObject *self, void *closure)
|
||||
{
|
||||
return pyg_enum_from_gtype(GST_TYPE_EVENT_TYPE, GST_EVENT_TYPE(GST_EVENT(self->obj)));
|
||||
}
|
||||
%%
|
||||
override-attr GstEvent.timestamp
|
||||
static PyObject *
|
||||
_wrap_gst_event__get_timestamp(PyGObject *self, void *closure)
|
||||
{
|
||||
return PyInt_FromLong(GST_EVENT(self->obj)->timestamp);
|
||||
}
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
void pygst_register_classes (PyObject *d);
|
||||
void pygst_add_constants(PyObject *module, const gchar *strip_prefix);
|
||||
void _pygst_register_boxed_types(PyObject *moddict);
|
||||
|
||||
extern PyMethodDef pygst_functions[];
|
||||
extern GSList *mainloops;
|
||||
|
@ -114,6 +115,7 @@ init_gst (void)
|
|||
g_free (argv);
|
||||
}
|
||||
|
||||
_pygst_register_boxed_types (NULL);
|
||||
pygobject_register_sinkfunc(GST_TYPE_OBJECT, sink_gstobject);
|
||||
|
||||
m = Py_InitModule ("_gst", pygst_functions);
|
||||
|
|
|
@ -22,66 +22,169 @@
|
|||
%%
|
||||
headers
|
||||
|
||||
/* we need to do this until PyClosures get exception handlers */
|
||||
#ifndef pyg_closure_set_exception_handler
|
||||
# define pyg_closure_set_exception_handler(ig, nore)
|
||||
# define EXCEPTION_HANDLER G_GNUC_UNUSED
|
||||
#else
|
||||
# define EXCEPTION_HANDLER
|
||||
#endif
|
||||
#define SET_PAD_CLOSURE(self, args, kwargs, name) \
|
||||
static char *kwlist[] = { G_STRINGIFY (name), NULL }; \
|
||||
PyObject *function; \
|
||||
GstPad *pad; \
|
||||
GClosure *closure; \
|
||||
PyGstPadPrivate *priv; \
|
||||
\
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, \
|
||||
"O:GstPad.set_" G_STRINGIFY (name), \
|
||||
kwlist, \
|
||||
&function)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
if (!PyCallable_Check(function)) { \
|
||||
PyErr_SetString(PyExc_TypeError, G_STRINGIFY (name) " not callable"); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
closure = pyg_closure_new (function, NULL, NULL); \
|
||||
pyg_closure_set_exception_handler (closure, handle_ ## name ## _exception); \
|
||||
pygobject_watch_closure((PyObject *)self, closure); \
|
||||
priv = py_pad_private(self);\
|
||||
if (priv->name) { \
|
||||
g_closure_invalidate (priv->name); \
|
||||
g_closure_unref (priv->name); \
|
||||
} \
|
||||
priv->name = closure; \
|
||||
pad = (GstPad*)pygobject_get(self); \
|
||||
gst_pad_set_ ## name (pad, call_ ## name); \
|
||||
\
|
||||
Py_INCREF(Py_None); \
|
||||
return Py_None;
|
||||
|
||||
static void
|
||||
free_pad_private (gpointer data)
|
||||
{
|
||||
PyGstPadPrivate *private = data;
|
||||
#define INVALIDATE_CLOSURE(closure) \
|
||||
if (closure) { \
|
||||
g_closure_invalidate (closure); \
|
||||
g_closure_unref (closure); \
|
||||
closure = NULL; \
|
||||
}
|
||||
INVALIDATE_CLOSURE (private->link_function)
|
||||
INVALIDATE_CLOSURE (private->event_function)
|
||||
INVALIDATE_CLOSURE (private->chain_function)
|
||||
INVALIDATE_CLOSURE (private->get_function)
|
||||
INVALIDATE_CLOSURE (private->getcaps_function)
|
||||
#undef INVALIDATE_CLOSURE
|
||||
}
|
||||
|
||||
static PyGstPadPrivate*
|
||||
pad_private(GstPad *pad)
|
||||
{
|
||||
return (PyGstPadPrivate*)gst_pad_get_element_private(pad);
|
||||
PyGstPadPrivate *private;
|
||||
static GQuark padprivate = 0;
|
||||
|
||||
if (!padprivate)
|
||||
padprivate = g_quark_from_static_string ("PyGst::PadPrivate");
|
||||
private = g_object_get_qdata (G_OBJECT (pad), padprivate);
|
||||
if (private == NULL) {
|
||||
private = g_new0(PyGstPadPrivate, 1);
|
||||
private->pad = (PyGObject *) pygobject_new (G_OBJECT (pad));
|
||||
Py_DECREF (private->pad);
|
||||
g_object_set_qdata_full (G_OBJECT (pad), padprivate, private, free_pad_private);
|
||||
}
|
||||
return private;
|
||||
}
|
||||
|
||||
static PyGstPadPrivate*
|
||||
py_pad_private(PyGObject *pad)
|
||||
{
|
||||
PyGstPadPrivate *private;
|
||||
GstPad *gpad;
|
||||
|
||||
gpad = (GstPad*)pygobject_get(pad);
|
||||
private = (PyGstPadPrivate*)gst_pad_get_element_private(gpad);
|
||||
if (private == NULL) {
|
||||
/* FIXME need to free this somewhere */
|
||||
private = g_new0(PyGstPadPrivate, 1);
|
||||
Py_INCREF(pad);
|
||||
private->pad = pad;
|
||||
gst_pad_set_element_private(gpad, private);
|
||||
}
|
||||
return private;
|
||||
return pad_private ((GstPad *)pygobject_get(pad));
|
||||
}
|
||||
|
||||
%%
|
||||
ignore
|
||||
gst_pad_select
|
||||
gst_pad_selectv
|
||||
gst_pad_new_from_template
|
||||
gst_pad_load_and_link
|
||||
%%
|
||||
override gst_pad_set_getcaps_function kwargs
|
||||
|
||||
static void EXCEPTION_HANDLER
|
||||
handle_getcaps_function_exception (GValue *ret, guint n, const GValue *params)
|
||||
{
|
||||
g_value_set_boxed (ret, gst_pad_get_pad_template_caps (
|
||||
GST_PAD (g_value_get_object (¶ms[0]))));
|
||||
PyErr_Clear ();
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
call_getcaps_function (GstPad *pad)
|
||||
{
|
||||
GClosure *closure;
|
||||
GValue ret = { 0, };
|
||||
GValue args = { 0, };
|
||||
GstCaps *caps;
|
||||
|
||||
g_value_init (&ret, GST_TYPE_CAPS);
|
||||
g_value_init (&args, GST_TYPE_REAL_PAD);
|
||||
g_value_set_object (&args, pad);
|
||||
|
||||
closure = pad_private(pad)->getcaps_function;
|
||||
|
||||
g_closure_invoke (closure, &ret, 1, &args, NULL);
|
||||
|
||||
caps = g_value_dup_boxed (&ret);
|
||||
g_value_unset (&ret);
|
||||
g_value_unset (&args);
|
||||
return caps;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_pad_set_getcaps_function (PyGObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
SET_PAD_CLOSURE (self, args, kwargs, getcaps_function)
|
||||
}
|
||||
|
||||
%%
|
||||
override gst_pad_set_link_function kwargs
|
||||
|
||||
static GstPadLinkReturn
|
||||
call_link_function (GstPad *pad, GstCaps *caps)
|
||||
static void EXCEPTION_HANDLER
|
||||
handle_link_function_exception (GValue *ret, guint n, const GValue *params)
|
||||
{
|
||||
PyObject *function;
|
||||
PyObject *retval;
|
||||
GstPadLinkReturn ret;
|
||||
PyGILState_STATE state;
|
||||
g_value_set_enum (ret, GST_PAD_LINK_REFUSED);
|
||||
PyErr_Clear ();
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
call_link_function (GstPad *pad, const GstCaps *caps)
|
||||
{
|
||||
GClosure *closure;
|
||||
GValue ret = { 0, };
|
||||
GValue args[2] = { { 0, }, {0, } };
|
||||
GstPadLinkReturn i;
|
||||
|
||||
function = pad_private(pad)->link_function;
|
||||
g_value_init (&ret, GST_TYPE_PAD_LINK_RETURN);
|
||||
g_value_init (&args[0], GST_TYPE_REAL_PAD);
|
||||
g_value_init (&args[1], GST_TYPE_CAPS);
|
||||
g_value_set_object (&args[0], pad);
|
||||
g_value_set_boxed (&args[1], caps);
|
||||
|
||||
state = pyg_gil_state_ensure();
|
||||
closure = pad_private(pad)->link_function;
|
||||
|
||||
g_closure_invoke (closure, &ret, 2, args, NULL);
|
||||
|
||||
retval = (PyObject*)PyObject_CallFunction (function,
|
||||
"OO",
|
||||
pad_private(pad)->pad,
|
||||
pyg_boxed_new(GST_TYPE_CAPS, caps, TRUE, TRUE));
|
||||
|
||||
if (PyErr_Occurred ()) {
|
||||
PyErr_Print ();
|
||||
pyg_gil_state_release(state);
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
}
|
||||
|
||||
ret = PyInt_AsLong(retval);
|
||||
|
||||
pyg_gil_state_release(state);
|
||||
|
||||
return ret;
|
||||
i = g_value_get_enum (&ret);
|
||||
g_value_unset (&ret);
|
||||
g_value_unset (&args[0]);
|
||||
g_value_unset (&args[1]);
|
||||
return i;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
@ -89,55 +192,43 @@ _wrap_gst_pad_set_link_function (PyGObject *self,
|
|||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "link_function", NULL };
|
||||
PyObject *link_function;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.set_link_funcion",
|
||||
kwlist,
|
||||
&link_function)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(link_function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "link_function not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(link_function);
|
||||
py_pad_private(self)->link_function = link_function;
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
gst_pad_set_link_function(pad, (GstPadLinkFunction)call_link_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
SET_PAD_CLOSURE (self, args, kwargs, link_function)
|
||||
}
|
||||
|
||||
%%
|
||||
override gst_pad_set_chain_function kwargs
|
||||
|
||||
static void
|
||||
call_chain_function(GstPad *pad, GstBuffer *buf)
|
||||
static void EXCEPTION_HANDLER
|
||||
handle_chain_function_exception (GValue *ret, guint n, const GValue *params)
|
||||
{
|
||||
PyObject *function;
|
||||
PyGILState_STATE state;
|
||||
GstElement *element = gst_pad_get_parent (g_value_get_object (¶ms[0]));
|
||||
|
||||
if (!_pygst_element_check_error (element))
|
||||
g_assert_not_reached (); /* only returns FALSE when there's no error */
|
||||
}
|
||||
|
||||
function = pad_private(pad)->chain_function;
|
||||
|
||||
state = pyg_gil_state_ensure();
|
||||
|
||||
PyObject_CallFunction (function,
|
||||
"OO",
|
||||
pad_private(pad)->pad,
|
||||
pyg_boxed_new(GST_TYPE_BUFFER, buf, TRUE, TRUE));
|
||||
|
||||
if (PyErr_Occurred ()) {
|
||||
PyErr_Print ();
|
||||
pyg_gil_state_release(state);
|
||||
return;
|
||||
static void
|
||||
call_chain_function(GstPad *pad, GstData *data)
|
||||
{
|
||||
GClosure *closure;
|
||||
GValue args[2] = { { 0, }, { 0, } };
|
||||
|
||||
g_value_init (&args[0], GST_TYPE_REAL_PAD);
|
||||
if (GST_IS_BUFFER (data)) {
|
||||
g_value_init (&args[1], GST_TYPE_BUFFER);
|
||||
} else if (GST_IS_EVENT (data)) {
|
||||
g_value_init (&args[1], GST_TYPE_EVENT);
|
||||
} else {
|
||||
g_value_init (&args[1], GST_TYPE_DATA);
|
||||
}
|
||||
g_value_set_object (&args[0], pad);
|
||||
g_value_take_boxed (&args[1], data);
|
||||
closure = pad_private(pad)->chain_function;
|
||||
|
||||
g_closure_invoke (closure, NULL, 2, args, NULL);
|
||||
|
||||
pyg_gil_state_release(state);
|
||||
g_value_unset (&args[0]);
|
||||
g_value_unset (&args[1]);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
@ -145,61 +236,44 @@ _wrap_gst_pad_set_chain_function(PyGObject *self,
|
|||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "chain_function", NULL };
|
||||
PyObject *chain_function;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.set_chain_funcion",
|
||||
kwlist,
|
||||
&chain_function)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(chain_function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "chain_function not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(chain_function);
|
||||
py_pad_private(self)->chain_function = chain_function;
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
gst_pad_set_chain_function(pad, (GstPadChainFunction)call_chain_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
SET_PAD_CLOSURE (self, args, kwargs, chain_function)
|
||||
}
|
||||
%%
|
||||
override gst_pad_set_event_function kwargs
|
||||
|
||||
static void EXCEPTION_HANDLER
|
||||
handle_event_function_exception (GValue *ret, guint n, const GValue *params)
|
||||
{
|
||||
GstElement *element = gst_pad_get_parent (g_value_get_object (¶ms[0]));
|
||||
|
||||
if (!_pygst_element_check_error (element))
|
||||
g_assert_not_reached (); /* only returns FALSE when there's no error */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
call_event_function (GstPad *pad, GstEvent *event)
|
||||
{
|
||||
PyObject *function;
|
||||
PyObject *retval;
|
||||
gboolean ret;
|
||||
PyGILState_STATE state;
|
||||
GClosure *closure;
|
||||
GValue ret = { 0, };
|
||||
GValue args[2] = { { 0, }, { 0, } };
|
||||
gboolean bool;
|
||||
|
||||
function = pad_private(pad)->event_function;
|
||||
g_value_init (&ret, G_TYPE_BOOLEAN);
|
||||
g_value_set_boolean (&ret, FALSE);
|
||||
g_value_init (&args[0], GST_TYPE_REAL_PAD);
|
||||
g_value_init (&args[1], GST_TYPE_EVENT);
|
||||
g_value_set_object (&args[0], pad);
|
||||
g_value_set_boxed (&args[1], event);
|
||||
closure = pad_private(pad)->event_function;
|
||||
|
||||
state = pyg_gil_state_ensure();
|
||||
g_closure_invoke (closure, &ret, 2, args, NULL);
|
||||
|
||||
retval = PyObject_CallFunction (function,
|
||||
"OO",
|
||||
pad_private(pad)->pad,
|
||||
pyg_boxed_new(GST_TYPE_EVENT, event, TRUE, TRUE));
|
||||
bool = g_value_get_boolean (&ret);
|
||||
|
||||
if (PyErr_Occurred ()) {
|
||||
PyErr_Print ();
|
||||
pyg_gil_state_release(state);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = PyInt_AsLong(retval);
|
||||
|
||||
pyg_gil_state_release(state);
|
||||
|
||||
return ret;
|
||||
g_value_unset (&ret);
|
||||
g_value_unset (&args[0]);
|
||||
g_value_unset (&args[1]);
|
||||
return bool;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
@ -207,58 +281,41 @@ _wrap_gst_pad_set_event_function (PyGObject *self,
|
|||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "event_function", NULL };
|
||||
PyObject *event_function;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.set_event_funcion",
|
||||
kwlist,
|
||||
&event_function)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(event_function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "event_function not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(event_function);
|
||||
py_pad_private(self)->event_function = event_function;
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
gst_pad_set_event_function(pad, (GstPadEventFunction)call_event_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
SET_PAD_CLOSURE (self, args, kwargs, event_function)
|
||||
}
|
||||
|
||||
%%
|
||||
override gst_pad_set_get_function kwargs
|
||||
|
||||
static void EXCEPTION_HANDLER
|
||||
handle_get_function_exception (GValue *ret, guint n, const GValue *params)
|
||||
{
|
||||
GstElement *element = gst_pad_get_parent (g_value_get_object (¶ms[0]));
|
||||
|
||||
if (!_pygst_element_check_error (element))
|
||||
g_assert_not_reached (); /* only returns FALSE when there's no error */
|
||||
}
|
||||
|
||||
static GstData*
|
||||
call_get_function (GstPad *pad)
|
||||
{
|
||||
PyObject *function;
|
||||
PyObject *retval;
|
||||
GClosure *closure;
|
||||
GValue ret = { 0, };
|
||||
GValue args = { 0, };
|
||||
GstData *data = NULL;
|
||||
PyGILState_STATE state;
|
||||
|
||||
function = pad_private(pad)->get_function;
|
||||
g_value_init (&ret, GST_TYPE_DATA);
|
||||
g_value_init (&args, GST_TYPE_REAL_PAD);
|
||||
g_value_set_object (&args, pad);
|
||||
closure = pad_private(pad)->get_function;
|
||||
|
||||
state = pyg_gil_state_ensure();
|
||||
g_closure_invoke (closure, &ret, 1, &args, NULL);
|
||||
|
||||
retval = PyObject_CallFunction(function, "O", pad_private(pad)->pad);
|
||||
data = g_value_get_boxed (&ret);
|
||||
gst_data_ref (data);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
goto bail;
|
||||
} else if (retval == Py_None) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
pygst_data_from_pyobject(retval, &data);
|
||||
|
||||
bail:
|
||||
pyg_gil_state_release(state);
|
||||
g_value_unset (&ret);
|
||||
g_value_unset (&args);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -267,29 +324,7 @@ _wrap_gst_pad_set_get_function (PyGObject *self,
|
|||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "get_function", NULL };
|
||||
PyObject *get_function;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.set_get_funcion",
|
||||
kwlist,
|
||||
&get_function)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(get_function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "get_function not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(get_function);
|
||||
py_pad_private(self)->get_function = get_function;
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
gst_pad_set_get_function(pad, (GstPadGetFunction)call_get_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
SET_PAD_CLOSURE (self, args, kwargs, get_function)
|
||||
}
|
||||
%%
|
||||
override-slot GstPad.tp_repr
|
||||
|
@ -305,7 +340,7 @@ _wrap_gst_pad_tp_repr (PyGObject *self)
|
|||
parent = gst_pad_get_parent (pad);
|
||||
|
||||
buf = g_strdup_printf ("<GstPad (%s:%s) at %lx>",
|
||||
gst_element_get_name (parent),
|
||||
parent ? gst_element_get_name (parent) : "---",
|
||||
gst_pad_get_name (pad), (long) self->obj);
|
||||
|
||||
retval = PyString_FromString(buf);
|
||||
|
@ -457,3 +492,56 @@ _wrap_gst_pad_template_get_caps_by_name(PyGObject *self, PyObject *args, PyObjec
|
|||
/* pyg_boxed_new handles NULL checking */
|
||||
return pyg_boxed_new(GST_TYPE_CAPS, ret, TRUE, TRUE);
|
||||
}
|
||||
%%
|
||||
override gst_pad_new kwargs
|
||||
static int
|
||||
_wrap_gst_pad_new(PyGObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "name", "direction", NULL };
|
||||
static char *kwlist2[] = { "template", "name", NULL };
|
||||
PyGObject *templ;
|
||||
char *name = NULL;
|
||||
PyObject *py_direction = NULL;
|
||||
GstPadDirection direction;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwargs, "sO:GstPad.__init__", kwlist, &name, &py_direction)) {
|
||||
if (pyg_enum_get_value(GST_TYPE_PAD_DIRECTION, py_direction, (gint *)&direction))
|
||||
return -1;
|
||||
self->obj = (GObject *)gst_pad_new(name, direction);
|
||||
} else {
|
||||
PyErr_Clear ();
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwargs, "O!|s:GstPad.__init__", kwlist2, &PyGstPadTemplate_Type, &templ, &name)) {
|
||||
if (name == NULL)
|
||||
name = GST_PAD_TEMPLATE_NAME_TEMPLATE (GST_PAD_TEMPLATE(templ->obj));
|
||||
self->obj = (GObject *)gst_pad_new_from_template(GST_PAD_TEMPLATE(templ->obj), name);
|
||||
}
|
||||
}
|
||||
if (!self->obj) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "could not create GstPad object");
|
||||
return -1;
|
||||
}
|
||||
pygobject_register_wrapper((PyObject *)self);
|
||||
return 0;
|
||||
}
|
||||
%%
|
||||
override-slot GstPadTemplate.tp_getattr
|
||||
#define IS_ATTR(name) (strcmp (name, attr) == 0)
|
||||
PyObject *
|
||||
_wrap_gst_pad_template_tp_getattr(PyObject *self, char *attr)
|
||||
{
|
||||
GstPadTemplate *templ = GST_PAD_TEMPLATE (pygobject_get (self));
|
||||
|
||||
if (IS_ATTR ("__members__")) {
|
||||
return Py_BuildValue("[ssss]", "name_template", "direction", "presence", "caps" );
|
||||
} else if (IS_ATTR ("name_template")) {
|
||||
return PyString_FromString (GST_PAD_TEMPLATE_NAME_TEMPLATE(templ));
|
||||
} else if (IS_ATTR ("direction")) {
|
||||
return pyg_enum_from_gtype(GST_TYPE_PAD_DIRECTION, GST_PAD_TEMPLATE_DIRECTION(templ));
|
||||
} else if (IS_ATTR ("presence")) {
|
||||
return pyg_enum_from_gtype(GST_TYPE_PAD_PRESENCE, GST_PAD_TEMPLATE_PRESENCE(templ));
|
||||
} else if (IS_ATTR ("caps")) {
|
||||
return pyg_boxed_new (GST_TYPE_CAPS, GST_PAD_TEMPLATE_CAPS(templ), TRUE, TRUE);
|
||||
}
|
||||
return Py_FindMethod(_PyGstPadTemplate_methods, self, attr);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ _wrap_gst_structure_set_value(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
}
|
||||
|
||||
g_value_init(&value, type);
|
||||
if (pyg_value_from_pyobject(&value, py_value) != 0) {
|
||||
if (pygst_value_from_pyobject(&value, py_value) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
gst_structure_set_value(pyg_boxed_get(self, GstStructure), field,
|
||||
|
@ -131,6 +131,27 @@ _wrap_gst_structure_get_int(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_structure_get_double kwargs
|
||||
static PyObject *
|
||||
_wrap_gst_structure_get_double(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "fieldname", NULL };
|
||||
char *fieldname;
|
||||
gdouble value;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"s:GstStructure.get_double",
|
||||
kwlist, &fieldname))
|
||||
return NULL;
|
||||
|
||||
if (gst_structure_get_double(pyg_boxed_get(self, GstStructure), fieldname, &value))
|
||||
return PyFloat_FromDouble(value);
|
||||
|
||||
/* XXX: Raise exception? */
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
define GstStructure.has_key args
|
||||
static PyObject*
|
||||
_wrap_gst_structure_has_key(PyGObject *self, PyObject *args)
|
||||
|
@ -163,7 +184,7 @@ _wrap_gst_structure_subscript(PyGObject *self, PyObject *py_key)
|
|||
const GValue *gvalue;
|
||||
gvalue = gst_structure_get_value((GstStructure*)self->obj, field);
|
||||
g_assert(gvalue != NULL);
|
||||
v = pyg_value_as_pyobject(gvalue, TRUE);
|
||||
v = pygst_value_as_pyobject(gvalue, TRUE);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_KeyError, field);
|
||||
}
|
||||
|
@ -184,37 +205,13 @@ _wrap_gst_structure_ass_subscript(PyGObject *self,
|
|||
structure = (GstStructure*)self->obj;
|
||||
key = PyString_AsString(py_key);
|
||||
if (py_value != NULL) {
|
||||
if (PyString_Check(py_value)) {
|
||||
#if 0
|
||||
GValue *value = NULL;
|
||||
gst_structure_field_from_string(PyString_AsString(py_value), value);
|
||||
g_print ("gvalue: %s %s %s\n",
|
||||
PyString_AsString(py_value),
|
||||
gst_value_serialize(value),
|
||||
G_VALUE_TYPE_NAME(value));
|
||||
gst_structure_set_value(structure, key, value);
|
||||
#else
|
||||
GValue value = { 0, };
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
gst_value_deserialize(&value, PyString_AsString(py_value));
|
||||
gst_structure_set_value(structure, key, &value);
|
||||
g_value_unset(&value);
|
||||
#endif
|
||||
// gst_structure_set(structure, key, G_TYPE_STRING, PyString_AsString(py_value), NULL);
|
||||
} else if (PyInt_Check(py_value))
|
||||
gst_structure_set(structure, key, G_TYPE_INT, PyInt_AsLong(py_value), NULL);
|
||||
else if (PyFloat_Check(py_value))
|
||||
gst_structure_set(structure, key, G_TYPE_DOUBLE, PyFloat_AsDouble(py_value), NULL);
|
||||
#if 0
|
||||
g_value_init(&value, g_type_from_name("PyObject"));
|
||||
if (pyg_value_from_pyobject(&value, py_value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "can't convert value");
|
||||
GValue v = { 0, };
|
||||
if (!pygst_value_init_for_pyobject (&v, py_value))
|
||||
return -1;
|
||||
if (pygst_value_from_pyobject(&v, py_value))
|
||||
return -1;
|
||||
}
|
||||
|
||||
gst_structure_set_value(structure, key, &value);
|
||||
g_value_unset(&value);
|
||||
#endif
|
||||
gst_structure_set_value(structure, key, &v);
|
||||
g_value_unset(&v);
|
||||
} else {
|
||||
gst_structure_remove_field(structure, key);
|
||||
}
|
||||
|
@ -245,7 +242,7 @@ pygst_structure_foreach_marshal(GQuark field_id,
|
|||
state = pyg_gil_state_ensure();
|
||||
|
||||
py_field = Py_BuildValue("s", g_quark_to_string(field_id));
|
||||
py_value = pyg_value_as_pyobject(value, FALSE);
|
||||
py_value = pygst_value_as_pyobject(value, FALSE);
|
||||
if (cunote->data)
|
||||
retobj = PyEval_CallFunction(cunote->func, "(NNO)",
|
||||
py_field, py_value,
|
||||
|
@ -331,3 +328,18 @@ _wrap_gst_structure_from_string(PyObject *self, PyObject *args, PyObject *kwargs
|
|||
/* pyg_boxed_new handles NULL checking */
|
||||
return pyg_boxed_new(GST_TYPE_STRUCTURE, ret, TRUE, TRUE);
|
||||
}
|
||||
%%
|
||||
override-slot GstStructure.tp_dealloc
|
||||
static void
|
||||
_wrap_gst_structure_tp_dealloc (PyObject *self)
|
||||
{
|
||||
PyGBoxed *boxed = (PyGBoxed *) self;
|
||||
|
||||
if (boxed->free_on_dealloc && boxed->boxed) {
|
||||
gst_structure_free (boxed->boxed);
|
||||
} else if (boxed->boxed) {
|
||||
pygst_caps_map_remove_structure (self);
|
||||
}
|
||||
|
||||
self->ob_type->tp_free((PyObject *)self);
|
||||
}
|
||||
|
|
301
gst/pygstvalue.c
Normal file
301
gst/pygstvalue.c
Normal file
|
@ -0,0 +1,301 @@
|
|||
/* gst-python
|
||||
* Copyright (C) 2004 Andy Wingo
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Andy Wingo <wingo@pobox.com>
|
||||
*/
|
||||
|
||||
/* define this for all source files that don't run init_pygobject()
|
||||
* before including pygobject.h */
|
||||
#define NO_IMPORT_PYGOBJECT
|
||||
|
||||
#include "pygstvalue.h"
|
||||
|
||||
|
||||
static PyObject *gstvalue_class = NULL;
|
||||
static PyObject *gstfourcc_class = NULL;
|
||||
static PyObject *gstintrange_class = NULL;
|
||||
static PyObject *gstdoublerange_class = NULL;
|
||||
static PyObject *gstfraction_class = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* pygst_value_as_pyobject:
|
||||
* @value: the GValue object.
|
||||
* @copy_boxed: true if boxed values should be copied.
|
||||
*
|
||||
* This function creates/returns a Python wrapper object that
|
||||
* represents the GValue passed as an argument.
|
||||
*
|
||||
* Returns: a PyObject representing the value.
|
||||
*/
|
||||
PyObject *
|
||||
pygst_value_as_pyobject(const GValue *value, gboolean copy_boxed)
|
||||
{
|
||||
PyObject *ret = pyg_value_as_pyobject(value, copy_boxed);
|
||||
if (!ret) {
|
||||
PyErr_Clear();
|
||||
if (GST_VALUE_HOLDS_FOURCC (value)) {
|
||||
gchar str[5];
|
||||
g_snprintf (str, 5, GST_FOURCC_FORMAT,
|
||||
GST_FOURCC_ARGS (gst_value_get_fourcc (value)));
|
||||
ret = PyObject_Call (gstfourcc_class, Py_BuildValue ("(s)", str), NULL);
|
||||
} else if (GST_VALUE_HOLDS_INT_RANGE (value)) {
|
||||
ret = PyObject_Call
|
||||
(gstintrange_class,
|
||||
Py_BuildValue ("ii",
|
||||
gst_value_get_int_range_min (value),
|
||||
gst_value_get_int_range_max (value)),
|
||||
NULL);
|
||||
} else if (GST_VALUE_HOLDS_DOUBLE_RANGE (value)) {
|
||||
ret = PyObject_Call
|
||||
(gstdoublerange_class,
|
||||
Py_BuildValue ("dd",
|
||||
gst_value_get_double_range_min (value),
|
||||
gst_value_get_double_range_max (value)),
|
||||
NULL);
|
||||
} else if (GST_VALUE_HOLDS_LIST (value)) {
|
||||
int i, len;
|
||||
len = gst_value_list_get_size (value);
|
||||
ret = PyList_New (len);
|
||||
for (i=0; i<len; i++) {
|
||||
PyList_SetItem (ret, i,
|
||||
pygst_value_as_pyobject
|
||||
(gst_value_list_get_value (value, i), copy_boxed));
|
||||
}
|
||||
} else if (GST_VALUE_HOLDS_FIXED_LIST (value)) {
|
||||
int i, len;
|
||||
len = gst_value_list_get_size (value);
|
||||
ret = PyTuple_New (len);
|
||||
for (i=0; i<len; i++) {
|
||||
PyTuple_SetItem (ret, i,
|
||||
pygst_value_as_pyobject
|
||||
(gst_value_list_get_value (value, i), copy_boxed));
|
||||
}
|
||||
} else if (GST_VALUE_HOLDS_FRACTION (value)) {
|
||||
ret = PyObject_Call
|
||||
(gstfraction_class,
|
||||
Py_BuildValue ("ii",
|
||||
gst_value_get_fraction_numerator (value),
|
||||
gst_value_get_fraction_denominator (value)),
|
||||
NULL);
|
||||
} else {
|
||||
gchar buf[256];
|
||||
g_snprintf (buf, 256, "unknown type: %s", g_type_name (G_VALUE_TYPE (value)));
|
||||
PyErr_SetString(PyExc_TypeError, buf);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define VALUE_TYPE_CHECK(v, t) \
|
||||
G_STMT_START{\
|
||||
if (!G_VALUE_HOLDS (v, t)) {\
|
||||
gchar errbuf[256];\
|
||||
g_snprintf (errbuf, 256, "Could not convert %s to %s",\
|
||||
g_type_name (t), g_type_name (G_VALUE_TYPE (v)));\
|
||||
PyErr_SetString (PyExc_TypeError, errbuf);\
|
||||
return -1;\
|
||||
}}G_STMT_END
|
||||
|
||||
gboolean
|
||||
pygst_value_init_for_pyobject (GValue *value, PyObject *obj)
|
||||
{
|
||||
GType t;
|
||||
|
||||
if (!(t = pyg_type_from_object ((PyObject*)obj->ob_type))) {
|
||||
if (PyObject_IsInstance (obj, gstvalue_class)) {
|
||||
PyErr_Clear ();
|
||||
if (PyObject_IsInstance (obj, gstfourcc_class))
|
||||
t = GST_TYPE_FOURCC;
|
||||
else if (PyObject_IsInstance (obj, gstintrange_class))
|
||||
t = GST_TYPE_INT_RANGE;
|
||||
else if (PyObject_IsInstance (obj, gstdoublerange_class))
|
||||
t = GST_TYPE_DOUBLE_RANGE;
|
||||
else if (PyObject_IsInstance (obj, gstfraction_class))
|
||||
t = GST_TYPE_FRACTION;
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "Unexpected gst.Value instance");
|
||||
return FALSE;
|
||||
}
|
||||
} else if (PyTuple_Check (obj)) {
|
||||
PyErr_Clear ();
|
||||
t = GST_TYPE_FIXED_LIST;
|
||||
} else if (PyList_Check (obj)) {
|
||||
PyErr_Clear ();
|
||||
t = GST_TYPE_LIST;
|
||||
} else {
|
||||
/* pyg_type_from_object already set the error */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
g_value_init (value, t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pygst_value_from_pyobject:
|
||||
* @value: the GValue object to store the converted value in.
|
||||
* @obj: the Python object to convert.
|
||||
*
|
||||
* This function converts a Python object and stores the result in a
|
||||
* GValue. The GValue must be initialised in advance with
|
||||
* g_value_init(). If the Python object can't be converted to the
|
||||
* type of the GValue, then an error is returned.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
pygst_value_from_pyobject (GValue *value, PyObject *obj)
|
||||
{
|
||||
GType f = g_type_fundamental (G_VALUE_TYPE (value));
|
||||
|
||||
/* work around a bug in pygtk whereby pyg_value_from_pyobject claims success
|
||||
for unknown fundamental types without actually doing anything */
|
||||
if (f < G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST)
|
||||
&& pyg_value_from_pyobject (value, obj) == 0) {
|
||||
return 0;
|
||||
} else if (PyObject_IsInstance (obj, gstvalue_class)) {
|
||||
PyErr_Clear ();
|
||||
|
||||
if (PyObject_IsInstance (obj, gstfourcc_class)) {
|
||||
PyObject *pystr;
|
||||
gchar *str;
|
||||
VALUE_TYPE_CHECK (value, GST_TYPE_FOURCC);
|
||||
if (!(pystr = PyObject_GetAttrString (obj, "fourcc")))
|
||||
return -1;
|
||||
if (!(str = PyString_AsString (pystr)))
|
||||
return -1;
|
||||
g_assert (strlen (str) == 4);
|
||||
gst_value_set_fourcc (value, GST_STR_FOURCC (str));
|
||||
} else if (PyObject_IsInstance (obj, gstintrange_class)) {
|
||||
PyObject *pyval;
|
||||
long low, high;
|
||||
VALUE_TYPE_CHECK (value, GST_TYPE_INT_RANGE);
|
||||
if (!(pyval = PyObject_GetAttrString (obj, "low")))
|
||||
return -1;
|
||||
low = PyInt_AsLong (pyval);
|
||||
g_assert (G_MININT <= low && low <= G_MAXINT);
|
||||
if (!(pyval = PyObject_GetAttrString (obj, "high")))
|
||||
return -1;
|
||||
high = PyInt_AsLong (pyval);
|
||||
g_assert (G_MININT <= high && high <= G_MAXINT);
|
||||
gst_value_set_int_range (value, (int)low, (int)high);
|
||||
} else if (PyObject_IsInstance (obj, gstdoublerange_class)) {
|
||||
PyObject *pyval;
|
||||
double low, high;
|
||||
VALUE_TYPE_CHECK (value, GST_TYPE_DOUBLE_RANGE);
|
||||
if (!(pyval = PyObject_GetAttrString (obj, "low")))
|
||||
return -1;
|
||||
low = PyFloat_AsDouble (pyval);
|
||||
if (!(pyval = PyObject_GetAttrString (obj, "high")))
|
||||
return -1;
|
||||
high = PyFloat_AsDouble (pyval);
|
||||
gst_value_set_double_range (value, low, high);
|
||||
} else if (PyObject_IsInstance (obj, gstfraction_class)) {
|
||||
PyObject *pyval;
|
||||
long num, denom;
|
||||
VALUE_TYPE_CHECK (value, GST_TYPE_FRACTION);
|
||||
if (!(pyval = PyObject_GetAttrString (obj, "num")))
|
||||
return -1;
|
||||
num = PyInt_AsLong (pyval);
|
||||
g_assert (G_MININT <= num && num <= G_MAXINT);
|
||||
if (!(pyval = PyObject_GetAttrString (obj, "denom")))
|
||||
return -1;
|
||||
denom = PyInt_AsLong (pyval);
|
||||
g_assert (G_MININT <= denom && denom <= G_MAXINT);
|
||||
gst_value_set_fraction (value, (int)num, (int)denom);
|
||||
} else {
|
||||
gchar buf[256];
|
||||
gchar *str = PyString_AsString (PyObject_Repr(obj));
|
||||
g_snprintf(buf, 256, "Unknown gst.Value type: %s", str);
|
||||
PyErr_SetString(PyExc_TypeError, buf);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else if (PyTuple_Check (obj)) {
|
||||
gint i, len;
|
||||
PyErr_Clear ();
|
||||
VALUE_TYPE_CHECK (value, GST_TYPE_FIXED_LIST);
|
||||
len = PyTuple_Size (obj);
|
||||
for (i = 0; i < len; i++) {
|
||||
PyObject *o;
|
||||
GValue new = {0,};
|
||||
o = PyTuple_GetItem (obj, i);
|
||||
if (!pygst_value_init_for_pyobject (&new, o))
|
||||
return -1;
|
||||
if (pygst_value_from_pyobject (&new, o) != 0) {
|
||||
g_value_unset (&new);
|
||||
return -1;
|
||||
}
|
||||
gst_value_list_append_value (value, &new);
|
||||
g_value_unset (&new);
|
||||
}
|
||||
return 0;
|
||||
} else if (PyList_Check (obj)) {
|
||||
gint i, len;
|
||||
PyErr_Clear ();
|
||||
VALUE_TYPE_CHECK (value, GST_TYPE_LIST);
|
||||
len = PyList_Size (obj);
|
||||
for (i = 0; i < len; i++) {
|
||||
PyObject *o;
|
||||
GValue new = {0,};
|
||||
o = PyList_GetItem (obj, i);
|
||||
if (!pygst_value_init_for_pyobject (&new, o))
|
||||
return -1;
|
||||
if (pygst_value_from_pyobject (&new, o) != 0) {
|
||||
g_value_unset (&new);
|
||||
return -1;
|
||||
}
|
||||
gst_value_list_append_value (value, &new);
|
||||
g_value_unset (&new);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#define NULL_CHECK(o) if (!o) goto err
|
||||
|
||||
gboolean
|
||||
pygst_value_init(void)
|
||||
{
|
||||
PyObject *module, *dict;
|
||||
|
||||
if ((module = PyImport_ImportModule("gst")) == NULL)
|
||||
return FALSE;
|
||||
|
||||
dict = PyModule_GetDict (module);
|
||||
|
||||
gstvalue_class = (PyObject*)PyDict_GetItemString (dict, "Value");
|
||||
NULL_CHECK (gstvalue_class);
|
||||
gstfourcc_class = (PyObject*)PyDict_GetItemString (dict, "Fourcc");
|
||||
NULL_CHECK (gstfourcc_class);
|
||||
gstintrange_class = (PyObject*)PyDict_GetItemString (dict, "IntRange");
|
||||
NULL_CHECK (gstintrange_class);
|
||||
gstdoublerange_class = (PyObject*)PyDict_GetItemString (dict, "DoubleRange");
|
||||
NULL_CHECK (gstdoublerange_class);
|
||||
gstfraction_class = (PyObject*)PyDict_GetItemString (dict, "Fraction");
|
||||
NULL_CHECK (gstfraction_class);
|
||||
return TRUE;
|
||||
|
||||
err:
|
||||
PyErr_SetString (PyExc_ImportError,
|
||||
"Failed to get GstValue classes from gst module");
|
||||
return FALSE;
|
||||
}
|
29
gst/pygstvalue.h
Normal file
29
gst/pygstvalue.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* gst-python
|
||||
* Copyright (C) 2004 Andy Wingo
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Andy Wingo <wingo@pobox.com>
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
PyObject *pygst_value_as_pyobject(const GValue *value, gboolean copy_boxed);
|
||||
gboolean pygst_value_init_for_pyobject (GValue *value, PyObject *obj);
|
||||
int pygst_value_from_pyobject(GValue *value, PyObject *obj);
|
||||
gboolean pygst_value_init(void);
|
|
@ -31,7 +31,7 @@ tests = \
|
|||
test_xml.py
|
||||
|
||||
check-local: testhelper.la
|
||||
@PYTHONPATH=$(PYTHONPATH):$(top_builddir):$(top_builddir)/gst/.libs $(PYTHON) $(srcdir)/runtests.py
|
||||
@G_DEBUG=fatal_warnings GST_DEBUG=*:0 PYTHONPATH=$(top_builddir):$(top_builddir)/gst/.libs:`pwd`:$(top_srcdir):$(PYTHONPATH) $(PYTHON) $(srcdir)/runtests.py
|
||||
@rm -fr *.pyc
|
||||
|
||||
EXTRA_DIST = $(tests) common.py runtests.py test-object.h
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import dl
|
||||
try:
|
||||
from dl import RTLD_LAZY, RTLD_GLOBAL
|
||||
except ImportError:
|
||||
# dl doesn't seem to be available on 64bit systems
|
||||
try:
|
||||
from DLFCN import RTLD_LAZY, RTLD_GLOBAL
|
||||
except ImportError:
|
||||
pass
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
@ -13,36 +20,51 @@ except:
|
|||
print "WARNING: gobject doesn't have threads_init, no threadsafety"
|
||||
|
||||
# Don't insert before .
|
||||
sys.path.insert(1, os.path.join('..'))
|
||||
# sys.path.insert(1, os.path.join('..'))
|
||||
|
||||
# Load GST and make sure we load it from the current build
|
||||
sys.setdlopenflags(dl.RTLD_LAZY | dl.RTLD_GLOBAL)
|
||||
sys.setdlopenflags(RTLD_LAZY | RTLD_GLOBAL)
|
||||
|
||||
# Hack
|
||||
sys.argv.append('--gst-debug-no-color')
|
||||
|
||||
path = os.path.abspath(os.path.join('..', 'gst'))
|
||||
import gst
|
||||
topbuilddir = os.path.abspath(os.path.join('..'))
|
||||
topsrcdir = os.path.abspath(os.path.join('..'))
|
||||
if topsrcdir.endswith('_build'):
|
||||
topsrcdir = os.path.dirname(topsrcdir)
|
||||
|
||||
# gst's __init__.py is in topsrcdir/gst
|
||||
path = os.path.abspath(os.path.join(topsrcdir, 'gst'))
|
||||
import gst
|
||||
file = gst.__file__
|
||||
assert file.startswith(path), 'bad gst path: %s' % file
|
||||
|
||||
# gst's interfaces and play are in topbuilddir/gst
|
||||
path = os.path.abspath(os.path.join(topbuilddir, 'gst'))
|
||||
try:
|
||||
import gst.interfaces
|
||||
assert os.path.basename(gst.interfaces.__file__) != path, 'bad path'
|
||||
except ImportError:
|
||||
pass
|
||||
# hack: we import it from our builddir/gst/.libs instead; ugly
|
||||
import interfaces
|
||||
gst.interfaces = interfaces
|
||||
file = gst.interfaces.__file__
|
||||
assert file.startswith(path), 'bad gst.interfaces path: %s' % file
|
||||
|
||||
try:
|
||||
import gst.play
|
||||
assert os.path.basename(gst.play.__file__) != path, 'bad path'
|
||||
except ImportError:
|
||||
# hack: we import it from our builddir/gst/.libs instead; ugly
|
||||
import play
|
||||
gst.play = play
|
||||
pass
|
||||
file = gst.play.__file__
|
||||
assert file.startswith(path), 'bad gst.play path: %s' % file
|
||||
|
||||
# testhelper needs ltihooks
|
||||
import gst.ltihooks
|
||||
|
||||
import ltihooks
|
||||
import testhelper
|
||||
|
||||
# finally remove ltihooks
|
||||
gst.ltihooks.uninstall()
|
||||
ltihooks.uninstall()
|
||||
|
||||
_stderr = None
|
||||
|
||||
|
|
|
@ -6,11 +6,9 @@ import unittest
|
|||
|
||||
SKIP_FILES = ['common', 'runtests']
|
||||
|
||||
dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
os.chdir(dir)
|
||||
|
||||
def gettestnames():
|
||||
files = glob.glob('*.py')
|
||||
dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
files = [os.path.basename(p) for p in glob.glob('%s/*.py' % dir)]
|
||||
names = map(lambda x: x[:-3], files)
|
||||
map(names.remove, SKIP_FILES)
|
||||
return names
|
||||
|
@ -22,4 +20,6 @@ for name in gettestnames():
|
|||
suite.addTest(loader.loadTestsFromName(name))
|
||||
|
||||
testRunner = unittest.TextTestRunner()
|
||||
testRunner.run(suite)
|
||||
result = testRunner.run(suite)
|
||||
if result.failures or result.errors:
|
||||
sys.exit(1)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import sys
|
||||
import gc
|
||||
from common import gobject, gst, unittest
|
||||
|
||||
class BufferTest(unittest.TestCase):
|
||||
|
@ -9,7 +10,13 @@ class BufferTest(unittest.TestCase):
|
|||
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)
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@ from common import gst, unittest
|
|||
class CapsTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.caps = gst.caps_from_string('video/x-raw-yuv,width=10,framerate=5.0;video/x-raw-rgb,width=15,framerate=10.0')
|
||||
self.structure = self.caps.get_structure(0)
|
||||
self.structure = self.caps[0]
|
||||
self.any = gst.Caps("ANY")
|
||||
self.empty = gst.Caps()
|
||||
|
||||
def testCapsMime(self):
|
||||
mime = self.structure.get_name()
|
||||
|
@ -61,6 +63,14 @@ class CapsTest(unittest.TestCase):
|
|||
assert isinstance(struct['height'], float)
|
||||
assert struct['height'] == 20.0
|
||||
|
||||
def testCapsRefernceStructs(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
|
||||
|
@ -80,6 +90,57 @@ class CapsTest(unittest.TestCase):
|
|||
|
||||
# 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"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# testsuite for gstreamer.Element
|
||||
|
||||
import common
|
||||
from common import gst, unittest
|
||||
|
||||
class ElementTest(unittest.TestCase):
|
||||
|
@ -44,7 +43,7 @@ class FakeSinkTest(ElementTest):
|
|||
self.error = True
|
||||
|
||||
self.element.connect('error', error_cb)
|
||||
common.run_silent(self.element.set_state, state)
|
||||
self.element.set_state (state)
|
||||
assert self.error, 'error not set'
|
||||
#assert error_message.find('ERROR') != -1
|
||||
|
||||
|
|
|
@ -12,7 +12,10 @@ class Availability(unittest.TestCase):
|
|||
assert issubclass(gst.interfaces.Mixer, gobject.GInterface)
|
||||
|
||||
class FunctionCall(unittest.TestCase):
|
||||
def testXOverlay(self):
|
||||
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)
|
||||
|
|
|
@ -5,9 +5,6 @@ class StructureTest(unittest.TestCase):
|
|||
def setUp(self):
|
||||
self.struct = gst.structure_from_string('video/x-raw-yuv,width=10,foo="bar",pixel-aspect-ratio=1/2,framerate=5.0')
|
||||
|
||||
#def foo(self):
|
||||
# gst.structure_from_string("foo")
|
||||
|
||||
def testName(self):
|
||||
assert self.struct.get_name() == 'video/x-raw-yuv'
|
||||
self.struct.set_name('foobar')
|
||||
|
@ -37,30 +34,39 @@ class StructureTest(unittest.TestCase):
|
|||
assert isinstance(self.struct['integer'], int)
|
||||
assert self.struct['integer'] == 5, self.struct['integer']
|
||||
|
||||
def testCreateFourCC(self):
|
||||
self.struct['fourcc'] = "(fourcc)XVID"
|
||||
#assert self.struct.has_key('fourcc')
|
||||
#print self.struct.to_string()
|
||||
#assert isinstance(self.struct['fourcc'], 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['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]
|
||||
|
||||
# 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 structure['pixel-aspect-ratio'].numerator == 1
|
||||
#assert structure['pixel-aspect-ratio'].denominator == 2
|
||||
#assert float(structure['pixel-aspect-ratio']) == 0.5
|
||||
#structure['pixel-aspect-ratio'] = gst.Fraction(3, 4)
|
||||
#assert structure['pixel-aspect-ratio'].numerator == 3
|
||||
#assert structure['pixel-aspect-ratio'].denominator == 4
|
||||
#assert float(structure['pixel-aspect-ratio']) == 0.75
|
||||
|
||||
assert self.struct['framerate'] == 5.0
|
||||
self.struct['framerate'] = 10.0
|
||||
assert self.struct['framerate'] == 10.0
|
||||
|
||||
# a list of heights
|
||||
#structure['height'] = (20, 40, 60)
|
||||
#assert structure['width'] == (20, 40, 60)
|
||||
# FIXME: add ranges
|
||||
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
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in a new issue