2013-12-21 23 views
6

我想要创建一种新型音频滤镜的原型。目前我使用GStreamer来返回音频的缓冲区,Cython将滤波器应用到它。然后我将结果发送回GStreamer。如何在Cython中编写GStreamer插件

所有东西都包装在python主代码中,GStreamer访问使用pygst完成。使用Cython创建原型非常棒,因为它可以在代码运行时自动重新编译,而且效率非常高。

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

你对如何实现这个目标有想法吗?

回答

5

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

例如,你可以手工写一个小C存根来初始化模块作为一个的GStreamer插件:

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

#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功能

但是,这不是整个故事。为了这个工作,你必须说服gstreamer将libpython加载到它的进程中,因为cython依赖它甚至只是初始化。您可能需要在代码运行之前稍微初始化Python解释器。您需要为所有要使用的gstreamer插件注册API定义cython存根。如果其他人试图在同一个gstreamer进程中做同样的事情,它可能会全部崩溃。

因此,所有这一切说,一个更直接的路径可能是创建一个桥接到Python代码的gstreamer插件,然后使用该插件访问您的cython模块。通过这种方式,python嵌入是明确的,您将有机会在加载代码之前正确初始化Python解释器。这样的插件可能对其他尝试为您的项目做类似项目的人很有用,无论是使用cython还是​​模块。

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

+0

换句话说,“这太复杂了!”。 –

1

Cython生成需要在Python上下文中初始化才能使用的Python扩展模块。我认为,除非您与gstreamer开发人员一起首先将Python模块支持添加到gstreamer中,否则您试图完成的任务将不可能实现。