Dead end on gstreamer for Windows

I use the gstreamer 1.8.1 library in my C # WinForms application, which allows me to watch multiple RTSP video streams from the device’s video server at the same time.

I wrote a native C ++ dll that wraps gstreamer calls. I use it from a C # application through the DllImport attribute.

In most cases, everything works fine. But sometimes (I think when the connection to the video server is unstable), I get a dead end gst_element_set_state(pipeline, GST_STATE_NULL);in my native DLL.

All gstreamer API calls are created from the main (GUI) thread. Deadlock is very rare - only once a day. It is very tiring to catch this error, and I do not know how to fix it or get around it.

Here are some screenshots from the Visual Studio debugger when the deadlock is in action:

debugger watch call stack

dll gstreamer :

#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;
}

# 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);

- , ?

+4

All Articles