2013-12-21 43 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中,否則您試圖完成的任務將不可能實現。