2012-08-08 17:59:09 +00:00
|
|
|
# -*- Mode: Python; py-indent-offset: 4 -*-
|
|
|
|
# vim: tabstop=4 shiftwidth=4 expandtab
|
|
|
|
#
|
|
|
|
# Gst.py
|
|
|
|
#
|
|
|
|
# Copyright (C) 2012 Thibault Saunier <thibault.saunier@collabora.com>
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
|
|
# License as published by the Free Software Foundation; either
|
|
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
# Lesser General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
|
|
# License along with this program; if not, write to the
|
2013-11-25 17:01:48 +00:00
|
|
|
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
2013-12-12 11:20:12 +00:00
|
|
|
# Boston, MA 02110-1301, USA.
|
2012-08-08 17:59:09 +00:00
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 3, or (at your option)
|
|
|
|
# any later version.
|
|
|
|
|
|
|
|
import sys
|
2015-04-24 08:27:47 +00:00
|
|
|
import inspect
|
2019-04-10 22:42:49 +00:00
|
|
|
import itertools
|
2019-08-08 23:03:17 +00:00
|
|
|
import weakref
|
2012-08-08 17:59:09 +00:00
|
|
|
from ..overrides import override
|
2018-04-25 17:47:19 +00:00
|
|
|
from ..module import get_introspection_module
|
2015-04-15 17:55:16 +00:00
|
|
|
|
2017-07-25 17:00:08 +00:00
|
|
|
from gi.repository import GLib
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
|
2018-04-25 17:47:19 +00:00
|
|
|
Gst = get_introspection_module('Gst')
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
__all__ = []
|
|
|
|
|
|
|
|
if Gst._version == '0.10':
|
|
|
|
import warnings
|
|
|
|
warn_msg = "You have imported the Gst 0.10 module. Because Gst 0.10 \
|
|
|
|
was not designed for use with introspection some of the \
|
|
|
|
interfaces and API will fail. As such this is not supported \
|
|
|
|
by the GStreamer development team and we encourage you to \
|
2019-11-19 13:07:09 +00:00
|
|
|
port your app to Gst 1 or greater. gst-python is the recommended \
|
2012-08-08 17:59:09 +00:00
|
|
|
python module to use with Gst 0.10"
|
|
|
|
|
|
|
|
warnings.warn(warn_msg, RuntimeWarning)
|
|
|
|
|
2019-05-06 15:29:53 +00:00
|
|
|
|
|
|
|
class Element(Gst.Element):
|
|
|
|
@staticmethod
|
|
|
|
def link_many(*args):
|
|
|
|
'''
|
|
|
|
@raises: Gst.LinkError
|
|
|
|
'''
|
|
|
|
for pair in pairwise(args):
|
|
|
|
if not pair[0].link(pair[1]):
|
|
|
|
raise LinkError(
|
|
|
|
'Failed to link {} and {}'.format(pair[0], pair[1]))
|
|
|
|
|
|
|
|
Element = override(Element)
|
|
|
|
__all__.append('Element')
|
|
|
|
|
|
|
|
|
2012-11-04 16:02:24 +00:00
|
|
|
class Bin(Gst.Bin):
|
|
|
|
def __init__(self, name=None):
|
|
|
|
Gst.Bin.__init__(self, name=name)
|
|
|
|
|
|
|
|
def add(self, *args):
|
|
|
|
for arg in args:
|
|
|
|
if not Gst.Bin.add(self, arg):
|
|
|
|
raise AddError(arg)
|
|
|
|
|
2019-04-10 22:42:49 +00:00
|
|
|
def make_and_add(self, factory_name, instance_name=None):
|
|
|
|
'''
|
|
|
|
@raises: Gst.AddError
|
|
|
|
'''
|
|
|
|
elem = Gst.ElementFactory.make(factory_name, instance_name)
|
|
|
|
if not elem:
|
|
|
|
raise AddError(
|
|
|
|
'No such element: {}'.format(factory_name))
|
|
|
|
self.add(elem)
|
|
|
|
return elem
|
|
|
|
|
|
|
|
|
2012-11-04 16:02:24 +00:00
|
|
|
Bin = override(Bin)
|
|
|
|
__all__.append('Bin')
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
class Caps(Gst.Caps):
|
|
|
|
|
2014-03-15 14:45:43 +00:00
|
|
|
def __nonzero__(self):
|
|
|
|
return not self.is_empty()
|
|
|
|
|
2018-02-15 19:08:38 +00:00
|
|
|
def __new__(cls, *args):
|
|
|
|
if not args:
|
2012-08-08 17:59:09 +00:00
|
|
|
return Caps.new_empty()
|
2018-02-15 19:08:38 +00:00
|
|
|
elif len(args) > 1:
|
2012-08-08 17:59:09 +00:00
|
|
|
raise TypeError("wrong arguments when creating GstCaps object")
|
2018-02-15 19:08:38 +00:00
|
|
|
elif isinstance(args[0], str):
|
|
|
|
return Caps.from_string(args[0])
|
|
|
|
elif isinstance(args[0], Caps):
|
|
|
|
return args[0].copy()
|
|
|
|
elif isinstance(args[0], Structure):
|
|
|
|
res = Caps.new_empty()
|
|
|
|
res.append_structure(args[0])
|
|
|
|
return res
|
|
|
|
elif isinstance(args[0], (list, tuple)):
|
|
|
|
res = Caps.new_empty()
|
|
|
|
for e in args[0]:
|
|
|
|
res.append_structure(e)
|
|
|
|
return res
|
2012-08-08 17:59:09 +00:00
|
|
|
|
|
|
|
raise TypeError("wrong arguments when creating GstCaps object")
|
|
|
|
|
2014-05-22 20:48:09 +00:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
return super(Caps, self).__init__()
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
def __str__(self):
|
|
|
|
return self.to_string()
|
|
|
|
|
2012-10-15 07:00:03 +00:00
|
|
|
def __getitem__(self, index):
|
|
|
|
if index >= self.get_size():
|
|
|
|
raise IndexError('structure index out of range')
|
|
|
|
return self.get_structure(index)
|
|
|
|
|
|
|
|
def __len__(self):
|
|
|
|
return self.get_size()
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
Caps = override(Caps)
|
|
|
|
__all__.append('Caps')
|
|
|
|
|
2019-09-02 16:11:56 +00:00
|
|
|
class PadFunc:
|
|
|
|
def __init__(self, func):
|
|
|
|
self.func = func
|
2014-06-06 08:30:07 +00:00
|
|
|
|
2019-09-02 16:11:56 +00:00
|
|
|
def __call__(self, pad, parent, obj):
|
|
|
|
if isinstance(self.func, weakref.WeakMethod):
|
|
|
|
func = self.func()
|
|
|
|
else:
|
|
|
|
func = self.func
|
2015-03-18 12:53:55 +00:00
|
|
|
|
2015-04-24 08:27:47 +00:00
|
|
|
try:
|
2019-09-02 16:11:56 +00:00
|
|
|
res = func(pad, obj)
|
2015-04-24 08:27:47 +00:00
|
|
|
except TypeError:
|
|
|
|
try:
|
2019-09-02 16:11:56 +00:00
|
|
|
res = func(pad, parent, obj)
|
2015-04-24 08:27:47 +00:00
|
|
|
except TypeError:
|
2019-09-02 16:11:56 +00:00
|
|
|
raise TypeError("Invalid method %s, 2 or 3 arguments required"
|
|
|
|
% func)
|
2015-03-18 12:53:55 +00:00
|
|
|
|
|
|
|
return res
|
2014-06-06 08:30:07 +00:00
|
|
|
|
2019-09-02 16:11:56 +00:00
|
|
|
class Pad(Gst.Pad):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super(Gst.Pad, self).__init__(*args, **kwargs)
|
|
|
|
|
2014-06-06 08:30:07 +00:00
|
|
|
def set_chain_function(self, func):
|
2019-09-02 16:11:56 +00:00
|
|
|
self.set_chain_function_full(PadFunc(func), None)
|
2014-06-06 08:30:07 +00:00
|
|
|
|
|
|
|
def set_event_function(self, func):
|
2019-09-02 16:11:56 +00:00
|
|
|
self.set_event_function_full(PadFunc(func), None)
|
2014-06-06 08:30:07 +00:00
|
|
|
|
2015-03-18 12:53:55 +00:00
|
|
|
def set_query_function(self, func):
|
2019-09-02 16:11:56 +00:00
|
|
|
self.set_query_function_full(PadFunc(func), None)
|
2015-03-18 12:53:55 +00:00
|
|
|
|
2012-11-04 16:00:14 +00:00
|
|
|
def query_caps(self, filter=None):
|
|
|
|
return Gst.Pad.query_caps(self, filter)
|
|
|
|
|
2019-01-09 10:39:19 +00:00
|
|
|
def set_caps(self, caps):
|
|
|
|
if not isinstance(caps, Gst.Caps):
|
|
|
|
raise TypeError("%s is not a Gst.Caps." % (type(caps)))
|
|
|
|
|
|
|
|
if not caps.is_fixed():
|
|
|
|
return False
|
|
|
|
|
|
|
|
event = Gst.Event.new_caps(caps)
|
|
|
|
|
|
|
|
if self.direction == Gst.PadDirection.SRC:
|
|
|
|
res = self.push_event(event)
|
|
|
|
else:
|
|
|
|
res = self.send_event(event)
|
|
|
|
|
|
|
|
return res
|
|
|
|
|
2012-11-04 16:00:14 +00:00
|
|
|
def link(self, pad):
|
|
|
|
ret = Gst.Pad.link(self, pad)
|
|
|
|
if ret != Gst.PadLinkReturn.OK:
|
|
|
|
raise LinkError(ret)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
Pad = override(Pad)
|
|
|
|
__all__.append('Pad')
|
|
|
|
|
2012-10-24 18:47:07 +00:00
|
|
|
class GhostPad(Gst.GhostPad):
|
|
|
|
def __init__(self, name, target=None, direction=None):
|
|
|
|
if direction is None:
|
|
|
|
if target is None:
|
2015-11-08 10:56:20 +00:00
|
|
|
raise TypeError('you must pass at least one of target '
|
2015-03-18 12:53:55 +00:00
|
|
|
'and direction')
|
2012-10-24 18:47:07 +00:00
|
|
|
direction = target.props.direction
|
|
|
|
|
|
|
|
Gst.GhostPad.__init__(self, name=name, direction=direction)
|
|
|
|
self.construct()
|
|
|
|
if target is not None:
|
|
|
|
self.set_target(target)
|
|
|
|
|
2012-11-04 16:00:14 +00:00
|
|
|
def query_caps(self, filter=None):
|
|
|
|
return Gst.GhostPad.query_caps(self, filter)
|
|
|
|
|
2012-10-24 18:47:07 +00:00
|
|
|
GhostPad = override(GhostPad)
|
|
|
|
__all__.append('GhostPad')
|
|
|
|
|
2012-10-15 07:10:25 +00:00
|
|
|
class IteratorError(Exception):
|
|
|
|
pass
|
|
|
|
__all__.append('IteratorError')
|
|
|
|
|
2012-10-15 07:12:33 +00:00
|
|
|
class AddError(Exception):
|
|
|
|
pass
|
|
|
|
__all__.append('AddError')
|
|
|
|
|
2012-10-15 07:13:44 +00:00
|
|
|
class LinkError(Exception):
|
|
|
|
pass
|
|
|
|
__all__.append('LinkError')
|
|
|
|
|
2019-12-10 14:58:01 +00:00
|
|
|
class MapError(Exception):
|
|
|
|
pass
|
|
|
|
__all__.append('MapError')
|
|
|
|
|
|
|
|
|
2012-10-15 07:10:25 +00:00
|
|
|
class Iterator(Gst.Iterator):
|
|
|
|
def __iter__(self):
|
|
|
|
while True:
|
|
|
|
result, value = self.next()
|
|
|
|
if result == Gst.IteratorResult.DONE:
|
|
|
|
break
|
|
|
|
|
|
|
|
if result != Gst.IteratorResult.OK:
|
|
|
|
raise IteratorError(result)
|
|
|
|
|
|
|
|
yield value
|
|
|
|
|
|
|
|
Iterator = override(Iterator)
|
|
|
|
__all__.append('Iterator')
|
|
|
|
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
class ElementFactory(Gst.ElementFactory):
|
|
|
|
|
|
|
|
# ElementFactory
|
|
|
|
def get_longname(self):
|
|
|
|
return self.get_metadata("long-name")
|
|
|
|
|
|
|
|
def get_description(self):
|
|
|
|
return self.get_metadata("description")
|
|
|
|
|
|
|
|
def get_klass(self):
|
|
|
|
return self.get_metadata("klass")
|
|
|
|
|
2012-10-15 07:15:21 +00:00
|
|
|
@classmethod
|
|
|
|
def make(cls, factory_name, instance_name=None):
|
|
|
|
return Gst.ElementFactory.make(factory_name, instance_name)
|
2012-10-15 07:12:33 +00:00
|
|
|
|
|
|
|
class Pipeline(Gst.Pipeline):
|
|
|
|
def __init__(self, name=None):
|
|
|
|
Gst.Pipeline.__init__(self, name=name)
|
|
|
|
|
|
|
|
Pipeline = override(Pipeline)
|
|
|
|
__all__.append('Pipeline')
|
|
|
|
|
2012-11-22 06:11:45 +00:00
|
|
|
class Structure(Gst.Structure):
|
2017-07-24 16:13:13 +00:00
|
|
|
def __new__(cls, *args, **kwargs):
|
|
|
|
if not args:
|
|
|
|
if kwargs:
|
|
|
|
raise TypeError("wrong arguments when creating GstStructure, first argument"
|
|
|
|
" must be the structure name.")
|
|
|
|
return Structure.new_empty()
|
|
|
|
elif len(args) > 1:
|
|
|
|
raise TypeError("wrong arguments when creating GstStructure object")
|
|
|
|
elif isinstance(args[0], str):
|
|
|
|
if not kwargs:
|
|
|
|
return Structure.from_string(args[0])[0]
|
|
|
|
struct = Structure.new_empty(args[0])
|
|
|
|
for k, v in kwargs.items():
|
|
|
|
struct[k] = v
|
|
|
|
|
|
|
|
return struct
|
|
|
|
elif isinstance(args[0], Structure):
|
|
|
|
return args[0].copy()
|
|
|
|
|
|
|
|
raise TypeError("wrong arguments when creating GstStructure object")
|
|
|
|
|
2017-07-25 17:00:08 +00:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
2012-11-22 06:11:45 +00:00
|
|
|
def __getitem__(self, key):
|
|
|
|
return self.get_value(key)
|
2015-03-18 12:53:55 +00:00
|
|
|
|
2017-07-25 17:00:08 +00:00
|
|
|
def keys(self):
|
|
|
|
keys = set()
|
|
|
|
def foreach(fid, value, unused1, udata):
|
|
|
|
keys.add(GLib.quark_to_string(fid))
|
|
|
|
return True
|
|
|
|
|
|
|
|
self.foreach(foreach, None, None)
|
|
|
|
return keys
|
2017-07-24 21:06:06 +00:00
|
|
|
|
2012-12-07 17:18:21 +00:00
|
|
|
def __setitem__(self, key, value):
|
|
|
|
return self.set_value(key, value)
|
|
|
|
|
2017-07-25 17:00:08 +00:00
|
|
|
def __str__(self):
|
|
|
|
return self.to_string()
|
|
|
|
|
2012-11-22 06:11:45 +00:00
|
|
|
Structure = override(Structure)
|
|
|
|
__all__.append('Structure')
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
ElementFactory = override(ElementFactory)
|
|
|
|
__all__.append('ElementFactory')
|
|
|
|
|
|
|
|
class Fraction(Gst.Fraction):
|
|
|
|
def __init__(self, num, denom=1):
|
|
|
|
def __gcd(a, b):
|
|
|
|
while b != 0:
|
|
|
|
tmp = a
|
|
|
|
a = b
|
|
|
|
b = tmp % b
|
|
|
|
return abs(a)
|
|
|
|
|
|
|
|
def __simplify():
|
|
|
|
num = self.num
|
|
|
|
denom = self.denom
|
|
|
|
|
|
|
|
if num < 0:
|
|
|
|
num = -num
|
|
|
|
denom = -denom
|
|
|
|
|
|
|
|
# Compute greatest common divisor
|
|
|
|
gcd = __gcd(num, denom)
|
|
|
|
if gcd != 0:
|
|
|
|
num /= gcd
|
|
|
|
denom /= gcd
|
|
|
|
|
|
|
|
self.num = num
|
|
|
|
self.denom = denom
|
|
|
|
|
|
|
|
self.num = num
|
|
|
|
self.denom = denom
|
|
|
|
|
|
|
|
__simplify()
|
|
|
|
self.type = "fraction"
|
|
|
|
|
|
|
|
def __repr__(self):
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
return '<Gst.Fraction %s>' % (str(self))
|
2012-08-08 17:59:09 +00:00
|
|
|
|
|
|
|
def __value__(self):
|
|
|
|
return self.num / self.denom
|
|
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
|
if isinstance(other, Fraction):
|
|
|
|
return self.num * other.denom == other.num * self.denom
|
|
|
|
return False
|
|
|
|
|
|
|
|
def __ne__(self, other):
|
|
|
|
return not self.__eq__(other)
|
|
|
|
|
|
|
|
def __mul__(self, other):
|
|
|
|
if isinstance(other, Fraction):
|
|
|
|
return Fraction(self.num * other.num,
|
|
|
|
self.denom * other.denom)
|
|
|
|
elif isinstance(other, int):
|
|
|
|
return Fraction(self.num * other, self.denom)
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
raise TypeError("%s is not supported, use Gst.Fraction or int." %
|
|
|
|
(type(other)))
|
2012-08-08 17:59:09 +00:00
|
|
|
|
|
|
|
__rmul__ = __mul__
|
|
|
|
|
2014-03-23 09:34:10 +00:00
|
|
|
def __truediv__(self, other):
|
2012-08-08 17:59:09 +00:00
|
|
|
if isinstance(other, Fraction):
|
|
|
|
return Fraction(self.num * other.denom,
|
|
|
|
self.denom * other.num)
|
|
|
|
elif isinstance(other, int):
|
|
|
|
return Fraction(self.num, self.denom * other)
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
return TypeError("%s is not supported, use Gst.Fraction or int." %
|
|
|
|
(type(other)))
|
2012-08-08 17:59:09 +00:00
|
|
|
|
2014-03-23 09:34:10 +00:00
|
|
|
__div__ = __truediv__
|
|
|
|
|
|
|
|
def __rtruediv__(self, other):
|
2012-08-08 17:59:09 +00:00
|
|
|
if isinstance(other, int):
|
|
|
|
return Fraction(self.denom * other, self.num)
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
return TypeError("%s is not an int." % (type(other)))
|
2012-08-08 17:59:09 +00:00
|
|
|
|
2014-03-23 09:34:10 +00:00
|
|
|
__rdiv__ = __rtruediv__
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
def __float__(self):
|
|
|
|
return float(self.num) / float(self.denom)
|
|
|
|
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
def __str__(self):
|
|
|
|
return '%d/%d' % (self.num, self.denom)
|
|
|
|
|
2012-08-08 17:59:09 +00:00
|
|
|
Fraction = override(Fraction)
|
|
|
|
__all__.append('Fraction')
|
|
|
|
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
|
|
|
|
class IntRange(Gst.IntRange):
|
|
|
|
def __init__(self, r):
|
|
|
|
if not isinstance(r, range):
|
|
|
|
raise TypeError("%s is not a range." % (type(r)))
|
|
|
|
|
|
|
|
if (r.start >= r.stop):
|
|
|
|
raise TypeError("Range start must be smaller then stop")
|
|
|
|
|
|
|
|
if r.start % r.step != 0:
|
|
|
|
raise TypeError("Range start must be a multiple of the step")
|
|
|
|
|
|
|
|
if r.stop % r.step != 0:
|
|
|
|
raise TypeError("Range stop must be a multiple of the step")
|
|
|
|
|
|
|
|
self.range = r
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return '<Gst.IntRange [%d,%d,%d]>' % (self.range.start,
|
|
|
|
self.range.stop, self.range.step)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
if self.range.step == 1:
|
|
|
|
return '[%d,%d]' % (self.range.start, self.range.stop)
|
|
|
|
else:
|
|
|
|
return '[%d,%d,%d]' % (self.range.start, self.range.stop,
|
|
|
|
self.range.step)
|
|
|
|
|
2017-07-24 21:06:06 +00:00
|
|
|
def __eq__(self, other):
|
|
|
|
if isinstance(other, range):
|
|
|
|
return self.range == other
|
|
|
|
elif isinstance(other, IntRange):
|
|
|
|
return self.range == other.range
|
|
|
|
return False
|
|
|
|
|
2017-05-21 16:06:25 +00:00
|
|
|
if sys.version_info >= (3, 0):
|
|
|
|
IntRange = override(IntRange)
|
|
|
|
__all__.append('IntRange')
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Int64Range(Gst.Int64Range):
|
|
|
|
def __init__(self, r):
|
|
|
|
if not isinstance(r, range):
|
|
|
|
raise TypeError("%s is not a range." % (type(r)))
|
|
|
|
|
|
|
|
if (r.start >= r.stop):
|
|
|
|
raise TypeError("Range start must be smaller then stop")
|
|
|
|
|
|
|
|
if r.start % r.step != 0:
|
|
|
|
raise TypeError("Range start must be a multiple of the step")
|
|
|
|
|
|
|
|
if r.stop % r.step != 0:
|
|
|
|
raise TypeError("Range stop must be a multiple of the step")
|
|
|
|
|
|
|
|
self.range = r
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return '<Gst.Int64Range [%d,%d,%d]>' % (self.range.start,
|
|
|
|
self.range.stop, self.range.step)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
if self.range.step == 1:
|
|
|
|
return '(int64)[%d,%d]' % (self.range.start, self.range.stop)
|
|
|
|
else:
|
|
|
|
return '(int64)[%d,%d,%d]' % (self.range.start, self.range.stop,
|
|
|
|
self.range.step)
|
|
|
|
|
2017-07-24 21:06:06 +00:00
|
|
|
def __eq__(self, other):
|
|
|
|
if isinstance(other, range):
|
|
|
|
return self.range == other
|
|
|
|
elif isinstance(other, IntRange):
|
|
|
|
return self.range == other.range
|
|
|
|
return False
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
|
2017-07-25 20:17:54 +00:00
|
|
|
class Bitmask(Gst.Bitmask):
|
|
|
|
def __init__(self, v):
|
2019-11-19 13:07:09 +00:00
|
|
|
if not isinstance(v, int):
|
|
|
|
raise TypeError("%s is not an int." % (type(v)))
|
2017-07-25 20:17:54 +00:00
|
|
|
|
2019-11-19 13:07:09 +00:00
|
|
|
self.v = int(v)
|
2017-07-25 20:17:54 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return hex(self.v)
|
|
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
|
return self.v == other
|
|
|
|
|
|
|
|
|
|
|
|
Bitmask = override(Bitmask)
|
|
|
|
__all__.append('Bitmask')
|
|
|
|
|
|
|
|
|
2017-05-21 16:06:25 +00:00
|
|
|
if sys.version_info >= (3, 0):
|
|
|
|
Int64Range = override(Int64Range)
|
|
|
|
__all__.append('Int64Range')
|
overrides: Add more GstValue overrides
This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:
structure["range"] = Gst.IntRange(range(0,10,2)))
Same for the 64 bit variant. And when you do:
r = structure.get_value("range")
A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:
structure["range"] = Gst.DoubleRange(0,10.0)
structure["range"] =
Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5)
When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.
For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.
structure["list"] = Gst.ValueList([1,2,3,4])
structure["array"] = Gst.ValueArray([1,2,3,4)
Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:
list = Gst.ValueList([1,2,3,4])
array = Gst.ValueArray (list)
https://bugzilla.gnome.org/show_bug.cgi?id=753754
2017-03-23 16:21:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class DoubleRange(Gst.DoubleRange):
|
|
|
|
def __init__(self, start, stop):
|
|
|
|
self.start = float(start)
|
|
|
|
self.stop = float(stop)
|
|
|
|
|
|
|
|
if (start >= stop):
|
|
|
|
raise TypeError("Range start must be smaller then stop")
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return '<Gst.DoubleRange [%s,%s]>' % (str(self.start), str(self.stop))
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return '(double)[%s,%s]' % (str(self.range.start), str(self.range.stop))
|
|
|
|
|
|
|
|
|
|
|
|
DoubleRange = override(DoubleRange)
|
|
|
|
__all__.append('DoubleRange')
|
|
|
|
|
|
|
|
|
|
|
|
class FractionRange(Gst.FractionRange):
|
|
|
|
def __init__(self, start, stop):
|
|
|
|
if not isinstance(start, Gst.Fraction):
|
|
|
|
raise TypeError("%s is not a Gst.Fraction." % (type(start)))
|
|
|
|
|
|
|
|
if not isinstance(stop, Gst.Fraction):
|
|
|
|
raise TypeError("%s is not a Gst.Fraction." % (type(stop)))
|
|
|
|
|
|
|
|
if (float(start) >= float(stop)):
|
|
|
|
raise TypeError("Range start must be smaller then stop")
|
|
|
|
|
|
|
|
self.start = start
|
|
|
|
self.stop = stop
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return '<Gst.FractionRange [%s,%s]>' % (str(self.start),
|
|
|
|
str(self.stop))
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return '(fraction)[%s,%s]' % (str(self.start), str(self.stop))
|
|
|
|
|
|
|
|
FractionRange = override(FractionRange)
|
|
|
|
__all__.append('FractionRange')
|
|
|
|
|
|
|
|
|
|
|
|
class ValueArray(Gst.ValueArray):
|
|
|
|
def __init__(self, array):
|
|
|
|
self.array = list(array)
|
|
|
|
|
|
|
|
def __getitem__(self, index):
|
|
|
|
return self.array[index]
|
|
|
|
|
|
|
|
def __setitem__(self, index, value):
|
|
|
|
self.array[index] = value
|
|
|
|
|
|
|
|
def __len__(self):
|
|
|
|
return len(self.array)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return '<' + ','.join(map(str,self.array)) + '>'
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return '<Gst.ValueArray %s>' % (str(self))
|
|
|
|
|
|
|
|
ValueArray = override(ValueArray)
|
|
|
|
__all__.append('ValueArray')
|
|
|
|
|
|
|
|
|
|
|
|
class ValueList(Gst.ValueList):
|
|
|
|
def __init__(self, array):
|
|
|
|
self.array = list(array)
|
|
|
|
|
|
|
|
def __getitem__(self, index):
|
|
|
|
return self.array[index]
|
|
|
|
|
|
|
|
def __setitem__(self, index, value):
|
|
|
|
self.array[index] = value
|
|
|
|
|
|
|
|
def __len__(self):
|
|
|
|
return len(self.array)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return '{' + ','.join(map(str,self.array)) + '}'
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return '<Gst.ValueList %s>' % (str(self))
|
|
|
|
|
|
|
|
ValueList = override(ValueList)
|
|
|
|
__all__.append('ValueList')
|
|
|
|
|
2019-04-10 22:42:49 +00:00
|
|
|
# From https://docs.python.org/3/library/itertools.html
|
|
|
|
|
|
|
|
|
|
|
|
def pairwise(iterable):
|
|
|
|
a, b = itertools.tee(iterable)
|
|
|
|
next(b, None)
|
|
|
|
return zip(a, b)
|
|
|
|
|
2019-04-05 13:58:38 +00:00
|
|
|
class MapInfo:
|
|
|
|
def __init__(self):
|
|
|
|
self.memory = None
|
|
|
|
self.flags = Gst.MapFlags(0)
|
|
|
|
self.size = 0
|
|
|
|
self.maxsize = 0
|
|
|
|
self.data = None
|
|
|
|
self.user_data = None
|
|
|
|
self.__parent__ = None
|
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __exit__(self, type, value, tb):
|
|
|
|
self.__parent__.unmap(self)
|
|
|
|
|
|
|
|
__all__.append("MapInfo")
|
|
|
|
|
|
|
|
class Buffer(Gst.Buffer):
|
|
|
|
|
|
|
|
def map_range(self, idx, length, flags):
|
2019-12-10 14:58:01 +00:00
|
|
|
mapinfo = MapInfo()
|
2019-04-05 13:58:38 +00:00
|
|
|
if (_gi_gst.buffer_override_map_range(self, mapinfo, idx, length, int(flags))):
|
|
|
|
mapinfo.__parent__ = self
|
|
|
|
return (mapinfo)
|
2019-12-10 14:58:01 +00:00
|
|
|
raise MapError('MappingError','Buffer mapping was not successfull')
|
2019-04-05 13:58:38 +00:00
|
|
|
|
|
|
|
def map(self, flags):
|
|
|
|
mapinfo = MapInfo()
|
2019-12-10 14:58:01 +00:00
|
|
|
if _gi_gst.buffer_override_map(self, mapinfo, int(flags)):
|
2019-04-05 13:58:38 +00:00
|
|
|
mapinfo.__parent__ = self
|
2019-12-10 14:58:01 +00:00
|
|
|
return mapinfo
|
|
|
|
raise MapError('MappingError','Buffer mapping was not successfull')
|
2019-04-05 13:58:38 +00:00
|
|
|
|
|
|
|
def unmap(self, mapinfo):
|
2019-12-10 14:58:01 +00:00
|
|
|
if _gi_gst.buffer_override_unmap(self, mapinfo) is not True:
|
|
|
|
raise MapError('UnmappingError','Buffer unmapping was not successfull')
|
2019-04-05 13:58:38 +00:00
|
|
|
|
|
|
|
Buffer = override(Buffer)
|
|
|
|
__all__.append('Buffer')
|
|
|
|
|
|
|
|
class Memory(Gst.Memory):
|
|
|
|
|
|
|
|
def map(self, flags):
|
|
|
|
mapinfo = MapInfo()
|
|
|
|
if (_gi_gst.memory_override_map(self, mapinfo, int(flags))):
|
|
|
|
mapinfo.__parent__ = self
|
|
|
|
return (mapinfo)
|
2019-12-10 14:58:01 +00:00
|
|
|
raise MapError('MappingError','Memory mapping was not successfull')
|
2019-04-05 13:58:38 +00:00
|
|
|
|
|
|
|
def unmap(self, mapinfo):
|
2019-12-10 14:58:01 +00:00
|
|
|
return _gi_gst.memory_override_unmap(self, mapinfo)
|
2019-04-05 13:58:38 +00:00
|
|
|
|
|
|
|
Memory = override(Memory)
|
|
|
|
__all__.append('Memory')
|
2019-04-10 22:42:49 +00:00
|
|
|
|
2013-12-03 22:49:11 +00:00
|
|
|
def TIME_ARGS(time):
|
|
|
|
if time == Gst.CLOCK_TIME_NONE:
|
|
|
|
return "CLOCK_TIME_NONE"
|
|
|
|
|
|
|
|
return "%u:%02u:%02u.%09u" % (time / (Gst.SECOND * 60 * 60),
|
|
|
|
(time / (Gst.SECOND * 60)) % 60,
|
|
|
|
(time / Gst.SECOND) % 60,
|
|
|
|
time % Gst.SECOND)
|
|
|
|
__all__.append('TIME_ARGS')
|
|
|
|
|
2018-10-30 23:41:31 +00:00
|
|
|
from gi.overrides import _gi_gst
|
2012-08-20 02:40:06 +00:00
|
|
|
_gi_gst
|
2012-08-08 17:59:09 +00:00
|
|
|
|
2012-09-27 12:41:29 +00:00
|
|
|
# maybe more python and less C some day if core turns a bit more introspection
|
|
|
|
# and binding friendly in the debug area
|
2015-11-08 10:56:28 +00:00
|
|
|
Gst.trace = _gi_gst.trace
|
2012-09-27 12:41:29 +00:00
|
|
|
Gst.log = _gi_gst.log
|
|
|
|
Gst.debug = _gi_gst.debug
|
|
|
|
Gst.info = _gi_gst.info
|
|
|
|
Gst.warning = _gi_gst.warning
|
|
|
|
Gst.error = _gi_gst.error
|
|
|
|
Gst.fixme = _gi_gst.fixme
|
|
|
|
Gst.memdump = _gi_gst.memdump
|
2015-04-15 17:55:16 +00:00
|
|
|
|
|
|
|
# Make sure PyGst is not usable if GStreamer has not been initialized
|
2015-04-24 08:35:14 +00:00
|
|
|
class NotInitialized(Exception):
|
2015-04-15 17:55:16 +00:00
|
|
|
pass
|
2015-04-24 08:35:14 +00:00
|
|
|
__all__.append('NotInitialized')
|
2015-04-15 17:55:16 +00:00
|
|
|
|
|
|
|
def fake_method(*args):
|
2015-04-24 08:35:14 +00:00
|
|
|
raise NotInitialized("Please call Gst.init(argv) before using GStreamer")
|
2015-04-15 17:55:16 +00:00
|
|
|
|
|
|
|
|
2015-04-24 08:27:47 +00:00
|
|
|
real_functions = [o for o in inspect.getmembers(Gst) if isinstance(o[1], type(Gst.init))]
|
2015-04-15 17:55:16 +00:00
|
|
|
|
|
|
|
class_methods = []
|
2015-04-24 08:27:47 +00:00
|
|
|
for cname_klass in [o for o in inspect.getmembers(Gst) if isinstance(o[1], type(Gst.Element)) or isinstance(o[1], type(Gst.Caps))]:
|
2015-04-15 17:55:16 +00:00
|
|
|
class_methods.append((cname_klass,
|
|
|
|
[(o, cname_klass[1].__dict__[o])
|
|
|
|
for o in cname_klass[1].__dict__
|
|
|
|
if isinstance(cname_klass[1].__dict__[o], type(Gst.init))]))
|
|
|
|
|
|
|
|
def init_pygst():
|
|
|
|
for fname, function in real_functions:
|
|
|
|
if fname not in ["init", "init_check", "deinit"]:
|
|
|
|
setattr(Gst, fname, function)
|
|
|
|
|
|
|
|
for cname_class, methods in class_methods:
|
|
|
|
for mname, method in methods:
|
|
|
|
setattr(cname_class[1], mname, method)
|
|
|
|
|
|
|
|
|
|
|
|
def deinit_pygst():
|
|
|
|
for fname, func in real_functions:
|
2019-01-30 18:45:21 +00:00
|
|
|
if fname not in ["init", "init_check", "deinit", "is_initialized"]:
|
2015-04-15 17:55:16 +00:00
|
|
|
setattr(Gst, fname, fake_method)
|
|
|
|
for cname_class, methods in class_methods:
|
|
|
|
for mname, method in methods:
|
|
|
|
setattr(cname_class[1], mname, fake_method)
|
|
|
|
|
|
|
|
real_init = Gst.init
|
|
|
|
def init(argv):
|
|
|
|
init_pygst()
|
|
|
|
return real_init(argv)
|
|
|
|
Gst.init = init
|
|
|
|
|
|
|
|
real_init_check = Gst.init_check
|
|
|
|
def init_check(argv):
|
|
|
|
init_pygst()
|
|
|
|
return real_init_check(argv)
|
|
|
|
Gst.init_check = init_check
|
|
|
|
|
|
|
|
real_deinit = Gst.deinit
|
|
|
|
def deinit():
|
|
|
|
deinit_pygst()
|
|
|
|
return real_deinit()
|
|
|
|
|
|
|
|
Gst.deinit = deinit
|
|
|
|
|
2017-09-25 00:43:49 +00:00
|
|
|
if not Gst.is_initialized():
|
|
|
|
deinit_pygst()
|