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):

  1. 通过为 GStreamer 提供 MainWindow 句柄来显示视频。这将导致视频接管整个 WPF。这段代码有效,但我们将无法添加任何 WPF 控件。
    var windowHandle = new WindowInteropHelper(System.Windows.Application.Current.MainWindow).Handle;
    _playback = new Playback(windowHandle, _enableOverlay); 
  1. 我们想使用的另一种方法是在 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 包。