From ba69afdc475f1fd41b2fb3141ada2531f190cf02 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Thu, 16 Jun 2016 15:13:02 +1000 Subject: [PATCH] qmlglsink: add win32 support The current state of c++ ABI's on Window's and Gst's/Qt's conflicting mingw builds means that we cannot use mingw for building the qt plugin. Instead, a qmake .pro file is provided that is expected to be used with the msvc binaries provided by Qt like so: (with the PATH environment variable containing the path to the qt biniaries and PKG_CONFIG_PATH containing the path to GStreamer modules) cd /path/to/sources/gst-plugins-bad/ext/qt qmake -tp vc Then open the resulting VS project and build the library. Then cp debug/libgstqtsink.dll /path/to/prefix/lib/gstreamer-1.0/libgstqtsink.cll https://bugzilla.gnome.org/show_bug.cgi?id=761260 --- ext/qt/qtitem.cc | 93 ++++++++++++++++++++++++++++++----------------------- ext/qt/qtplugin.pro | 39 ++++++++++++++++++++++ 2 files changed, 91 insertions(+), 41 deletions(-) create mode 100644 ext/qt/qtplugin.pro diff --git a/ext/qt/qtitem.cc b/ext/qt/qtitem.cc index 505ed03..67820b9 100644 --- a/ext/qt/qtitem.cc +++ b/ext/qt/qtitem.cc @@ -178,6 +178,10 @@ QtGLVideoItem::QtGLVideoItem() if (QString::fromUtf8 ("ios") == app->platformName()) this->priv->display = gst_gl_display_new (); #endif +#if GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (HAVE_QT_WIN32) + if (QString::fromUtf8 ("windows") == app->platformName()) + this->priv->display = gst_gl_display_new (); +#endif if (!this->priv->display) this->priv->display = gst_gl_display_new (); @@ -216,9 +220,9 @@ QtGLVideoItem::getDAR(gint * num, gint * den) } void -QtGLVideoItem::setForceAspectRatio(bool far) +QtGLVideoItem::setForceAspectRatio(bool force_aspect_ratio) { - this->priv->force_aspect_ratio = far; + this->priv->force_aspect_ratio = !!force_aspect_ratio; } bool @@ -314,7 +318,7 @@ qt_item_set_buffer (QtGLVideoItem * widget, GstBuffer * buffer) void QtGLVideoItem::onSceneGraphInitialized () { - GstGLPlatform platform; + GstGLPlatform platform = (GstGLPlatform) 0; GstGLAPI gl_api; guintptr gl_handle; @@ -333,60 +337,37 @@ QtGLVideoItem::onSceneGraphInitialized () #if GST_GL_HAVE_WINDOW_X11 && defined (HAVE_QT_X11) if (GST_IS_GL_DISPLAY_X11 (this->priv->display)) { platform = GST_GL_PLATFORM_GLX; - gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); - gl_handle = gst_gl_context_get_current_gl_context (platform); - if (gl_handle) - this->priv->other_context = - gst_gl_context_new_wrapped (this->priv->display, gl_handle, - platform, gl_api); } #endif #if GST_GL_HAVE_WINDOW_WAYLAND && defined (HAVE_QT_WAYLAND) if (GST_IS_GL_DISPLAY_WAYLAND (this->priv->display)) { platform = GST_GL_PLATFORM_EGL; - gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); - gl_handle = gst_gl_context_get_current_gl_context (platform); - if (gl_handle) - this->priv->other_context = - gst_gl_context_new_wrapped (this->priv->display, gl_handle, - platform, gl_api); } #endif - #if GST_GL_HAVE_PLATFORM_EGL && defined (HAVE_QT_EGLFS) if (GST_IS_GL_DISPLAY_EGL (this->priv->display)) { platform = GST_GL_PLATFORM_EGL; - gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); - gl_handle = gst_gl_context_get_current_gl_context (platform); - if (gl_handle) - this->priv->other_context = - gst_gl_context_new_wrapped (this->priv->display, gl_handle, - platform, gl_api); } #endif - + if (platform == 0 && this->priv->display) { #if GST_GL_HAVE_WINDOW_COCOA && GST_GL_HAVE_PLATFORM_COCOA && defined (HAVE_QT_MAC) - if (this->priv->display) { platform = GST_GL_PLATFORM_CGL; - gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); - gl_handle = gst_gl_context_get_current_gl_context (platform); - if (gl_handle) - this->priv->other_context = - gst_gl_context_new_wrapped (this->priv->display, gl_handle, - platform, gl_api); - } -#endif -#if GST_GL_HAVE_WINDOW_EAGL && GST_GL_HAVE_PLATFORM_EAGL && defined (HAVE_QT_IOS) - if (this->priv->display) { +#elif GST_GL_HAVE_WINDOW_EAGL && GST_GL_HAVE_PLATFORM_EAGL && defined (HAVE_QT_IOS) platform = GST_GL_PLATFORM_EAGL; - gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); - gl_handle = gst_gl_context_get_current_gl_context (platform); - if (gl_handle) - this->priv->other_context = - gst_gl_context_new_wrapped (this->priv->display, gl_handle, - platform, gl_api); - } +#elif GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (HAVE_QT_WIN32) + platform = GST_GL_PLATFORM_WGL; +#else + GST_ERROR ("Unknown platform"); + return; #endif + } + + gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); + gl_handle = gst_gl_context_get_current_gl_context (platform); + if (gl_handle) + this->priv->other_context = + gst_gl_context_new_wrapped (this->priv->display, gl_handle, + platform, gl_api); (void) platform; (void) gl_api; @@ -402,6 +383,36 @@ QtGLVideoItem::onSceneGraphInitialized () this->priv->other_context = NULL; } else { gst_gl_display_filter_gl_api (this->priv->display, gst_gl_context_get_gl_api (this->priv->other_context)); +#if GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (HAVE_QT_WIN32) + if (!wglGetProcAddress ("wglCreateContextAttribsARB")) { + GstGLWindow *window; + HDC device; + + /* If there's no wglCreateContextAttribsARB() support, then we would fallback to + * wglShareLists() which will fail with ERROR_BUSY (0xaa) if either of the GL + * contexts are current in any other thread. + * + * The workaround here is to temporarily disable Qt's GL context while we + * set up our own. + */ + this->priv->context = gst_gl_context_new (this->priv->display); + window = gst_gl_context_get_window (this->priv->context); + device = (HDC) gst_gl_window_get_display (window); + + wglMakeCurrent (device, 0); + gst_object_unref (window); + if (!gst_gl_context_create (this->priv->context, this->priv->other_context, &error)) { + GST_ERROR ("%p failed to create shared GL context: %s", this, error->message); + g_object_unref (this->priv->context); + this->priv->context = NULL; + g_object_unref (this->priv->other_context); + this->priv->other_context = NULL; + wglMakeCurrent (device, (HGLRC) gl_handle); + return; + } + wglMakeCurrent (device, (HGLRC) gl_handle); + } +#endif gst_gl_context_activate (this->priv->other_context, FALSE); m_openGlContextInitialized = true; } diff --git a/ext/qt/qtplugin.pro b/ext/qt/qtplugin.pro new file mode 100644 index 0000000..af1d8dd --- /dev/null +++ b/ext/qt/qtplugin.pro @@ -0,0 +1,39 @@ +TEMPLATE = lib + +TARGET = libgstqtsink + +QT += qml quick widgets + +QT_CONFIG -= no-pkg-config +CONFIG += link_pkgconfig debug plugin +PKGCONFIG = \ + gstreamer-1.0 \ + gstreamer-video-1.0 \ + gstreamer-gl-1.0 + +DEFINES += \ + GST_USE_UNSTABLE_API \ + HAVE_QT_WIN32 \ + 'GST_PACKAGE_NAME=\"GStreamer Bad Plug-ins (qmake)\"' \ + 'GST_PACKAGE_ORIGIN=\"Unknown package origin\"' \ + 'GST_LICENSE=\"LGPL\"' \ + 'PACKAGE=\"gst-plugins-bad (qmake)\"' \ + 'PACKAGE_VERSION=\"1.9.0.1\"' + +SOURCES += \ + gstplugin.cc \ + gstqsgtexture.cc \ + gstqtsink.cc \ + qtitem.cc + +HEADERS += \ + gstqsgtexture.h \ + gstqtgl.h \ + gstqtsink.h \ + qtitem.h + +INCLUDEPATH += \ + $$(GSTREAMER_ROOT)/include \ + $$[QT_INSTALL_PREFIX]/include/QtGui/$$[QT_VERSION]/QtGui/ + + \ No newline at end of file -- 2.7.4