我在我的C# WinForms应用程序中使用了1.8.1版本的gstreamer库,这允许我同时观看来自视频服务器设备的多个RTSP视频流。
我编写了一个本地的c++ dll,它封装了对gstreamer的调用。我通过DllImport属性从C#应用程序中使用它。
大多数情况下一切都很完美。但是有时候(当与视频服务器的连接不稳定时)我在我的本地dll中的
所有对gstreamer API的调用都是从主(GUI)线程中进行的。死锁发生得非常少 - 每天只有一次。很烦人捕获这个错误,我不知道如何修复或解决它。
下面是Visual Studio调试器中死锁运行时的一些屏幕截图: gstreamer包装器dll的源代码非常简洁。
有人知道死锁为什么会发生吗?
我编写了一个本地的c++ dll,它封装了对gstreamer的调用。我通过DllImport属性从C#应用程序中使用它。
大多数情况下一切都很完美。但是有时候(当与视频服务器的连接不稳定时)我在我的本地dll中的
gst_element_set_state(pipeline, GST_STATE_NULL);
遇到死锁。所有对gstreamer API的调用都是从主(GUI)线程中进行的。死锁发生得非常少 - 每天只有一次。很烦人捕获这个错误,我不知道如何修复或解决它。
下面是Visual Studio调试器中死锁运行时的一些屏幕截图: gstreamer包装器dll的源代码非常简洁。
#pragma comment(lib, "gstreamer-1.0.lib")
#pragma comment(lib, "glib-2.0.lib")
#pragma comment(lib, "gobject-2.0.lib")
#pragma comment(lib, "gstvideo-1.0.lib")
GSTLIB_API void init()
{
gst_init(NULL, NULL);
}
GSTLIB_API GstElement* create(const char* uri, const void* hwnd)
{
GstElement* pipeline = gst_element_factory_make("playbin", "play");
g_object_set(G_OBJECT(pipeline), "uri", uri, NULL);
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(pipeline), (guintptr)hwnd);
return pipeline;
}
GSTLIB_API void play(GstElement* pipeline)
{
gst_element_set_state(pipeline, GST_STATE_PLAYING);
}
GSTLIB_API void stop(GstElement* pipeline)
{
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(pipeline), 0);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));
}
GSTLIB_API bool hasError(GstElement* pipeline)
{
auto state = GST_STATE(pipeline);
return state != GST_STATE_PLAYING;
}
C#对本地dll进行绑定:
[DllImport("GstLib.dll", EntryPoint = @"?init@@YAXXZ",
CallingConvention = CallingConvention.Cdecl)]
private static extern void init();
[DllImport("GstLib.dll", EntryPoint = @"?create@@YAPAU_GstElement@@PBDPBX@Z",
CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr create([MarshalAs(UnmanagedType.LPStr)] string uri, IntPtr hwnd);
[DllImport("GstLib.dll", EntryPoint = @"?stop@@YAXPAU_GstElement@@@Z",
CallingConvention = CallingConvention.Cdecl)]
private static extern void stop(IntPtr pipeline);
[DllImport("GstLib.dll", EntryPoint = @"?play@@YAXPAU_GstElement@@@Z",
CallingConvention = CallingConvention.Cdecl)]
private static extern void play(IntPtr pipeline);
[DllImport("GstLib.dll", EntryPoint = @"?hasError@@YA_NPAU_GstElement@@@Z",
CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool hasError(IntPtr pipeline);
有人知道死锁为什么会发生吗?