diff --git a/modules/videoio/src/cap_gstreamer.cpp b/modules/videoio/src/cap_gstreamer.cpp index 4d9330daf8..67c119cd36 100644 --- a/modules/videoio/src/cap_gstreamer.cpp +++ b/modules/videoio/src/cap_gstreamer.cpp @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -107,6 +108,7 @@ template<> inline void GSafePtr_release(GstBuffer** pPtr) { if (pPtr) template<> inline void GSafePtr_release(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } } template<> inline void GSafePtr_release(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } } template<> inline void GSafePtr_release(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } } +template<> inline void GSafePtr_release(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } } template<> inline void GSafePtr_release(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } } template<> inline void GSafePtr_release(GstEncodingContainerProfile** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } } @@ -194,10 +196,15 @@ public: private: bool isFailed; bool call_deinit; + bool start_loop; + GSafePtr loop; + std::thread thread; + gst_initializer() : isFailed(false) { call_deinit = utils::getConfigurationParameterBool("OPENCV_VIDEOIO_GSTREAMER_CALL_DEINIT", false); + start_loop = utils::getConfigurationParameterBool("OPENCV_VIDEOIO_GSTREAMER_START_MAINLOOP", false); GSafePtr err; gst_init_check(NULL, NULL, err.getRef()); @@ -215,6 +222,14 @@ private: isFailed = true; return; } + + if (start_loop) + { + loop.attach(g_main_loop_new (NULL, FALSE)); + thread = std::thread([this](){ + g_main_loop_run (loop); + }); + } } ~gst_initializer() { @@ -223,6 +238,12 @@ private: // Debug leaks: GST_LEAKS_TRACER_STACK_TRACE=1 GST_DEBUG="GST_TRACER:7" GST_TRACERS="leaks" gst_deinit(); } + + if (start_loop) + { + g_main_loop_quit(loop); + thread.join(); + } } };