[Libreoffice-commits] core.git: avmedia/Library_avmediagst.mk avmedia/source config_host/config_vclplug.h.in config_host.mk.in configure.ac include/vcl vcl/inc vcl/Library_vclplug_gtk3_kde5.mk vcl/Library_vclplug_gtk3.mk vcl/Library_vclplug_qt5.mk vcl/qt5 vcl/source vcl/unx

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Thu Jun 13 21:46:02 UTC 2019


 avmedia/Library_avmediagst.mk          |   20 ----
 avmedia/source/gstreamer/gstplayer.cxx |  161 ++++++++++-----------------------
 avmedia/source/gstreamer/gstplayer.hxx |    9 -
 config_host.mk.in                      |    6 -
 config_host/config_vclplug.h.in        |    3 
 configure.ac                           |   30 +++---
 include/vcl/syschild.hxx               |    2 
 vcl/Library_vclplug_gtk3.mk            |    1 
 vcl/Library_vclplug_gtk3_kde5.mk       |    1 
 vcl/Library_vclplug_qt5.mk             |    7 -
 vcl/inc/qt5/Qt5Instance.hxx            |    2 
 vcl/inc/salinst.hxx                    |    3 
 vcl/inc/unx/gstsink.hxx                |   27 +++++
 vcl/inc/unx/gtk/gtkinst.hxx            |    4 
 vcl/qt5/Qt5Instance.cxx                |   38 +++++++
 vcl/source/window/syschild.cxx         |    5 +
 vcl/unx/gtk3/gtk3gtkinst.cxx           |   33 ++++++
 17 files changed, 193 insertions(+), 159 deletions(-)

New commits:
commit a6201725d760cbce832d4de029b418bb7334df6a
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Mon Jun 10 21:40:33 2019 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Thu Jun 13 23:45:09 2019 +0200

    Don't link avmediagst with gtk3 and qt5
    
    While the VCL plugins are dynamically loaded and therefore just
    load their depending toolkit libraries, the GStreamer avmedia
    backend now links against Qt and GTK+. The GStreamer API itself
    is toolkit agnostic and the toolkit setup just uses a single
    GStreamer symbol to create the specific video sink.
    
    So the toolkit binding can simply be moved into the VCL plugin.
    At the point of the GStreamer toolkit setup call the GStreamer
    library is loaded by avmediagst, so the dlsym lookup should
    never fail.
    
    I also dropped the special GtkWidget handling. Using g_object_get
    will increase the refcount of the widget. A g_object_unref after
    adding it to the container seems to destroy it correctly.
    
    Change-Id: I693947e441bceb4b09bc38920e308e39142d0a35
    Reviewed-on: https://gerrit.libreoffice.org/73849
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/avmedia/Library_avmediagst.mk b/avmedia/Library_avmediagst.mk
index 027123911e87..7ed6cc451a24 100644
--- a/avmedia/Library_avmediagst.mk
+++ b/avmedia/Library_avmediagst.mk
@@ -21,26 +21,6 @@ $(eval $(call gb_Library_add_libs,avmediagst,\
     $(GSTREAMER_1_0_LIBS) \
 ))
 
-ifneq ($(ENABLE_GTK3),)
-$(eval $(call gb_Library_add_cxxflags,avmediagst,\
-    $$(GTK3_CFLAGS) \
-))
-
-$(eval $(call gb_Library_add_libs,avmediagst,\
-    $(GTK3_LIBS) \
-))
-endif
-
-ifneq ($(ENABLE_QT5),)
-$(eval $(call gb_Library_add_cxxflags,avmediagst,\
-    $$(QT5_CFLAGS) \
-))
-
-$(eval $(call gb_Library_add_libs,avmediagst,\
-    $(QT5_LIBS) \
-))
-endif
-
 $(eval $(call gb_Library_use_external,avmediagst,boost_headers))
 
 $(eval $(call gb_Library_use_sdk_api,avmediagst))
diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx
index f88addd0cfef..35feb8ad5ea2 100644
--- a/avmedia/source/gstreamer/gstplayer.cxx
+++ b/avmedia/source/gstreamer/gstplayer.cxx
@@ -42,10 +42,6 @@
 #include "gstframegrabber.hxx"
 #include "gstwindow.hxx"
 
-#if ENABLE_QT5
-#include <QtWidgets/QWidget>
-#endif
-
 #include <gst/video/videooverlay.h>
 #define AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_GStreamer"
 #define AVMEDIA_GST_PLAYER_SERVICENAME        "com.sun.star.media.Player_GStreamer"
@@ -287,9 +283,6 @@ Player::Player() :
     GstPlayer_BASE( m_aMutex ),
     mpPlaybin( nullptr ),
     mpVolumeControl( nullptr ),
-#if ENABLE_GTK3
-    mpGtkWidget( nullptr ),
-#endif
     mbUseGtkSink( false ),
     mbFakeVideo (false ),
     mnUnmutedVolume( 0 ),
@@ -347,14 +340,6 @@ void SAL_CALL Player::disposing()
     // Release the elements and pipeline
     if( mbInitialized )
     {
-#if ENABLE_GTK3
-        if (mpGtkWidget)
-        {
-            gtk_widget_destroy(mpGtkWidget);
-            mpGtkWidget = nullptr;
-        }
-#endif
-
         if( mpPlaybin )
         {
             gst_element_set_state( mpPlaybin, GST_STATE_NULL );
@@ -557,14 +542,6 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
 
 void Player::preparePlaybin( const OUString& rURL, GstElement *pSink )
 {
-#if ENABLE_GTK3
-    if (mpGtkWidget)
-    {
-        gtk_widget_destroy(mpGtkWidget);
-        mpGtkWidget = nullptr;
-    }
-#endif
-
     if (mpPlaybin != nullptr)
     {
         gst_element_set_state( mpPlaybin, GST_STATE_NULL );
@@ -870,98 +847,64 @@ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( co
     if( aSize.Width > 0 && aSize.Height > 0 )
     {
         ::avmedia::gstreamer::Window* pWindow = new ::avmedia::gstreamer::Window;
+        if (rArguments.getLength() <= 2)
+        {
+            xRet = pWindow;
+            return xRet;
+        }
 
-        xRet = pWindow;
+        sal_IntPtr pIntPtr = 0;
+        rArguments[ 2 ] >>= pIntPtr;
+        SystemChildWindow *pParentWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );
+        if (!pParentWindow)
+            return nullptr;
+
+        const SystemEnvData* pEnvData = pParentWindow->GetSystemData();
+        if (!pEnvData)
+            return nullptr;
+
+        OUString aToolkit = OUString::createFromAscii(pEnvData->pToolkit);
+        OUString aPlatform = OUString::createFromAscii(pEnvData->pPlatformName);
 
-        if( rArguments.getLength() > 2 )
+        // tdf#124027: the position of embedded window is identical w/ the position
+        // of media object in all other vclplugs (gtk, kde5, gen), in gtk3 w/o gtksink it
+        // needs to be translated
+        if (aToolkit == "gtk3")
         {
-            sal_IntPtr pIntPtr = 0;
-            rArguments[ 2 ] >>= pIntPtr;
-            SystemChildWindow *pParentWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );
+            Point aPoint = pParentWindow->GetPosPixel();
+            maArea.X = aPoint.getX();
+            maArea.Y = aPoint.getY();
+        }
 
-            const SystemEnvData* pEnvData = pParentWindow ? pParentWindow->GetSystemData() : nullptr;
-            OSL_ASSERT(pEnvData);
-            if (pEnvData)
-            {
-                OUString aToolkit = OUString::createFromAscii(pEnvData->pToolkit);
-                OUString aPlatform = OUString::createFromAscii(pEnvData->pPlatformName);
-
-                // tdf#124027: the position of embedded window is identical w/ the position
-                // of media object in all other vclplugs (gtk, kde5, gen), in gtk3 w/o gtksink it
-                // needs to be translated
-                if (aToolkit == "gtk3")
-                {
-                    if (pParentWindow)
-                    {
-                        Point aPoint = pParentWindow->GetPosPixel();
-                        maArea.X = aPoint.getX();
-                        maArea.Y = aPoint.getY();
-                    }
-                }
+        mbUseGtkSink = false;
 
-                GstElement *pVideosink = nullptr;
-#if ENABLE_GTK3
-                pVideosink = (aToolkit == "gtk3") ?
-                              gst_element_factory_make("gtksink", "gtksink") : nullptr;
-                if (pVideosink)
-                {
-                    mbUseGtkSink = true;
-                    g_object_get(pVideosink, "widget", &mpGtkWidget, nullptr);
-                    gtk_widget_set_vexpand(mpGtkWidget, true);
-                    gtk_widget_set_hexpand(mpGtkWidget, true);
-                    GtkWidget *pParent = static_cast<GtkWidget*>(pEnvData->pWidget);
-                    gtk_container_add (GTK_CONTAINER(pParent), mpGtkWidget);
-
-                    g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pVideosink, nullptr);
-                    g_object_set( G_OBJECT( mpPlaybin ), "force-aspect-ratio", FALSE, nullptr);
-
-                    gtk_widget_show_all (pParent);
-                }
-                else
-#endif
-                {
-#if ENABLE_QT5
-                    // try to use qwidget5videosink for qt5 on Wayland, which requires the Qt5 packages for QtGStreamer to be installed
-                    if (aToolkit == "qt5" && aPlatform == "wayland")
-                    {
-                        pVideosink = gst_element_factory_make("qwidget5videosink", "qwidget5videosink");
-                        if (pVideosink) {
-                            QWidget* pQWidget = static_cast<QWidget*>(pEnvData->pWidget);
-                            g_object_set(G_OBJECT(pVideosink), "widget", pQWidget, nullptr);
-                        }
-                        else
-                        {
-                            SAL_WARN("avmedia.gstreamer", "Couldn't initialize qwidget5videosink."
-                                                          " Video playback might not work as expected."
-                                                          " Please install Qt5 packages for QtGStreamer.");
-                            // with no videosink explicitly set, GStreamer will open its own (misplaced) window(s) to display video
-                        }
-                    }
-#endif
-                    if (!pVideosink)
-                    {
-                        if (aPlatform == "wayland")
-                            pVideosink = gst_element_factory_make("waylandsink", "video-output");
-                        else
-                            pVideosink = gst_element_factory_make("autovideosink", "video-output");
-                    }
-
-                    if (!pVideosink)
-                    {
-                        xRet.clear();
-                        return nullptr;
-                    }
-                    g_object_set(G_OBJECT(mpPlaybin), "video-sink", pVideosink, nullptr);
-                    mbUseGtkSink = false;
-                    mnWindowID = pEnvData->aWindow;
-                    mpDisplay = pEnvData->pDisplay;
-                    SAL_INFO( "avmedia.gstreamer", AVVERSION "set window id to " << static_cast<int>(mnWindowID) << " XOverlay " << mpXOverlay);
-                    gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
-                    if ( mpXOverlay != nullptr )
-                        gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
-                }
-            }
+        GstElement *pVideosink = static_cast<GstElement*>(pParentWindow->CreateGStreamerSink());
+        if (pVideosink)
+        {
+            if (aToolkit == "gtk3")
+                mbUseGtkSink = true;
+        }
+        else
+        {
+            if (aPlatform == "wayland")
+                pVideosink = gst_element_factory_make("waylandsink", "video-output");
+            else
+                pVideosink = gst_element_factory_make("autovideosink", "video-output");
+            if (!pVideosink)
+                return nullptr;
         }
+
+        xRet = pWindow;
+
+        g_object_set(G_OBJECT(mpPlaybin), "video-sink", pVideosink, nullptr);
+        g_object_set(G_OBJECT(mpPlaybin), "force-aspect-ratio", FALSE, nullptr);
+
+        mnWindowID = pEnvData->aWindow;
+        mpDisplay = pEnvData->pDisplay;
+        SAL_INFO( "avmedia.gstreamer", AVVERSION "set window id to " << static_cast<int>(mnWindowID) << " XOverlay " << mpXOverlay);
+        gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
+        if ( mpXOverlay != nullptr )
+            gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
     }
 
     return xRet;
diff --git a/avmedia/source/gstreamer/gstplayer.hxx b/avmedia/source/gstreamer/gstplayer.hxx
index 9bc0e3eb4cb5..67aabb998d7a 100644
--- a/avmedia/source/gstreamer/gstplayer.hxx
+++ b/avmedia/source/gstreamer/gstplayer.hxx
@@ -20,8 +20,6 @@
 #ifndef INCLUDED_AVMEDIA_SOURCE_GSTREAMER_GSTPLAYER_HXX
 #define INCLUDED_AVMEDIA_SOURCE_GSTREAMER_GSTPLAYER_HXX
 
-#include <config_vclplug.h>
-
 #include <osl/conditn.hxx>
 #include "gstcommon.hxx"
 
@@ -29,10 +27,6 @@
 #include <cppuhelper/compbase.hxx>
 #include <cppuhelper/basemutex.hxx>
 
-#if ENABLE_GTK3
-#    include <gtk/gtk.h>
-#endif
-
 typedef struct _GstVideoOverlay GstVideoOverlay;
 
 namespace avmedia { namespace gstreamer {
@@ -85,9 +79,6 @@ private:
     // Add elements and pipeline here
     GstElement*             mpPlaybin;  // the playbin is also a pipeline
     GstElement*             mpVolumeControl;  // the playbin is also a pipeline
-#if ENABLE_GTK3
-    GtkWidget*              mpGtkWidget;
-#endif
     bool                    mbUseGtkSink;
     bool                    mbFakeVideo;
 
diff --git a/config_host.mk.in b/config_host.mk.in
index 3711857b5bd4..8eb33deb4645 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -466,9 +466,9 @@ export PYTHON_VERSION_MAJOR=@PYTHON_VERSION_MAJOR@
 export PYTHON_VERSION_MINOR=@PYTHON_VERSION_MINOR@
 export QT5_CFLAGS=$(gb_SPACE)@QT5_CFLAGS@
 export QT5_LIBS=$(gb_SPACE)@QT5_LIBS@
-export QT5_GLIB_CFLAGS=$(gb_SPACE)@QT5_GLIB_CFLAGS@
-export QT5_GLIB_LIBS=$(gb_SPACE)@QT5_GLIB_LIBS@
-export QT5_HAVE_GLIB=@QT5_HAVE_GLIB@
+export QT5_GOBJECT_CFLAGS=$(gb_SPACE)@QT5_GOBJECT_CFLAGS@
+export QT5_GOBJECT_LIBS=$(gb_SPACE)@QT5_GOBJECT_LIBS@
+export QT5_HAVE_GOBJECT=@QT5_HAVE_GOBJECT@
 export QXP_CFLAGS=$(gb_SPACE)@QXP_CFLAGS@
 export QXP_LIBS=$(gb_SPACE)@QXP_LIBS@
 export RANLIB=@RANLIB@
diff --git a/config_host/config_vclplug.h.in b/config_host/config_vclplug.h.in
index 0b9ca095e5ec..f634483173bb 100644
--- a/config_host/config_vclplug.h.in
+++ b/config_host/config_vclplug.h.in
@@ -13,4 +13,7 @@ Settings about which desktops have support enabled.
 #define ENABLE_KDE5 0
 #define ENABLE_QT5 0
 
+#define QT5_HAVE_GOBJECT 0
+#define ENABLE_GSTREAMER_1_0 0
+
 #endif
diff --git a/configure.ac b/configure.ac
index 5db4063c921f..56485ac37f6d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10512,6 +10512,7 @@ if test "$build_gstreamer_1_0" = "yes"; then
         GSTREAMER_1_0_CFLAGS=$(printf '%s' "$GSTREAMER_1_0_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
         FilterLibs "${GSTREAMER_1_0_LIBS}"
         GSTREAMER_1_0_LIBS="${filteredlibs}"
+        AC_DEFINE(ENABLE_GSTREAMER_1_0)
     else
         AC_MSG_RESULT([no])
     fi
@@ -11073,9 +11074,9 @@ QT5_CFLAGS=""
 QT5_LIBS=""
 QMAKE5="qmake"
 MOC5="moc"
-QT5_GLIB_CFLAGS=""
-QT5_GLIB_LIBS=""
-QT5_HAVE_GLIB=""
+QT5_GOBJECT_CFLAGS=""
+QT5_GOBJECT_LIBS=""
+QT5_HAVE_GOBJECT=""
 if test \( "$test_kde5" = "yes" -a "$ENABLE_KDE5" = "TRUE" \) -o \
         \( "$test_qt5" = "yes" -a "$ENABLE_QT5" = "TRUE" \) -o \
         \( "$test_gtk3_kde5" = "yes" -a "$ENABLE_GTK3_KDE5" = "TRUE" \)
@@ -11149,21 +11150,22 @@ then
 the root of your Qt installation by exporting QT5DIR before running "configure".])
     fi
 
-    # Glib is needed for properly handling Qt event loop with Qt's Glib integration enabled.
-    # Sets also QT5_GLIB_CFLAGS/QT5_GLIB_LIBS if successful.
-    PKG_CHECK_MODULES(QT5_GLIB,[glib-2.0 >= 2.4],
-        [
-            QT5_HAVE_GLIB=1
-        ],
-        AC_MSG_WARN([[No Glib found, Qt5 support will not use native file pickers!]])
-    )
+
+    if test "$build_gstreamer_1_0" = "yes"; then
+        PKG_CHECK_MODULES(QT5_GOBJECT,[gobject-2.0], [
+                QT5_HAVE_GOBJECT=1
+                AC_DEFINE(QT5_HAVE_GOBJECT)
+            ],
+            AC_MSG_WARN([[No GObject found, can't use QWidget GStreamer sink on wayland!]])
+        )
+    fi
 fi
 AC_SUBST(QT5_CFLAGS)
 AC_SUBST(QT5_LIBS)
 AC_SUBST(MOC5)
-AC_SUBST(QT5_GLIB_CFLAGS)
-AC_SUBST(QT5_GLIB_LIBS)
-AC_SUBST(QT5_HAVE_GLIB)
+AC_SUBST(QT5_GOBJECT_CFLAGS)
+AC_SUBST(QT5_GOBJECT_LIBS)
+AC_SUBST(QT5_HAVE_GOBJECT)
 
 dnl ===================================================================
 dnl KDE5 Integration
diff --git a/include/vcl/syschild.hxx b/include/vcl/syschild.hxx
index 9f5be6780064..e15295e79a78 100644
--- a/include/vcl/syschild.hxx
+++ b/include/vcl/syschild.hxx
@@ -57,6 +57,8 @@ public:
     void                    SetLeaveEnterBackgrounds(const css::uno::Sequence<css::uno::Any>& rLeaveArgs, const css::uno::Sequence<css::uno::Any>& rEnterArgs);
     // return the platform specific handle/id of this window;
     sal_IntPtr              GetParentWindowHandle();
+
+    void*                   CreateGStreamerSink();
 };
 
 #endif // INCLUDED_VCL_SYSCHILD_HXX
diff --git a/vcl/Library_vclplug_gtk3.mk b/vcl/Library_vclplug_gtk3.mk
index a77f3b300ad6..c0ad6cd21e52 100644
--- a/vcl/Library_vclplug_gtk3.mk
+++ b/vcl/Library_vclplug_gtk3.mk
@@ -28,6 +28,7 @@ $(eval $(call gb_Library_add_cxxflags,vclplug_gtk3, \
 $(eval $(call gb_Library_set_include,vclplug_gtk3,\
     $$(INCLUDE) \
     $$(GTK3_CFLAGS) \
+    $$(GSTREAMER_1_0_CFLAGS) \
     -I$(SRCDIR)/vcl/inc \
     -I$(SRCDIR)/vcl/unx \
     -I$(SRCDIR)/vcl/unx/gtk3 \
diff --git a/vcl/Library_vclplug_gtk3_kde5.mk b/vcl/Library_vclplug_gtk3_kde5.mk
index cfd370221dde..d67c53e2a6f5 100644
--- a/vcl/Library_vclplug_gtk3_kde5.mk
+++ b/vcl/Library_vclplug_gtk3_kde5.mk
@@ -36,6 +36,7 @@ $(eval $(call gb_Library_add_cxxflags,vclplug_gtk3_kde5,\
     $$(INCLUDE) \
     $$(GTK3_CFLAGS) \
     $(KF5_CFLAGS) \
+    $$(GSTREAMER_1_0_CFLAGS) \
 ))
 
 $(eval $(call gb_Library_add_defs,vclplug_gtk3_kde5,\
diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index 1a0546488bcd..c1aaccea84c8 100644
--- a/vcl/Library_vclplug_qt5.mk
+++ b/vcl/Library_vclplug_qt5.mk
@@ -25,6 +25,7 @@ $(eval $(call gb_Library_set_include,vclplug_qt5,\
     $$(INCLUDE) \
     -I$(SRCDIR)/vcl/inc \
     -I$(SRCDIR)/vcl/inc/qt5 \
+    $(GSTREAMER_1_0_CFLAGS) \
 ))
 
 $(eval $(call gb_Library_add_defs,vclplug_qt5,\
@@ -70,12 +71,12 @@ $(eval $(call gb_Library_add_libs,vclplug_qt5,\
     $(QT5_LIBS) \
 ))
 
-ifneq ($(QT5_HAVE_GLIB),)
+ifneq ($(QT5_HAVE_GOBJECT),)
 $(eval $(call gb_Library_add_cxxflags,vclplug_qt5,\
-    $(QT5_GLIB_CFLAGS) \
+    $(QT5_GOBJECT_CFLAGS) \
 ))
 $(eval $(call gb_Library_add_libs,vclplug_qt5,\
-    $(QT5_GLIB_LIBS) \
+    $(QT5_GOBJECT_LIBS) \
 ))
 endif
 
diff --git a/vcl/inc/qt5/Qt5Instance.hxx b/vcl/inc/qt5/Qt5Instance.hxx
index c87f3c93c1ac..6c4afd328ee2 100644
--- a/vcl/inc/qt5/Qt5Instance.hxx
+++ b/vcl/inc/qt5/Qt5Instance.hxx
@@ -151,6 +151,8 @@ public:
     virtual css::uno::Reference<css::uno::XInterface> CreateDropTarget() override;
 
     void UpdateStyle(bool bFontsChanged);
+
+    void* CreateGStreamerSink(const SystemChildWindow*) override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx
index db1ae606a593..51b0347f3247 100644
--- a/vcl/inc/salinst.hxx
+++ b/vcl/inc/salinst.hxx
@@ -50,6 +50,7 @@ namespace weld {
     class Widget;
     class Window;
 }
+class SystemChildWindow;
 struct SystemParentData;
 struct SalPrinterQueueInfo;
 class ImplJobSetup;
@@ -206,6 +207,8 @@ public:
     virtual OUString        getOSVersion() { return OUString("-"); }
 
     virtual const cairo_font_options_t* GetCairoFontOptions() { return nullptr; }
+
+    virtual void* CreateGStreamerSink(const SystemChildWindow*) { return nullptr; }
 };
 
 // called from SVMain
diff --git a/vcl/inc/unx/gstsink.hxx b/vcl/inc/unx/gstsink.hxx
new file mode 100644
index 000000000000..2dff94b02c12
--- /dev/null
+++ b/vcl/inc/unx/gstsink.hxx
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <config_vclplug.h>
+
+#if ENABLE_GSTREAMER_1_0
+#include <gst/gst.h>
+#include <dlfcn.h>
+
+typedef GstElement* (*GstElementFactoryName)(const gchar*, const gchar*);
+
+static GstElementFactoryName gstElementFactoryNameSymbol()
+{
+    return reinterpret_cast<GstElementFactoryName>(dlsym(nullptr, "gst_element_factory_make"));
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index c0e073cca845..cc2455a42eb8 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -254,6 +254,10 @@ public:
 
     std::shared_ptr<vcl::unx::GtkPrintWrapper> const & getPrintWrapper() const;
 
+#if GTK_CHECK_VERSION(3,0,0)
+    void* CreateGStreamerSink(const SystemChildWindow*) override;
+#endif
+
 private:
     GtkSalTimer *m_pTimer;
 #if GTK_CHECK_VERSION(3,0,0)
diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
index 52061f8b5ea1..ae5de33b3cd5 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -48,7 +48,7 @@
 #include <comphelper/flagguard.hxx>
 #include <sal/log.hxx>
 #include <osl/process.h>
-
+#include <unx/gstsink.hxx>
 #include <headless/svpbmp.hxx>
 
 #include <mutex>
@@ -488,6 +488,42 @@ void Qt5Instance::UpdateStyle(bool bFontsChanged)
         m_aUpdateStyleTimer.Start();
 }
 
+void* Qt5Instance::CreateGStreamerSink(const SystemChildWindow* pWindow)
+{
+#if ENABLE_GSTREAMER_1_0 && QT5_HAVE_GOBJECT
+    auto pSymbol = gstElementFactoryNameSymbol();
+    if (!pSymbol)
+        return nullptr;
+
+    const SystemEnvData* pEnvData = pWindow->GetSystemData();
+    if (!pEnvData)
+        return nullptr;
+
+    OUString aPlatform = OUString::createFromAscii(pEnvData->pPlatformName);
+    if (aPlatform != "wayland")
+        return nullptr;
+
+    GstElement* pVideosink = pSymbol("qwidget5videosink", "qwidget5videosink");
+    if (pVideosink)
+    {
+        QWidget* pQWidget = static_cast<QWidget*>(pEnvData->pWidget);
+        g_object_set(G_OBJECT(pVideosink), "widget", pQWidget, nullptr);
+    }
+    else
+    {
+        SAL_WARN("vcl.qt5", "Couldn't initialize qwidget5videosink."
+                            " Video playback might not work as expected."
+                            " Please install Qt5 packages for QtGStreamer.");
+        // with no videosink explicitly set, GStreamer will open it's own (misplaced) window(s) to display video
+    }
+
+    return pVideosink;
+#else
+    (void*)pWindow;
+    return nullptr;
+#endif
+}
+
 void Qt5Instance::AllocFakeCmdlineArgs(std::unique_ptr<char* []>& rFakeArgv,
                                        std::unique_ptr<int>& rFakeArgc,
                                        std::vector<FreeableCStr>& rFakeArgvFreeable)
diff --git a/vcl/source/window/syschild.cxx b/vcl/source/window/syschild.cxx
index e6f3e6013400..e7beacdf608c 100644
--- a/vcl/source/window/syschild.cxx
+++ b/vcl/source/window/syschild.cxx
@@ -185,4 +185,9 @@ sal_IntPtr SystemChildWindow::GetParentWindowHandle()
     return nRet;
 }
 
+void* SystemChildWindow::CreateGStreamerSink()
+{
+    return ImplGetSVData()->mpDefInst->CreateGStreamerSink(this);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index ec1f6d4e28bd..42a66e69b460 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -36,6 +36,7 @@
 #include <tools/fract.hxx>
 #include <tools/stream.hxx>
 #include <unotools/resmgr.hxx>
+#include <unx/gstsink.hxx>
 #include <vcl/ImageTree.hxx>
 #include <vcl/i18nhelp.hxx>
 #include <vcl/quickselectionengine.hxx>
@@ -10778,4 +10779,36 @@ weld::Window* GtkSalFrame::GetFrameWeld() const
     return m_xFrameWeld.get();
 }
 
+void* GtkInstance::CreateGStreamerSink(const SystemChildWindow *pWindow)
+{
+#if ENABLE_GSTREAMER_1_0
+    auto aSymbol = gstElementFactoryNameSymbol();
+    if (!aSymbol)
+        return nullptr;
+
+    const SystemEnvData* pEnvData = pWindow->GetSystemData();
+    if (!pEnvData)
+        return nullptr;
+
+    GstElement* pVideosink = aSymbol("gtksink", "gtksink");
+    if (!pVideosink)
+        return nullptr;
+
+    GtkWidget *pGstWidget;
+    g_object_get(pVideosink, "widget", &pGstWidget, nullptr);
+    gtk_widget_set_vexpand(pGstWidget, true);
+    gtk_widget_set_hexpand(pGstWidget, true);
+
+    GtkWidget *pParent = static_cast<GtkWidget*>(pEnvData->pWidget);
+    gtk_container_add(GTK_CONTAINER(pParent), pGstWidget);
+    g_object_unref(pGstWidget);
+    gtk_widget_show_all(pParent);
+
+    return pVideosink;
+#else
+    (void*)pWindow;
+    return nullptr;
+#endif
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list