mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
The "yes, you can write chain based elements in Python" commit.
Original commit message from CVS: The "yes, you can write chain based elements in Python" commit. AKA The "oh my, that is a slow rot13" commit. AKA The "puddle from a stream of leaking bits" commit.
This commit is contained in:
parent
fac6f91e8d
commit
0d60c9d38a
14 changed files with 876 additions and 30 deletions
|
@ -28,9 +28,8 @@ from gobject import GObject
|
|||
def update(sender, *args):
|
||||
print sender.get_name(), args
|
||||
|
||||
def main():
|
||||
"A GStreamer based cp(1) with stats"
|
||||
#gst_debug_set_categories(-1)
|
||||
def filter(filters):
|
||||
"A GStreamer copy pipeline which can add arbitrary filters"
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print 'usage: %s source dest' % (sys.argv[0])
|
||||
|
@ -45,28 +44,20 @@ def main():
|
|||
return -1
|
||||
filesrc.set_property('location', sys.argv[1])
|
||||
|
||||
stats = gst_elementfactory_make ('statistics', 'stats');
|
||||
if not stats:
|
||||
print 'could not find plugin \"statistics\"'
|
||||
return -1
|
||||
stats.set_property('silent', 0)
|
||||
stats.set_property('buffer_update_freq', 1)
|
||||
stats.set_property('update_on_eos', 1)
|
||||
#GObject.connect(stats, 'update', update)
|
||||
|
||||
filesink = gst_elementfactory_make ('disksink', 'sink')
|
||||
if not filesink:
|
||||
print 'could not find plugin \"disksink\"'
|
||||
return -1
|
||||
filesink.set_property('location', sys.argv[2])
|
||||
|
||||
elements = [filesrc] + filters + [filesink]
|
||||
# add objects to the main pipeline
|
||||
for e in (filesrc, stats, filesink):
|
||||
for e in elements:
|
||||
bin.add(e)
|
||||
|
||||
# connect the elements
|
||||
previous = None
|
||||
for e in (filesrc, stats, filesink):
|
||||
for e in elements:
|
||||
if previous:
|
||||
previous.connect('src', e, 'sink')
|
||||
previous = e
|
||||
|
@ -81,6 +72,21 @@ def main():
|
|||
|
||||
return 0
|
||||
|
||||
def main():
|
||||
"A GStreamer based cp(1) with stats"
|
||||
gst_debug_set_categories(0)
|
||||
|
||||
stats = gst_elementfactory_make ('statistics', 'stats');
|
||||
if not stats:
|
||||
print 'could not find plugin \"statistics\"'
|
||||
return -1
|
||||
stats.set_property('silent', 0)
|
||||
stats.set_property('buffer_update_freq', 1)
|
||||
stats.set_property('update_on_eos', 1)
|
||||
#GObject.connect(stats, 'update', update)
|
||||
|
||||
return filter([stats])
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = main()
|
||||
sys.exit (ret)
|
||||
|
|
|
@ -43,12 +43,16 @@ class DVDPlay(object):
|
|||
print '***** a new pad %s was created' % pad.get_name()
|
||||
if pad.get_name()[:6] == 'video_':
|
||||
pad.connect(self.v_queue.get_pad('sink'))
|
||||
#self.pipeline.set_state(STATE_PAUSED)
|
||||
self.pipeline.add(self.v_thread)
|
||||
self.v_thread.set_state(STATE_PLAYING)
|
||||
#self.pipeline.set_state(STATE_PLAYING)
|
||||
elif pad.get_name() == 'private_stream_1.0':
|
||||
pad.connect(self.a_queue.get_pad('sink'))
|
||||
#self.pipeline.set_state(STATE_PAUSED)
|
||||
self.pipeline.add(self.a_thread)
|
||||
self.a_thread.set_state(STATE_PLAYING);
|
||||
#self.pipeline.set_state(STATE_PLAYING)
|
||||
else:
|
||||
print 'unknown pad: %s' % pad.get_name()
|
||||
|
||||
|
|
68
examples/gst/identity.py
Executable file
68
examples/gst/identity.py
Executable file
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env python2.2
|
||||
#
|
||||
# gst-python
|
||||
# Copyright (C) 2002 David I. Lehn
|
||||
#
|
||||
# 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: David I. Lehn <dlehn@vt.edu>
|
||||
#
|
||||
|
||||
import sys
|
||||
from gstreamer import *
|
||||
import gobject
|
||||
from cp import filter
|
||||
|
||||
class Identity(Element):
|
||||
def __init__(self):
|
||||
self.__gobject_init__()
|
||||
self.sinkpad = gst_pad_new('sink', PAD_SINK)
|
||||
self.add_pad(self.sinkpad)
|
||||
self.sinkpad.set_chain_function(self.chain)
|
||||
self.sinkpad.set_connect_function(self.pad_connect)
|
||||
|
||||
self.srcpad = gst_pad_new('src', PAD_SRC)
|
||||
self.add_pad(self.srcpad)
|
||||
self.srcpad.set_connect_function(self.pad_connect)
|
||||
|
||||
def get_bufferpool(self, pad):
|
||||
print 'get_bufferpool:', self, pad
|
||||
return self.srcpad.get_bufferpool()
|
||||
|
||||
def pad_connect(self, pad, caps):
|
||||
print 'pad_connect:', self, pad, caps
|
||||
return PAD_CONNECT_OK
|
||||
|
||||
def chain(self, pad, buf):
|
||||
self.srcpad.push(buf)
|
||||
|
||||
gobject.type_register(Identity)
|
||||
|
||||
def main():
|
||||
"A GStreamer Python subclassing example of an identity filter"
|
||||
gst_debug_set_categories(0)
|
||||
|
||||
identity = Identity()
|
||||
identity.set_name('identity')
|
||||
if not identity:
|
||||
print 'could not create \"Identity\" element'
|
||||
return -1
|
||||
|
||||
return filter([identity])
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = main()
|
||||
sys.exit (ret)
|
64
examples/gst/rot13.py
Executable file
64
examples/gst/rot13.py
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python2.2
|
||||
#
|
||||
# gst-python
|
||||
# Copyright (C) 2002 David I. Lehn
|
||||
#
|
||||
# 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: David I. Lehn <dlehn@vt.edu>
|
||||
#
|
||||
|
||||
import sys
|
||||
from gstreamer import *
|
||||
import gobject
|
||||
from identity import Identity
|
||||
from cp import filter
|
||||
|
||||
class Rot13(Identity):
|
||||
def chain(self, pad, buf):
|
||||
# override Identity's chain
|
||||
data = gst_buffer_get_data(buf)
|
||||
data2 = ''
|
||||
# waste cycles
|
||||
for c in data:
|
||||
if c.isalpha():
|
||||
if c.islower():
|
||||
a = 'a'
|
||||
else:
|
||||
a = 'A'
|
||||
c = chr((((ord(c) - ord(a)) + 13) % 26) + ord(a))
|
||||
data2 = data2 + c
|
||||
newbuf = gst_buffer_new()
|
||||
gst_buffer_set_data(newbuf, data2)
|
||||
self.srcpad.push(newbuf)
|
||||
|
||||
gobject.type_register(Rot13)
|
||||
|
||||
def main():
|
||||
"A GStreamer Python subclassing example of a rot13 filter"
|
||||
gst_debug_set_categories(0)
|
||||
|
||||
rot13 = Rot13()
|
||||
rot13.set_name('rot13')
|
||||
if not rot13:
|
||||
print 'could not create \"Rot13\" element'
|
||||
return -1
|
||||
|
||||
return filter([rot13])
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = main()
|
||||
sys.exit (ret)
|
|
@ -28,9 +28,8 @@ from gobject import GObject
|
|||
def update(sender, *args):
|
||||
print sender.get_name(), args
|
||||
|
||||
def main():
|
||||
"A GStreamer based cp(1) with stats"
|
||||
#gst_debug_set_categories(-1)
|
||||
def filter(filters):
|
||||
"A GStreamer copy pipeline which can add arbitrary filters"
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print 'usage: %s source dest' % (sys.argv[0])
|
||||
|
@ -45,28 +44,20 @@ def main():
|
|||
return -1
|
||||
filesrc.set_property('location', sys.argv[1])
|
||||
|
||||
stats = gst_elementfactory_make ('statistics', 'stats');
|
||||
if not stats:
|
||||
print 'could not find plugin \"statistics\"'
|
||||
return -1
|
||||
stats.set_property('silent', 0)
|
||||
stats.set_property('buffer_update_freq', 1)
|
||||
stats.set_property('update_on_eos', 1)
|
||||
#GObject.connect(stats, 'update', update)
|
||||
|
||||
filesink = gst_elementfactory_make ('disksink', 'sink')
|
||||
if not filesink:
|
||||
print 'could not find plugin \"disksink\"'
|
||||
return -1
|
||||
filesink.set_property('location', sys.argv[2])
|
||||
|
||||
elements = [filesrc] + filters + [filesink]
|
||||
# add objects to the main pipeline
|
||||
for e in (filesrc, stats, filesink):
|
||||
for e in elements:
|
||||
bin.add(e)
|
||||
|
||||
# connect the elements
|
||||
previous = None
|
||||
for e in (filesrc, stats, filesink):
|
||||
for e in elements:
|
||||
if previous:
|
||||
previous.connect('src', e, 'sink')
|
||||
previous = e
|
||||
|
@ -81,6 +72,21 @@ def main():
|
|||
|
||||
return 0
|
||||
|
||||
def main():
|
||||
"A GStreamer based cp(1) with stats"
|
||||
gst_debug_set_categories(0)
|
||||
|
||||
stats = gst_elementfactory_make ('statistics', 'stats');
|
||||
if not stats:
|
||||
print 'could not find plugin \"statistics\"'
|
||||
return -1
|
||||
stats.set_property('silent', 0)
|
||||
stats.set_property('buffer_update_freq', 1)
|
||||
stats.set_property('update_on_eos', 1)
|
||||
#GObject.connect(stats, 'update', update)
|
||||
|
||||
return filter([stats])
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = main()
|
||||
sys.exit (ret)
|
||||
|
|
|
@ -43,12 +43,16 @@ class DVDPlay(object):
|
|||
print '***** a new pad %s was created' % pad.get_name()
|
||||
if pad.get_name()[:6] == 'video_':
|
||||
pad.connect(self.v_queue.get_pad('sink'))
|
||||
#self.pipeline.set_state(STATE_PAUSED)
|
||||
self.pipeline.add(self.v_thread)
|
||||
self.v_thread.set_state(STATE_PLAYING)
|
||||
#self.pipeline.set_state(STATE_PLAYING)
|
||||
elif pad.get_name() == 'private_stream_1.0':
|
||||
pad.connect(self.a_queue.get_pad('sink'))
|
||||
#self.pipeline.set_state(STATE_PAUSED)
|
||||
self.pipeline.add(self.a_thread)
|
||||
self.a_thread.set_state(STATE_PLAYING);
|
||||
#self.pipeline.set_state(STATE_PLAYING)
|
||||
else:
|
||||
print 'unknown pad: %s' % pad.get_name()
|
||||
|
||||
|
|
68
examples/gstreamer/identity.py
Executable file
68
examples/gstreamer/identity.py
Executable file
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env python2.2
|
||||
#
|
||||
# gst-python
|
||||
# Copyright (C) 2002 David I. Lehn
|
||||
#
|
||||
# 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: David I. Lehn <dlehn@vt.edu>
|
||||
#
|
||||
|
||||
import sys
|
||||
from gstreamer import *
|
||||
import gobject
|
||||
from cp import filter
|
||||
|
||||
class Identity(Element):
|
||||
def __init__(self):
|
||||
self.__gobject_init__()
|
||||
self.sinkpad = gst_pad_new('sink', PAD_SINK)
|
||||
self.add_pad(self.sinkpad)
|
||||
self.sinkpad.set_chain_function(self.chain)
|
||||
self.sinkpad.set_connect_function(self.pad_connect)
|
||||
|
||||
self.srcpad = gst_pad_new('src', PAD_SRC)
|
||||
self.add_pad(self.srcpad)
|
||||
self.srcpad.set_connect_function(self.pad_connect)
|
||||
|
||||
def get_bufferpool(self, pad):
|
||||
print 'get_bufferpool:', self, pad
|
||||
return self.srcpad.get_bufferpool()
|
||||
|
||||
def pad_connect(self, pad, caps):
|
||||
print 'pad_connect:', self, pad, caps
|
||||
return PAD_CONNECT_OK
|
||||
|
||||
def chain(self, pad, buf):
|
||||
self.srcpad.push(buf)
|
||||
|
||||
gobject.type_register(Identity)
|
||||
|
||||
def main():
|
||||
"A GStreamer Python subclassing example of an identity filter"
|
||||
gst_debug_set_categories(0)
|
||||
|
||||
identity = Identity()
|
||||
identity.set_name('identity')
|
||||
if not identity:
|
||||
print 'could not create \"Identity\" element'
|
||||
return -1
|
||||
|
||||
return filter([identity])
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = main()
|
||||
sys.exit (ret)
|
64
examples/gstreamer/rot13.py
Executable file
64
examples/gstreamer/rot13.py
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python2.2
|
||||
#
|
||||
# gst-python
|
||||
# Copyright (C) 2002 David I. Lehn
|
||||
#
|
||||
# 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: David I. Lehn <dlehn@vt.edu>
|
||||
#
|
||||
|
||||
import sys
|
||||
from gstreamer import *
|
||||
import gobject
|
||||
from identity import Identity
|
||||
from cp import filter
|
||||
|
||||
class Rot13(Identity):
|
||||
def chain(self, pad, buf):
|
||||
# override Identity's chain
|
||||
data = gst_buffer_get_data(buf)
|
||||
data2 = ''
|
||||
# waste cycles
|
||||
for c in data:
|
||||
if c.isalpha():
|
||||
if c.islower():
|
||||
a = 'a'
|
||||
else:
|
||||
a = 'A'
|
||||
c = chr((((ord(c) - ord(a)) + 13) % 26) + ord(a))
|
||||
data2 = data2 + c
|
||||
newbuf = gst_buffer_new()
|
||||
gst_buffer_set_data(newbuf, data2)
|
||||
self.srcpad.push(newbuf)
|
||||
|
||||
gobject.type_register(Rot13)
|
||||
|
||||
def main():
|
||||
"A GStreamer Python subclassing example of a rot13 filter"
|
||||
gst_debug_set_categories(0)
|
||||
|
||||
rot13 = Rot13()
|
||||
rot13.set_name('rot13')
|
||||
if not rot13:
|
||||
print 'could not create \"Rot13\" element'
|
||||
return -1
|
||||
|
||||
return filter([rot13])
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = main()
|
||||
sys.exit (ret)
|
16
gst/gst.defs
16
gst/gst.defs
|
@ -3457,3 +3457,19 @@
|
|||
)
|
||||
|
||||
|
||||
(define-function gst_buffer_get_data
|
||||
(c-name "gst_buffer_get_data")
|
||||
(return-type "char*")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
)
|
||||
)
|
||||
|
||||
(define-function gst_buffer_set_data
|
||||
(c-name "gst_buffer_set_data")
|
||||
(return-type "none")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
'("char*" "data")
|
||||
)
|
||||
)
|
||||
|
|
|
@ -3457,3 +3457,19 @@
|
|||
)
|
||||
|
||||
|
||||
(define-function gst_buffer_get_data
|
||||
(c-name "gst_buffer_get_data")
|
||||
(return-type "char*")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
)
|
||||
)
|
||||
|
||||
(define-function gst_buffer_set_data
|
||||
(c-name "gst_buffer_set_data")
|
||||
(return-type "none")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
'("char*" "data")
|
||||
)
|
||||
)
|
||||
|
|
|
@ -28,6 +28,38 @@ headers
|
|||
#include "pygobject.h"
|
||||
#include <gst/gst.h>
|
||||
|
||||
typedef struct {
|
||||
PyGObject *pad;
|
||||
PyObject *connect_function;
|
||||
PyObject *chain_function;
|
||||
} PyGstPadPrivate;
|
||||
|
||||
static PyGstPadPrivate*
|
||||
pad_private(GstPad *pad)
|
||||
{
|
||||
return (PyGstPadPrivate*)gst_pad_get_element_private(pad);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
%%
|
||||
modulename gstreamer
|
||||
%%
|
||||
import gobject.GObject as PyGObject_Type
|
||||
%%
|
||||
|
@ -35,5 +67,222 @@ ignore-glob
|
|||
_*
|
||||
gstreamer_*init
|
||||
*_get_type
|
||||
|
||||
%%
|
||||
override gst_pad_set_connect_function kwargs
|
||||
|
||||
static GstPadConnectReturn
|
||||
call_connect_function (GstPad *pad, GstCaps *caps)
|
||||
{
|
||||
PyObject *function;
|
||||
PyObject *retval;
|
||||
|
||||
function = pad_private(pad)->connect_function;
|
||||
|
||||
retval = (PyObject*)PyObject_CallFunction (function,
|
||||
"OO",
|
||||
pad_private(pad)->pad,
|
||||
PyCObject_FromVoidPtr (caps, NULL));
|
||||
|
||||
if (PyErr_Occurred ()) {
|
||||
PyErr_Print ();
|
||||
return GST_PAD_CONNECT_REFUSED;
|
||||
}
|
||||
|
||||
return PyInt_AsLong(retval);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_pad_set_connect_function (PyGObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "connect_function", NULL };
|
||||
PyObject *connect_function;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.set_connect_funcion",
|
||||
kwlist,
|
||||
&connect_function)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(connect_function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "connect_function not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(connect_function);
|
||||
py_pad_private(self)->connect_function = connect_function;
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
gst_pad_set_connect_function(pad, call_connect_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_pad_set_chain_function kwargs
|
||||
|
||||
static void
|
||||
call_chain_function (GstPad *pad, GstBuffer *buf)
|
||||
{
|
||||
PyObject *function;
|
||||
|
||||
function = pad_private(pad)->chain_function;
|
||||
|
||||
PyObject_CallFunction (function,
|
||||
"OO",
|
||||
pad_private(pad)->pad,
|
||||
PyCObject_FromVoidPtr (buf, NULL));
|
||||
|
||||
if (PyErr_Occurred ()) {
|
||||
PyErr_Print ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
_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, call_chain_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_pad_push kwargs
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_pad_push (PyGObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "buffer", NULL };
|
||||
PyObject *pybuf;
|
||||
GstBuffer *buf;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.push",
|
||||
kwlist,
|
||||
&pybuf)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCObject_Check(pybuf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "push expecting a PyCObject");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
buf = (GstBuffer*)PyCObject_AsVoidPtr(pybuf);
|
||||
gst_pad_push(pad, buf);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_buffer_get_data
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_buffer_get_data (PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
PyObject *pybuf;
|
||||
GstBuffer *buf;
|
||||
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"O:GstBuffer:get_data",
|
||||
&pybuf)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCObject_Check(pybuf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "get_data expecting a PyCObject");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = (GstBuffer*)PyCObject_AsVoidPtr(pybuf);
|
||||
|
||||
return PyString_FromStringAndSize(
|
||||
GST_BUFFER_DATA(buf),
|
||||
GST_BUFFER_SIZE(buf));
|
||||
}
|
||||
%%
|
||||
override gst_buffer_set_data
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_buffer_set_data (PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
PyObject *pybuf;
|
||||
PyObject *data;
|
||||
GstBuffer *buf;
|
||||
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"OO:GstBuffer:set_data",
|
||||
&pybuf, &data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCObject_Check(pybuf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "set_data expecting a PyCObject");
|
||||
return NULL;
|
||||
}
|
||||
if (!PyString_Check(data)) {
|
||||
PyErr_SetString(PyExc_TypeError, "set_data expecting a string");
|
||||
return NULL;
|
||||
}
|
||||
if (GST_BUFFER_FLAGS(buf) & GST_BUFFER_READONLY) {
|
||||
PyErr_SetString(PyExc_TypeError, "set_data can't use a READONLY buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = (GstBuffer*)PyCObject_AsVoidPtr(pybuf);
|
||||
GST_BUFFER_SIZE(buf) = PyString_Size(data);
|
||||
GST_BUFFER_DATA(buf) = g_new0(char, GST_BUFFER_SIZE(buf));
|
||||
|
||||
memcpy(GST_BUFFER_DATA(buf),
|
||||
PyString_AsString(data),
|
||||
PyString_Size(data));
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_buffer_new
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_buffer_new (PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
GstBuffer *newbuf;
|
||||
|
||||
if (!PyArg_ParseTuple(args, ":GstBuffer:set_data")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newbuf = gst_buffer_new();
|
||||
return PyCObject_FromVoidPtr (newbuf, NULL);
|
||||
}
|
||||
|
|
|
@ -3457,3 +3457,19 @@
|
|||
)
|
||||
|
||||
|
||||
(define-function gst_buffer_get_data
|
||||
(c-name "gst_buffer_get_data")
|
||||
(return-type "char*")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
)
|
||||
)
|
||||
|
||||
(define-function gst_buffer_set_data
|
||||
(c-name "gst_buffer_set_data")
|
||||
(return-type "none")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
'("char*" "data")
|
||||
)
|
||||
)
|
||||
|
|
|
@ -3457,3 +3457,19 @@
|
|||
)
|
||||
|
||||
|
||||
(define-function gst_buffer_get_data
|
||||
(c-name "gst_buffer_get_data")
|
||||
(return-type "char*")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
)
|
||||
)
|
||||
|
||||
(define-function gst_buffer_set_data
|
||||
(c-name "gst_buffer_set_data")
|
||||
(return-type "none")
|
||||
(parameters
|
||||
'("GstBuffer*" "buf")
|
||||
'("char*" "data")
|
||||
)
|
||||
)
|
||||
|
|
|
@ -28,6 +28,38 @@ headers
|
|||
#include "pygobject.h"
|
||||
#include <gst/gst.h>
|
||||
|
||||
typedef struct {
|
||||
PyGObject *pad;
|
||||
PyObject *connect_function;
|
||||
PyObject *chain_function;
|
||||
} PyGstPadPrivate;
|
||||
|
||||
static PyGstPadPrivate*
|
||||
pad_private(GstPad *pad)
|
||||
{
|
||||
return (PyGstPadPrivate*)gst_pad_get_element_private(pad);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
%%
|
||||
modulename gstreamer
|
||||
%%
|
||||
import gobject.GObject as PyGObject_Type
|
||||
%%
|
||||
|
@ -35,5 +67,222 @@ ignore-glob
|
|||
_*
|
||||
gstreamer_*init
|
||||
*_get_type
|
||||
|
||||
%%
|
||||
override gst_pad_set_connect_function kwargs
|
||||
|
||||
static GstPadConnectReturn
|
||||
call_connect_function (GstPad *pad, GstCaps *caps)
|
||||
{
|
||||
PyObject *function;
|
||||
PyObject *retval;
|
||||
|
||||
function = pad_private(pad)->connect_function;
|
||||
|
||||
retval = (PyObject*)PyObject_CallFunction (function,
|
||||
"OO",
|
||||
pad_private(pad)->pad,
|
||||
PyCObject_FromVoidPtr (caps, NULL));
|
||||
|
||||
if (PyErr_Occurred ()) {
|
||||
PyErr_Print ();
|
||||
return GST_PAD_CONNECT_REFUSED;
|
||||
}
|
||||
|
||||
return PyInt_AsLong(retval);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_pad_set_connect_function (PyGObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "connect_function", NULL };
|
||||
PyObject *connect_function;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.set_connect_funcion",
|
||||
kwlist,
|
||||
&connect_function)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(connect_function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "connect_function not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(connect_function);
|
||||
py_pad_private(self)->connect_function = connect_function;
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
gst_pad_set_connect_function(pad, call_connect_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_pad_set_chain_function kwargs
|
||||
|
||||
static void
|
||||
call_chain_function (GstPad *pad, GstBuffer *buf)
|
||||
{
|
||||
PyObject *function;
|
||||
|
||||
function = pad_private(pad)->chain_function;
|
||||
|
||||
PyObject_CallFunction (function,
|
||||
"OO",
|
||||
pad_private(pad)->pad,
|
||||
PyCObject_FromVoidPtr (buf, NULL));
|
||||
|
||||
if (PyErr_Occurred ()) {
|
||||
PyErr_Print ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
_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, call_chain_function);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_pad_push kwargs
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_pad_push (PyGObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "buffer", NULL };
|
||||
PyObject *pybuf;
|
||||
GstBuffer *buf;
|
||||
GstPad *pad;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O:GstPad.push",
|
||||
kwlist,
|
||||
&pybuf)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCObject_Check(pybuf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "push expecting a PyCObject");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pad = (GstPad*)pygobject_get(self);
|
||||
buf = (GstBuffer*)PyCObject_AsVoidPtr(pybuf);
|
||||
gst_pad_push(pad, buf);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_buffer_get_data
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_buffer_get_data (PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
PyObject *pybuf;
|
||||
GstBuffer *buf;
|
||||
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"O:GstBuffer:get_data",
|
||||
&pybuf)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCObject_Check(pybuf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "get_data expecting a PyCObject");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = (GstBuffer*)PyCObject_AsVoidPtr(pybuf);
|
||||
|
||||
return PyString_FromStringAndSize(
|
||||
GST_BUFFER_DATA(buf),
|
||||
GST_BUFFER_SIZE(buf));
|
||||
}
|
||||
%%
|
||||
override gst_buffer_set_data
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_buffer_set_data (PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
PyObject *pybuf;
|
||||
PyObject *data;
|
||||
GstBuffer *buf;
|
||||
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"OO:GstBuffer:set_data",
|
||||
&pybuf, &data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCObject_Check(pybuf)) {
|
||||
PyErr_SetString(PyExc_TypeError, "set_data expecting a PyCObject");
|
||||
return NULL;
|
||||
}
|
||||
if (!PyString_Check(data)) {
|
||||
PyErr_SetString(PyExc_TypeError, "set_data expecting a string");
|
||||
return NULL;
|
||||
}
|
||||
if (GST_BUFFER_FLAGS(buf) & GST_BUFFER_READONLY) {
|
||||
PyErr_SetString(PyExc_TypeError, "set_data can't use a READONLY buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = (GstBuffer*)PyCObject_AsVoidPtr(pybuf);
|
||||
GST_BUFFER_SIZE(buf) = PyString_Size(data);
|
||||
GST_BUFFER_DATA(buf) = g_new0(char, GST_BUFFER_SIZE(buf));
|
||||
|
||||
memcpy(GST_BUFFER_DATA(buf),
|
||||
PyString_AsString(data),
|
||||
PyString_Size(data));
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
%%
|
||||
override gst_buffer_new
|
||||
|
||||
static PyObject*
|
||||
_wrap_gst_buffer_new (PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
GstBuffer *newbuf;
|
||||
|
||||
if (!PyArg_ParseTuple(args, ":GstBuffer:set_data")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newbuf = gst_buffer_new();
|
||||
return PyCObject_FromVoidPtr (newbuf, NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue