GStreamer# 等效于视频叠加功能
GStreamer# equivalent for video overlay functions
我有一个用于渲染视频流的 C#/Mono 应用程序,直到最近,我一直在使用我自己内部开发的 InterOp 绑定。
我现在正在从那种方法转向使用 GStreamer# 的那些方法,因为这可能会大大减少维护工作,至少对我而言:-)
由于我需要将独立的视频流绑定到特定的 DrawableArea
小部件,我的方法捕获了 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
中,所以,在紧要关头,我可以伪造我自己的函数来完成这项工作(或者只是坚持我们对那个函数的绑定 little 位)但在我看来这应该包含在 GStreamer# 中,因为渲染到特定的小部件似乎是一个非常方便的工具。
(a) 那些 GStreamer 摇摆不定。他们必须用所有不必要的打字替换他们的键盘 :-)
原来这些函数 是 可用的,但是在一个单独的库和子命名空间中到基线 GStreamer 东西。
Xid 的获取仍然是通过自制的 InterOp 绑定完成的,即:
[DllImport("libgdk-3", EntryPoint = "gdk_x11_window_get_xid")]
private extern static IntPtr GdkX11WindowGetXid(IntPtr window);
你还有 playbin、bus 和 X11 的实例级变量window ID:
private IntPtr windowXid;
private Gst.Element playBin;
private Gst.Bus bus;
然后,在实例化 class 时,您捕获 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
作为变量),代码可能会更清晰,但我想确保所有信息都可用。
我有一个用于渲染视频流的 C#/Mono 应用程序,直到最近,我一直在使用我自己内部开发的 InterOp 绑定。
我现在正在从那种方法转向使用 GStreamer# 的那些方法,因为这可能会大大减少维护工作,至少对我而言:-)
由于我需要将独立的视频流绑定到特定的 DrawableArea
小部件,我的方法捕获了 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
中,所以,在紧要关头,我可以伪造我自己的函数来完成这项工作(或者只是坚持我们对那个函数的绑定 little 位)但在我看来这应该包含在 GStreamer# 中,因为渲染到特定的小部件似乎是一个非常方便的工具。
(a) 那些 GStreamer 摇摆不定。他们必须用所有不必要的打字替换他们的键盘 :-)
原来这些函数 是 可用的,但是在一个单独的库和子命名空间中到基线 GStreamer 东西。
Xid 的获取仍然是通过自制的 InterOp 绑定完成的,即:
[DllImport("libgdk-3", EntryPoint = "gdk_x11_window_get_xid")]
private extern static IntPtr GdkX11WindowGetXid(IntPtr window);
你还有 playbin、bus 和 X11 的实例级变量window ID:
private IntPtr windowXid;
private Gst.Element playBin;
private Gst.Bus bus;
然后,在实例化 class 时,您捕获 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
作为变量),代码可能会更清晰,但我想确保所有信息都可用。