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
This commit is contained in:
Matthew Waters 2016-06-16 15:13:02 +10:00
parent c9dd45393e
commit 3be4b85a43
2 changed files with 91 additions and 41 deletions

View file

@ -178,6 +178,10 @@ QtGLVideoItem::QtGLVideoItem()
if (QString::fromUtf8 ("ios") == app->platformName()) if (QString::fromUtf8 ("ios") == app->platformName())
this->priv->display = gst_gl_display_new (); this->priv->display = gst_gl_display_new ();
#endif #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) if (!this->priv->display)
this->priv->display = gst_gl_display_new (); this->priv->display = gst_gl_display_new ();
@ -216,9 +220,9 @@ QtGLVideoItem::getDAR(gint * num, gint * den)
} }
void 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 bool
@ -314,7 +318,7 @@ qt_item_set_buffer (QtGLVideoItem * widget, GstBuffer * buffer)
void void
QtGLVideoItem::onSceneGraphInitialized () QtGLVideoItem::onSceneGraphInitialized ()
{ {
GstGLPlatform platform; GstGLPlatform platform = (GstGLPlatform) 0;
GstGLAPI gl_api; GstGLAPI gl_api;
guintptr gl_handle; guintptr gl_handle;
@ -333,60 +337,37 @@ QtGLVideoItem::onSceneGraphInitialized ()
#if GST_GL_HAVE_WINDOW_X11 && defined (HAVE_QT_X11) #if GST_GL_HAVE_WINDOW_X11 && defined (HAVE_QT_X11)
if (GST_IS_GL_DISPLAY_X11 (this->priv->display)) { if (GST_IS_GL_DISPLAY_X11 (this->priv->display)) {
platform = GST_GL_PLATFORM_GLX; 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 #endif
#if GST_GL_HAVE_WINDOW_WAYLAND && defined (HAVE_QT_WAYLAND) #if GST_GL_HAVE_WINDOW_WAYLAND && defined (HAVE_QT_WAYLAND)
if (GST_IS_GL_DISPLAY_WAYLAND (this->priv->display)) { if (GST_IS_GL_DISPLAY_WAYLAND (this->priv->display)) {
platform = GST_GL_PLATFORM_EGL; 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 #endif
#if GST_GL_HAVE_PLATFORM_EGL && defined (HAVE_QT_EGLFS) #if GST_GL_HAVE_PLATFORM_EGL && defined (HAVE_QT_EGLFS)
if (GST_IS_GL_DISPLAY_EGL (this->priv->display)) { if (GST_IS_GL_DISPLAY_EGL (this->priv->display)) {
platform = GST_GL_PLATFORM_EGL; 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 #endif
if (platform == 0 && this->priv->display) {
#if GST_GL_HAVE_WINDOW_COCOA && GST_GL_HAVE_PLATFORM_COCOA && defined (HAVE_QT_MAC) #if GST_GL_HAVE_WINDOW_COCOA && GST_GL_HAVE_PLATFORM_COCOA && defined (HAVE_QT_MAC)
if (this->priv->display) {
platform = GST_GL_PLATFORM_CGL; platform = GST_GL_PLATFORM_CGL;
gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); #elif GST_GL_HAVE_WINDOW_EAGL && GST_GL_HAVE_PLATFORM_EAGL && defined (HAVE_QT_IOS)
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) {
platform = GST_GL_PLATFORM_EAGL; platform = GST_GL_PLATFORM_EAGL;
gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL); #elif GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (HAVE_QT_WIN32)
gl_handle = gst_gl_context_get_current_gl_context (platform); platform = GST_GL_PLATFORM_WGL;
if (gl_handle) #else
this->priv->other_context = GST_ERROR ("Unknown platform");
gst_gl_context_new_wrapped (this->priv->display, gl_handle, return;
platform, gl_api);
}
#endif #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) platform;
(void) gl_api; (void) gl_api;
@ -402,6 +383,36 @@ QtGLVideoItem::onSceneGraphInitialized ()
this->priv->other_context = NULL; this->priv->other_context = NULL;
} else { } else {
gst_gl_display_filter_gl_api (this->priv->display, gst_gl_context_get_gl_api (this->priv->other_context)); 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); gst_gl_context_activate (this->priv->other_context, FALSE);
m_openGlContextInitialized = true; m_openGlContextInitialized = true;
} }

39
ext/qt/qtplugin.pro Normal file
View file

@ -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/