如何在Cython中编写GStreamer插件

时间:2013-12-21 12:55:38

标签: python gstreamer cython python-gstreamer

我想原型化一种新型音频滤波器。目前我使用GStreamer返回我的音频缓冲区,并使用Cython将滤镜应用于它。然后我将结果发送回GStreamer。

所有内容都包含在python主代码中,GStreamer访问使用pygst完成。使用Cython进行原型设计非常棒,因为它在运行代码时会自动重新编译,效率非常高。

但是我觉得如果我可以使用我的Cython文件生成一个GStreamer本机插件(用C语言编写)会更好。

您对如何实现这一目标有所了解吗?

2 个答案:

答案 0 :(得分:5)

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

例如,您可以手写一个小的C stub来将模块初始化为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/"
)

然后,您可以从cython模块中导出register_plugin函数:

cdef public int register_plugin(void *plugin):
    # use the gstreamer API in here to register your plugin

但是,这不是全部。为了使它能够工作,你必须以某种方式说服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模块中。

答案 1 :(得分:1)

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