Python 如何在Cython中编写GStreamer插件

Python 如何在Cython中编写GStreamer插件,python,gstreamer,cython,python-gstreamer,Python,Gstreamer,Cython,Python Gstreamer,我想做一个新型音频滤波器的原型。目前,我使用GStreamer返回音频缓冲区,Cython对其应用过滤器。然后我将结果发送回GStreamer 所有内容都封装在python主代码中,GStreamer访问是使用。使用Cython进行原型化非常好,因为它在代码运行时会自动重新编译,而且非常高效 然而,我觉得如果我可以使用我的Cython文件来生成一个GStreamer本机插件(这些插件是用C编写的),这会更好 您对如何实现这一点有什么想法吗?Cython生成了Python扩展模块,这些模块需要在P

我想做一个新型音频滤波器的原型。目前,我使用GStreamer返回音频缓冲区,Cython对其应用过滤器。然后我将结果发送回GStreamer

所有内容都封装在python主代码中,GStreamer访问是使用。使用Cython进行原型化非常好,因为它在代码运行时会自动重新编译,而且非常高效

然而,我觉得如果我可以使用我的Cython文件来生成一个GStreamer本机插件(这些插件是用C编写的),这会更好


您对如何实现这一点有什么想法吗?

Cython生成了Python扩展模块,这些模块需要在Python上下文中初始化才能发挥作用。我认为,除非您与gstreamer开发人员合作,首先将Python模块支持添加到gstreamer中,否则您试图实现的目标是不可能的。

Cython主要用于生成Python扩展模块,而不是真正用于支持其他插件API。然而,如果你愿意手动调整输出,你可能会得到一些合理的结果

例如,您可以手工编写一个小的C存根,将模块初始化为gstreamer插件:

#include "Python.h"
#include "gst_plugin.h"

static gboolean plugin_init (GstPlugin *plugin) {
    // initialize the extension module
    #if PY_MAJOR_VERSION < 3
        initgstreamer();
    #else
        PyInit_gstreamer();
    #endif

    // call into function exported from cython module
    return register_plugin(plugin);
}

GST_PLUGIN_DEFINE (
    GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    my_filter,
    "My filter plugin",
    plugin_init,
    VERSION,
    "LGPL",
    "GStreamer",
    "http://gstreamer.net/"
)
然而,这并不是全部。为了实现这一点,您必须以某种方式说服gstreamer将
libpython
加载到其进程中,因为cython依赖于它甚至只是初始化。您可能需要先初始化Python解释器,然后代码才能正常运行。您需要为所有要使用的gstreamer插件注册API定义cython存根。如果其他任何人试图在同一个gstreamer过程中做同样的事情,它可能都会崩溃

因此,有了所有这些,一个更简单的方法可能是制作一个连接到Python代码的gstreamer插件,然后使用该插件访问cython模块。通过这种方式,python嵌入是显式的,您将有机会在加载代码之前正确初始化python解释器。无论是使用cython还是
ctypes
模块,这样一个插件对于其他尝试执行与您类似项目的人都很有用

这样的插件实际上是一个颠倒的PyGST:它将Python作为库加载到GStreamer中,而不是将GStreamer作为库加载到Python中。可能有一些PyGST代码可以重复使用,但仍然有一个限制,即每个进程只能包含一个Python,因此使用此机制的多个模块都需要共享同一个Python解释器,就像在Apache Web服务器的
mod_python
模块中加载多个应用程序一样。

换句话说,“这太复杂了,伙计!”。
cdef public int register_plugin(void *plugin):
    # use the gstreamer API in here to register your plugin