我想原型化一种新型音频滤波器。目前我使用GStreamer返回我的音频缓冲区,并使用Cython将滤镜应用于它。然后我将结果发送回GStreamer。
所有内容都包含在python主代码中,GStreamer访问使用pygst完成。使用Cython进行原型设计非常棒,因为它在运行代码时会自动重新编译,效率非常高。
但是我觉得如果我可以使用我的Cython文件生成一个GStreamer本机插件(用C语言编写)会更好。
您对如何实现这一目标有所了解吗?
答案 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模块支持,否则你想要实现的目标是不可能的。