Update
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import gi
|
||||
import os
|
||||
import sys
|
||||
import imp
|
||||
from pathlib import Path
|
||||
|
||||
# Remove this dummy module the python path and
|
||||
# try to import the actual gi module
|
||||
sys.path.remove(str(Path(__file__).parents[1]))
|
||||
del sys.modules["gi"]
|
||||
import gi
|
||||
|
||||
|
||||
class GstOverrideImport:
|
||||
def find_module(self, fullname, path=None, target=None):
|
||||
if fullname.startswith('gi.overrides'):
|
||||
fp = None
|
||||
try:
|
||||
fp, _, _ = imp.find_module(fullname.split(
|
||||
'.')[-1], os.environ.get('_GI_OVERRIDES_PATH', '').split(os.pathsep),)
|
||||
except ImportError:
|
||||
return None
|
||||
finally:
|
||||
if fp:
|
||||
fp.close()
|
||||
return self
|
||||
return None
|
||||
|
||||
def load_module(self, name):
|
||||
if name in sys.modules:
|
||||
return sys.modules[name]
|
||||
|
||||
fp, pathname, description = imp.find_module(name.split(
|
||||
'.')[-1], os.environ.get('_GI_OVERRIDES_PATH', '').split(os.pathsep),)
|
||||
|
||||
try:
|
||||
module = imp.load_module(name, fp, pathname, description)
|
||||
finally:
|
||||
if fp:
|
||||
fp.close()
|
||||
sys.modules[name] = module
|
||||
return module
|
||||
|
||||
|
||||
sys.meta_path.insert(0, GstOverrideImport())
|
||||
@@ -0,0 +1 @@
|
||||
subdir('overrides')
|
||||
@@ -0,0 +1,744 @@
|
||||
# -*- 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
|
||||
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
import inspect
|
||||
import itertools
|
||||
import weakref
|
||||
from ..overrides import override
|
||||
from ..module import get_introspection_module
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
|
||||
Gst = get_introspection_module('Gst')
|
||||
|
||||
__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 \
|
||||
port your app to Gst 1 or greater. gst-python is the recommended \
|
||||
python module to use with Gst 0.10"
|
||||
|
||||
warnings.warn(warn_msg, RuntimeWarning)
|
||||
|
||||
|
||||
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')
|
||||
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
|
||||
Bin = override(Bin)
|
||||
__all__.append('Bin')
|
||||
|
||||
class Caps(Gst.Caps):
|
||||
|
||||
def __nonzero__(self):
|
||||
return not self.is_empty()
|
||||
|
||||
def __new__(cls, *args):
|
||||
if not args:
|
||||
return Caps.new_empty()
|
||||
elif len(args) > 1:
|
||||
raise TypeError("wrong arguments when creating GstCaps object")
|
||||
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
|
||||
|
||||
raise TypeError("wrong arguments when creating GstCaps object")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
return super(Caps, self).__init__()
|
||||
|
||||
def __str__(self):
|
||||
return self.to_string()
|
||||
|
||||
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()
|
||||
|
||||
Caps = override(Caps)
|
||||
__all__.append('Caps')
|
||||
|
||||
class PadFunc:
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __call__(self, pad, parent, obj):
|
||||
if isinstance(self.func, weakref.WeakMethod):
|
||||
func = self.func()
|
||||
else:
|
||||
func = self.func
|
||||
|
||||
try:
|
||||
res = func(pad, obj)
|
||||
except TypeError:
|
||||
try:
|
||||
res = func(pad, parent, obj)
|
||||
except TypeError:
|
||||
raise TypeError("Invalid method %s, 2 or 3 arguments required"
|
||||
% func)
|
||||
|
||||
return res
|
||||
|
||||
class Pad(Gst.Pad):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Gst.Pad, self).__init__(*args, **kwargs)
|
||||
|
||||
def set_chain_function(self, func):
|
||||
self.set_chain_function_full(PadFunc(func), None)
|
||||
|
||||
def set_event_function(self, func):
|
||||
self.set_event_function_full(PadFunc(func), None)
|
||||
|
||||
def set_query_function(self, func):
|
||||
self.set_query_function_full(PadFunc(func), None)
|
||||
|
||||
def query_caps(self, filter=None):
|
||||
return Gst.Pad.query_caps(self, filter)
|
||||
|
||||
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
|
||||
|
||||
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')
|
||||
|
||||
class GhostPad(Gst.GhostPad):
|
||||
def __init__(self, name, target=None, direction=None):
|
||||
if direction is None:
|
||||
if target is None:
|
||||
raise TypeError('you must pass at least one of target '
|
||||
'and direction')
|
||||
direction = target.props.direction
|
||||
|
||||
Gst.GhostPad.__init__(self, name=name, direction=direction)
|
||||
self.construct()
|
||||
if target is not None:
|
||||
self.set_target(target)
|
||||
|
||||
def query_caps(self, filter=None):
|
||||
return Gst.GhostPad.query_caps(self, filter)
|
||||
|
||||
GhostPad = override(GhostPad)
|
||||
__all__.append('GhostPad')
|
||||
|
||||
class IteratorError(Exception):
|
||||
pass
|
||||
__all__.append('IteratorError')
|
||||
|
||||
class AddError(Exception):
|
||||
pass
|
||||
__all__.append('AddError')
|
||||
|
||||
class LinkError(Exception):
|
||||
pass
|
||||
__all__.append('LinkError')
|
||||
|
||||
class MapError(Exception):
|
||||
pass
|
||||
__all__.append('MapError')
|
||||
|
||||
|
||||
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')
|
||||
|
||||
|
||||
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")
|
||||
|
||||
@classmethod
|
||||
def make(cls, factory_name, instance_name=None):
|
||||
return Gst.ElementFactory.make(factory_name, instance_name)
|
||||
|
||||
class Pipeline(Gst.Pipeline):
|
||||
def __init__(self, name=None):
|
||||
Gst.Pipeline.__init__(self, name=name)
|
||||
|
||||
Pipeline = override(Pipeline)
|
||||
__all__.append('Pipeline')
|
||||
|
||||
class Structure(Gst.Structure):
|
||||
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")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.get_value(key)
|
||||
|
||||
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
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
return self.set_value(key, value)
|
||||
|
||||
def __str__(self):
|
||||
return self.to_string()
|
||||
|
||||
Structure = override(Structure)
|
||||
__all__.append('Structure')
|
||||
|
||||
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):
|
||||
return '<Gst.Fraction %s>' % (str(self))
|
||||
|
||||
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)
|
||||
raise TypeError("%s is not supported, use Gst.Fraction or int." %
|
||||
(type(other)))
|
||||
|
||||
__rmul__ = __mul__
|
||||
|
||||
def __truediv__(self, other):
|
||||
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)
|
||||
return TypeError("%s is not supported, use Gst.Fraction or int." %
|
||||
(type(other)))
|
||||
|
||||
__div__ = __truediv__
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
if isinstance(other, int):
|
||||
return Fraction(self.denom * other, self.num)
|
||||
return TypeError("%s is not an int." % (type(other)))
|
||||
|
||||
__rdiv__ = __rtruediv__
|
||||
|
||||
def __float__(self):
|
||||
return float(self.num) / float(self.denom)
|
||||
|
||||
def __str__(self):
|
||||
return '%d/%d' % (self.num, self.denom)
|
||||
|
||||
Fraction = override(Fraction)
|
||||
__all__.append('Fraction')
|
||||
|
||||
|
||||
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)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, range):
|
||||
return self.range == other
|
||||
elif isinstance(other, IntRange):
|
||||
return self.range == other.range
|
||||
return False
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
IntRange = override(IntRange)
|
||||
__all__.append('IntRange')
|
||||
|
||||
|
||||
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)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, range):
|
||||
return self.range == other
|
||||
elif isinstance(other, IntRange):
|
||||
return self.range == other.range
|
||||
return False
|
||||
|
||||
class Bitmask(Gst.Bitmask):
|
||||
def __init__(self, v):
|
||||
if not isinstance(v, int):
|
||||
raise TypeError("%s is not an int." % (type(v)))
|
||||
|
||||
self.v = int(v)
|
||||
|
||||
def __str__(self):
|
||||
return hex(self.v)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.v == other
|
||||
|
||||
|
||||
Bitmask = override(Bitmask)
|
||||
__all__.append('Bitmask')
|
||||
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
Int64Range = override(Int64Range)
|
||||
__all__.append('Int64Range')
|
||||
|
||||
|
||||
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')
|
||||
|
||||
# From https://docs.python.org/3/library/itertools.html
|
||||
|
||||
|
||||
def pairwise(iterable):
|
||||
a, b = itertools.tee(iterable)
|
||||
next(b, None)
|
||||
return zip(a, b)
|
||||
|
||||
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 __iter__(self):
|
||||
# Make it behave like a tuple similar to the PyGObject generated API for
|
||||
# the `Gst.Buffer.map()` and friends.
|
||||
for i in (self.__parent__ is not None, self):
|
||||
yield i
|
||||
|
||||
def __enter__(self):
|
||||
if not self.__parent__:
|
||||
raise MapError('MappingError', 'Mapping was not successful')
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, tb):
|
||||
if not self.__parent__.unmap(self):
|
||||
raise MapError('MappingError', 'Unmapping was not successful')
|
||||
|
||||
__all__.append("MapInfo")
|
||||
|
||||
class Buffer(Gst.Buffer):
|
||||
|
||||
def map_range(self, idx, length, flags):
|
||||
mapinfo = MapInfo()
|
||||
if (_gi_gst.buffer_override_map_range(self, mapinfo, idx, length, int(flags))):
|
||||
mapinfo.__parent__ = self
|
||||
|
||||
return mapinfo
|
||||
|
||||
def map(self, flags):
|
||||
mapinfo = MapInfo()
|
||||
if _gi_gst.buffer_override_map(self, mapinfo, int(flags)):
|
||||
mapinfo.__parent__ = self
|
||||
|
||||
return mapinfo
|
||||
|
||||
def unmap(self, mapinfo):
|
||||
mapinfo.__parent__ = None
|
||||
return _gi_gst.buffer_override_unmap(self, mapinfo)
|
||||
|
||||
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
|
||||
|
||||
def unmap(self, mapinfo):
|
||||
mapinfo.__parent__ = None
|
||||
return _gi_gst.memory_override_unmap(self, mapinfo)
|
||||
|
||||
Memory = override(Memory)
|
||||
__all__.append('Memory')
|
||||
|
||||
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')
|
||||
|
||||
from gi.overrides import _gi_gst
|
||||
_gi_gst
|
||||
|
||||
# maybe more python and less C some day if core turns a bit more introspection
|
||||
# and binding friendly in the debug area
|
||||
Gst.trace = _gi_gst.trace
|
||||
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
|
||||
|
||||
# Make sure PyGst is not usable if GStreamer has not been initialized
|
||||
class NotInitialized(Exception):
|
||||
pass
|
||||
__all__.append('NotInitialized')
|
||||
|
||||
def fake_method(*args):
|
||||
raise NotInitialized("Please call Gst.init(argv) before using GStreamer")
|
||||
|
||||
|
||||
real_functions = [o for o in inspect.getmembers(Gst) if isinstance(o[1], type(Gst.init))]
|
||||
|
||||
class_methods = []
|
||||
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))]:
|
||||
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:
|
||||
if fname not in ["init", "init_check", "deinit", "is_initialized"]:
|
||||
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
|
||||
|
||||
if not Gst.is_initialized():
|
||||
deinit_pygst()
|
||||
@@ -0,0 +1,16 @@
|
||||
from ..module import get_introspection_module
|
||||
|
||||
import gi
|
||||
gi.require_version('Gst', '1.0')
|
||||
|
||||
from gi.repository import Gst # noqa
|
||||
|
||||
GstAudio = get_introspection_module('GstAudio')
|
||||
__all__ = []
|
||||
|
||||
|
||||
def __audio_info_from_caps(*args):
|
||||
raise NotImplementedError('AudioInfo.from_caps was removed, use AudioInfo.new_from_caps instead')
|
||||
|
||||
|
||||
GstAudio.AudioInfo.from_caps = __audio_info_from_caps
|
||||
@@ -0,0 +1,90 @@
|
||||
# -*- Mode: Python; py-indent-offset: 4 -*-
|
||||
# vim: tabstop=4 shiftwidth=4 expandtab
|
||||
#
|
||||
# Gst.py
|
||||
#
|
||||
# Copyright (C) 2012 Alessandro Decina <alessandro.d@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, write to the
|
||||
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
from ..overrides import override as override_
|
||||
from ..module import get_introspection_module
|
||||
|
||||
import gi
|
||||
gi.require_version('Gst', '1.0')
|
||||
|
||||
from gi.repository import Gst # noqa
|
||||
|
||||
GstPbutils = get_introspection_module('GstPbutils')
|
||||
__all__ = []
|
||||
|
||||
|
||||
def override(cls):
|
||||
name = cls.__name__
|
||||
globals()[name] = override_(cls)
|
||||
__all__.append(name)
|
||||
|
||||
return cls
|
||||
|
||||
real_init = GstPbutils.pb_utils_init
|
||||
def init():
|
||||
if not Gst.is_initialized():
|
||||
raise RuntimeError("Gst.init() needs to be called before importing GstPbutils")
|
||||
|
||||
real_init()
|
||||
|
||||
@override
|
||||
class EncodingVideoProfile(GstPbutils.EncodingVideoProfile):
|
||||
def __init__(self, format, preset=None, restriction=None, presence=0):
|
||||
GstPbutils.EncodingVideoProfile.__init__(self)
|
||||
self.set_format(format)
|
||||
if preset is not None:
|
||||
self.set_preset(preset)
|
||||
if restriction is None:
|
||||
restriction = Gst.Caps('ANY')
|
||||
self.set_restriction(restriction)
|
||||
self.set_presence(presence)
|
||||
|
||||
@override
|
||||
class EncodingAudioProfile(GstPbutils.EncodingAudioProfile):
|
||||
def __init__(self, format, preset=None, restriction=None, presence=0):
|
||||
GstPbutils.EncodingAudioProfile.__init__(self)
|
||||
self.set_format(format)
|
||||
if preset is not None:
|
||||
self.set_preset(preset)
|
||||
if restriction is None:
|
||||
restriction = Gst.Caps('ANY')
|
||||
self.set_restriction(restriction)
|
||||
self.set_presence(presence)
|
||||
|
||||
@override
|
||||
class EncodingContainerProfile(GstPbutils.EncodingContainerProfile):
|
||||
def __init__(self, name, description, format, preset=None):
|
||||
GstPbutils.EncodingContainerProfile.__init__(self)
|
||||
self.set_format(format)
|
||||
if name is not None:
|
||||
self.set_name(name)
|
||||
if description is not None:
|
||||
self.set_description(description)
|
||||
if preset is not None:
|
||||
self.set_preset(preset)
|
||||
|
||||
GstPbutils.pb_utils_init = init
|
||||
GstPbutils.init = init
|
||||
if Gst.is_initialized():
|
||||
init()
|
||||
@@ -0,0 +1,16 @@
|
||||
from ..module import get_introspection_module
|
||||
|
||||
import gi
|
||||
gi.require_version('Gst', '1.0')
|
||||
|
||||
from gi.repository import Gst # noqa
|
||||
|
||||
GstVideo = get_introspection_module('GstVideo')
|
||||
__all__ = []
|
||||
|
||||
|
||||
def __video_info_from_caps(*args):
|
||||
raise NotImplementedError('VideoInfo.from_caps was removed, use VideoInfo.new_from_caps instead')
|
||||
|
||||
|
||||
GstVideo.VideoInfo.from_caps = __video_info_from_caps
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
pysources = ['Gst.py', 'GstPbutils.py', 'GstVideo.py', 'GstAudio.py']
|
||||
install_data(pysources,
|
||||
install_dir: pygi_override_dir)
|
||||
|
||||
gstpython = python.extension_module('_gi_gst',
|
||||
sources: ['gstmodule.c'],
|
||||
install: true,
|
||||
install_dir : pygi_override_dir,
|
||||
include_directories : [configinc],
|
||||
dependencies : [gst_dep, python_dep, pygobject_dep])
|
||||
|
||||
env = environment()
|
||||
env.prepend('_GI_OVERRIDES_PATH', [
|
||||
meson.current_source_dir(),
|
||||
meson.current_build_dir()
|
||||
])
|
||||
meson.add_devenv(env)
|
||||
Reference in New Issue
Block a user