2016-02-19 43 views
1

我有一個用於渲染視頻流的C#/ Mono應用程序,直到最近,我一直在使用我自己開發的InterOp綁定。GStreamer#相當於視頻疊加功能

我現在從該方法轉移到使用這些的GStreamer的#,因爲這很可能是維護的工作量要少得多,至少對我來說:-)

因爲我需要綁定獨立的視頻流的我的方法捕獲了GStreamer消息,然後使用函數gst_is_video_overlay_prepare_window_handle_message(msg)(a)檢查了它們。

如果返回true,我隨後調用gst_video_overlay_set_window_handle(xid)進行響應,其中xid是之前用gdk_x11_window_get_xid()獲得的小部件的句柄。

我的問題是這樣的:通過GStreamer#代碼搜索,我找不到執行綁定的等價函數,所以我想知道這是如何實現的。

任何人有任何建議或信息提供?

對於這兩個函數的源代碼是gst-plugins-base-1.4.4/gst-libs/gst/video/videooverlay.c如此,在緊要關頭,我笨蛋了我自己的函數來完成這項工作(或只是堅持與我們的一個位綁定),但它似乎我這將會包含在GStreamer#中,因爲渲染到特定的小部件似乎是一個非常方便的工具。


的(a)那些的GStreamer搖尾巴。他們必須使用所有不必要的打字方式替換鍵盤:-)

回答

2

原來這些功能可用,但位於與基線GStreamer東西的單獨庫和子名稱空間中。

[DllImport("libgdk-3", EntryPoint = "gdk_x11_window_get_xid")] 
private extern static IntPtr GdkX11WindowGetXid(IntPtr window); 

您也可以爲playbin實例級別的變量,公共汽車和X11窗口ID:

中XID的獲得仍與自制的互操作結合,以機智做

private IntPtr windowXid; 
private Gst.Element playBin; 
private Gst.Bus bus; 

然後,實例化類時,你捕捉Realized信號,並確保GStreamer的總線上的所有信息到你的回調函數:

this.Realized += OnRealized; 
playBin = Gst.ElementFactory.Make('playbin', 'playbin'); 
bus = playBin.Bus; 
bus.AddSignalWatch(); 
bus.Message += MessageCallback; 

在這種實現的功能,爲您節省中XID供以後使用(在一個實例變量):

void OnRealized(object o, EventArgs args) { 
    windowXid = GdkX11WindowGetXid(this.Window.Handle); 
} 

,當由GStreamer的要求,提供這個句柄響應請求:

private void MessageCallback(object o, MessageArgs args) { 
    Gst.Message msg = args.Message; 
    if (! Gst.Video.Global.IsVideoOverlayPrepareWindowHandleMessage(msg)) 
     return; 

    Gst.Element src = msg.Src as Gst.Element; 
    if (src == null) 
     return; 

    Gst.Element overlay = null; 
    if (src is Gst.Bin) 
     overlay = ((Gst.Bin)src).GetByInterface 

    Gst.Video.VideoOverlayAdapter = new Gst.Video.VideoOverlayAdapter(overlay.Handle); 
    adapter.WindowHandle = windowXid; 
} 

請注意,我已經完全限定了所有GStreamer對象,因此它絕對清楚它們可以找到的位置。沒有它們的代碼可能會更清晰(並且使用var作爲變量),但我想確保所有信息都可用。