C# Gstreamer-d3d11-overlay Sink.Emit 渲染指针错误
C# Gstreamer-d3d11-overlay Sink.Emit pointer error on render
我正在 Windows 上使用 gstreamer-sharp-netcore(Mingw v1.19.1) 开发 C# WPF 应用程序。我们想要实现的是能够使用硬件加速渲染视频。为了避免 WPF 中的空域问题,我们使用 gstreamer-d3d11-overlay(https://github.com/berglie/gstreamer-d3d11-overlay/).
在示例中,有两种启动视频渲染的方法(MainWindow.cs):
- 通过为 GStreamer 提供 MainWindow 句柄来显示视频。这将导致视频接管整个 WPF。这段代码有效,但我们将无法添加任何 WPF 控件。
var windowHandle = new WindowInteropHelper(System.Windows.Application.Current.MainWindow).Handle;
_playback = new Playback(windowHandle, _enableOverlay);
- 我们想使用的另一种方法是在 WPF 中制作图像对象。创建 D3dImageEx 和 D3D11TestScene 并将其附加到图像对象。
_d3DImageEx = new D3DImageEx();
_D3D11Scene = new D3D11TestScene(1920, 1080);
d3dScene.Source = _d3DImageEx;
/* Set the backbuffer, which is a ID3D11Texture2D pointer */
IntPtr renderTarget = _D3D11Scene.GetRenderTarget();
IntPtr backBuffer = _d3DImageEx.CreateBackBuffer(D3DResourceTypeEx.ID3D11Texture2D, renderTarget);
_d3DImageEx.Lock();
_d3DImageEx.SetBackBuffer(D3DResourceType.IDirect3DSurface9, backBuffer, _enableSoftwareFallback);
_d3DImageEx.Unlock();
_playback = new Playback(IntPtr.Zero, _enableOverlay);
_playback.OnDrawSignalReceived += VideoSink_OnBeginDraw;
CompositionTarget.Rendering += CompositionTarget_Rendering;
成功初始化后,Gstreamer 将渲染视频并触发 OnDrawSignalReceived:
private void VideoSink_OnBeginDraw(Element sink, GLib.SignalArgs args)
{
var sharedHandle = _D3D11Scene.GetSharedHandle();
_ = sink.Emit("draw", sharedHandle, (UInt32)2, (UInt64)0, (UInt64)0);
}
在线:“sink.Emit”我们得到一个错误:
System.Reflection.TargetInvocationException
HResult=0x80131604
Message=Exception has been thrown by the target of an invocation.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at Gst.DynamicSignal.OnMarshal(IntPtr closure, Value& retval, UInt32 argc, IntPtr argsPtr, IntPtr ihint, IntPtr data)
This exception was originally thrown at this call stack:
Gst.DynamicSignal.Emit(GLib.Object, string, object[])
Gst.Object.Emit(string, object[])
TestHacoustoGst2D3D11WpfApp.MainWindow.VideoSink_OnBeginDraw(Gst.Element, GLib.SignalArgs) in MainWindow.xaml.cs
TestHacoustoGst2D3D11WpfApp.Playback.VideoSink_OnBeginDraw(object, GLib.SignalArgs) in Playback.cs
Inner Exception 1:
ApplicationException: Invalid parameter type: expected , got System.IntPtr
有谁知道如何解决这个问题?那将不胜感激:)
我们也在考虑使用 OpenTK,但我们必须了解如何有效地将 glimagesink 中的 OpenGL 纹理共享到 OpenTk。
此问题已在 GtkSharp 中修复:https://github.com/GLibSharp/GtkSharp/pull/52
我假设您使用的是 GstSharp NuGet 包,该包今天尚未使用此修复程序进行更新。
为了暂时解决这个问题,我上传了一个非官方的补丁到NuGet,搜索“GstSharp.HotFix”。
https://www.nuget.org/packages/GstSharp.Hotfix/
编辑:如果您使用的是修补程序包,请确保卸载官方 GstSharp 包。
我正在 Windows 上使用 gstreamer-sharp-netcore(Mingw v1.19.1) 开发 C# WPF 应用程序。我们想要实现的是能够使用硬件加速渲染视频。为了避免 WPF 中的空域问题,我们使用 gstreamer-d3d11-overlay(https://github.com/berglie/gstreamer-d3d11-overlay/).
在示例中,有两种启动视频渲染的方法(MainWindow.cs):
- 通过为 GStreamer 提供 MainWindow 句柄来显示视频。这将导致视频接管整个 WPF。这段代码有效,但我们将无法添加任何 WPF 控件。
var windowHandle = new WindowInteropHelper(System.Windows.Application.Current.MainWindow).Handle;
_playback = new Playback(windowHandle, _enableOverlay);
- 我们想使用的另一种方法是在 WPF 中制作图像对象。创建 D3dImageEx 和 D3D11TestScene 并将其附加到图像对象。
_d3DImageEx = new D3DImageEx();
_D3D11Scene = new D3D11TestScene(1920, 1080);
d3dScene.Source = _d3DImageEx;
/* Set the backbuffer, which is a ID3D11Texture2D pointer */
IntPtr renderTarget = _D3D11Scene.GetRenderTarget();
IntPtr backBuffer = _d3DImageEx.CreateBackBuffer(D3DResourceTypeEx.ID3D11Texture2D, renderTarget);
_d3DImageEx.Lock();
_d3DImageEx.SetBackBuffer(D3DResourceType.IDirect3DSurface9, backBuffer, _enableSoftwareFallback);
_d3DImageEx.Unlock();
_playback = new Playback(IntPtr.Zero, _enableOverlay);
_playback.OnDrawSignalReceived += VideoSink_OnBeginDraw;
CompositionTarget.Rendering += CompositionTarget_Rendering;
成功初始化后,Gstreamer 将渲染视频并触发 OnDrawSignalReceived:
private void VideoSink_OnBeginDraw(Element sink, GLib.SignalArgs args)
{
var sharedHandle = _D3D11Scene.GetSharedHandle();
_ = sink.Emit("draw", sharedHandle, (UInt32)2, (UInt64)0, (UInt64)0);
}
在线:“sink.Emit”我们得到一个错误:
System.Reflection.TargetInvocationException
HResult=0x80131604
Message=Exception has been thrown by the target of an invocation.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at Gst.DynamicSignal.OnMarshal(IntPtr closure, Value& retval, UInt32 argc, IntPtr argsPtr, IntPtr ihint, IntPtr data)
This exception was originally thrown at this call stack:
Gst.DynamicSignal.Emit(GLib.Object, string, object[])
Gst.Object.Emit(string, object[])
TestHacoustoGst2D3D11WpfApp.MainWindow.VideoSink_OnBeginDraw(Gst.Element, GLib.SignalArgs) in MainWindow.xaml.cs
TestHacoustoGst2D3D11WpfApp.Playback.VideoSink_OnBeginDraw(object, GLib.SignalArgs) in Playback.cs
Inner Exception 1:
ApplicationException: Invalid parameter type: expected , got System.IntPtr
有谁知道如何解决这个问题?那将不胜感激:)
我们也在考虑使用 OpenTK,但我们必须了解如何有效地将 glimagesink 中的 OpenGL 纹理共享到 OpenTk。
此问题已在 GtkSharp 中修复:https://github.com/GLibSharp/GtkSharp/pull/52
我假设您使用的是 GstSharp NuGet 包,该包今天尚未使用此修复程序进行更新。
为了暂时解决这个问题,我上传了一个非官方的补丁到NuGet,搜索“GstSharp.HotFix”。
https://www.nuget.org/packages/GstSharp.Hotfix/
编辑:如果您使用的是修补程序包,请确保卸载官方 GstSharp 包。