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@fbihome.de>
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 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")
|
||||
{
|
||||
Point aPoint = pParentWindow->GetPosPixel();
|
||||
maArea.X = aPoint.getX();
|
||||
maArea.Y = aPoint.getY();
|
||||
}
|
||||
|
||||
mbUseGtkSink = false;
|
||||
|
||||
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;
|
||||
|
||||
if( rArguments.getLength() > 2 )
|
||||
{
|
||||
sal_IntPtr pIntPtr = 0;
|
||||
rArguments[ 2 ] >>= pIntPtr;
|
||||
SystemChildWindow *pParentWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );
|
||||
g_object_set(G_OBJECT(mpPlaybin), "video-sink", pVideosink, nullptr);
|
||||
g_object_set(G_OBJECT(mpPlaybin), "force-aspect-ratio", FALSE, nullptr);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+3
-3
@@ -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@
|
||||
|
||||
@@ -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
|
||||
|
||||
+16
-14
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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,\
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: */
|
||||
@@ -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)
|
||||
|
||||
+37
-1
@@ -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)
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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: */
|
||||
|
||||
Reference in New Issue
Block a user