avmedia/source/inc/mediamisc.hxx | 7 ++- avmedia/source/qt6/QtPlayer.cxx | 51 +++++++++++++++++++++++++++-- avmedia/source/viewer/mediawindow_impl.cxx | 11 ++---- avmedia/source/viewer/mediawindow_impl.hxx | 3 - 4 files changed, 59 insertions(+), 13 deletions(-)
New commits: commit 3ab82581e5a5abc03c7ff06eac76a0b2fa0c9c34 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri May 2 17:39:53 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri May 2 22:29:20 2025 +0200 avmedia: Move context retrieval a level down Call comphelper::getProcessComponentContext directly in MediaWindowImpl::createPlayer instead of passing the XComponentContext as a param. Change-Id: If349dfe1b5a8216ba971233249bb135c1a7d2019 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184914 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx index 71d449b75748..513c6b89fb30 100644 --- a/avmedia/source/viewer/mediawindow_impl.cxx +++ b/avmedia/source/viewer/mediawindow_impl.cxx @@ -185,24 +185,23 @@ uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rUR // currently there isn't anything else, throw any mime type to the media players //if (!pMimeType || *pMimeType == AVMEDIA_MIMETYPE_COMMON) { - const uno::Reference<uno::XComponentContext>& xContext(::comphelper::getProcessComponentContext()); const OUString sToolkitName = Application::GetToolkitName(); if (sToolkitName == "gtk4") - xPlayer = createPlayer(rURL, u"com.sun.star.comp.avmedia.Manager_Gtk"_ustr, xContext); + xPlayer = createPlayer(rURL, u"com.sun.star.comp.avmedia.Manager_Gtk"_ustr); else if (sToolkitName.startsWith(u"kf6") || sToolkitName.startsWith(u"qt6")) - xPlayer = createPlayer(rURL, u"com.sun.star.comp.avmedia.Manager_Qt"_ustr, xContext); + xPlayer = createPlayer(rURL, u"com.sun.star.comp.avmedia.Manager_Qt"_ustr); else - xPlayer = createPlayer(rURL, AVMEDIA_MANAGER_SERVICE_NAME, xContext); + xPlayer = createPlayer(rURL, AVMEDIA_MANAGER_SERVICE_NAME); } return xPlayer; } uno::Reference< media::XPlayer > MediaWindowImpl::createPlayer( - const OUString& rURL, const OUString& rManagerServName, - const uno::Reference< uno::XComponentContext >& xContext) + const OUString& rURL, const OUString& rManagerServName) { uno::Reference< media::XPlayer > xPlayer; + const uno::Reference<uno::XComponentContext>& xContext = ::comphelper::getProcessComponentContext(); try { uno::Reference< media::XManager > xManager ( diff --git a/avmedia/source/viewer/mediawindow_impl.hxx b/avmedia/source/viewer/mediawindow_impl.hxx index bddda2665c56..7c2b07a19efa 100644 --- a/avmedia/source/viewer/mediawindow_impl.hxx +++ b/avmedia/source/viewer/mediawindow_impl.hxx @@ -137,8 +137,7 @@ private: void onURLChanged(); - static css::uno::Reference<css::media::XPlayer> createPlayer(const OUString& rURL, const OUString& rManagerServName, - const css::uno::Reference<css::uno::XComponentContext>& xContext); + static css::uno::Reference<css::media::XPlayer> createPlayer(const OUString& rURL, const OUString& rManagerServName); OUString maFileURL; OUString mTempFileURL; commit 821fcbfe97a1b5b1c9fc886c226dfc2bad8d4336 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri May 2 17:31:01 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri May 2 22:29:13 2025 +0200 avmedia: Use constexpr OUString Change-Id: Iaed5bd5c6e3ef75d7b1a210a10a9085648d90676 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184913 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/avmedia/source/inc/mediamisc.hxx b/avmedia/source/inc/mediamisc.hxx index f45f5b50da0b..53983aa27370 100644 --- a/avmedia/source/inc/mediamisc.hxx +++ b/avmedia/source/inc/mediamisc.hxx @@ -24,12 +24,13 @@ #include <unotools/resmgr.hxx> #ifdef _WIN32 -#define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.comp.avmedia.Manager_DirectX" +constexpr OUString AVMEDIA_MANAGER_SERVICE_NAME = u"com.sun.star.comp.avmedia.Manager_DirectX"_ustr; #else #ifdef MACOSX -#define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.comp.avmedia.Manager_MacAVF" +constexpr OUString AVMEDIA_MANAGER_SERVICE_NAME = u"com.sun.star.comp.avmedia.Manager_MacAVF"_ustr; #else -#define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.comp.avmedia.Manager_GStreamer" +constexpr OUString AVMEDIA_MANAGER_SERVICE_NAME + = u"com.sun.star.comp.avmedia.Manager_GStreamer"_ustr; #endif #endif diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx index 823152e3b029..71d449b75748 100644 --- a/avmedia/source/viewer/mediawindow_impl.cxx +++ b/avmedia/source/viewer/mediawindow_impl.cxx @@ -192,7 +192,7 @@ uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rUR else if (sToolkitName.startsWith(u"kf6") || sToolkitName.startsWith(u"qt6")) xPlayer = createPlayer(rURL, u"com.sun.star.comp.avmedia.Manager_Qt"_ustr, xContext); else - xPlayer = createPlayer(rURL, u"" AVMEDIA_MANAGER_SERVICE_NAME ""_ustr, xContext); + xPlayer = createPlayer(rURL, AVMEDIA_MANAGER_SERVICE_NAME, xContext); } return xPlayer; commit 08533ca4e2526644b803c40c0c3d3c96f43762af Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri May 2 17:52:19 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri May 2 22:29:07 2025 +0200 tdf#166055 avmedia qt: Use GStreamer frame grabber by default As described in tdf#166055, QtFrameGrabber currently still causes issues (freezes or crashes). The QtMultimedia API does not provide a simple way to synchronously retrieve a video frame, so the current approach is to connect to the QVideoSink::videoFrameChanged signal and start playing the video until the first frame arrives. There are various QtMultimedia plugins/backends (at least GStreamer and ffmpeg for Linux). Some use multiple threads internally. Some logic needs to be run in the main thread however, so it's not possible to move things to a separate thread/event loop to decouple it from the main thread. As a consequence, there is a need to trigger event processing while waiting for the frame, as QVideoSink::videoFrameChanged would otherwise never be called. Triggering event processing can have bad side-effects however, as seen in tdf#166055, e.g. leading to endless recursion or crashes when processing LO events. See also commit 697405b533a8ae5b6a8f5bd184b9344a96f71c69 Author: Michael Weghorn <m.wegh...@posteo.de> Date: Wed Apr 9 09:42:45 2025 +0200 tdf#166055 qt avmedia: Provide media/player size right away for more background and some thoughts. For now, avoid the problem by using the GStreamer based frame grabber even with QtPlayer by default. This means that the QtMultimedia framework is still used for video playback with the qt6 VCL plugin, where LO's GStreamer implementation doesn't work properly, see commit 441d8ed9be0e7f831b455a69b8688dcb79a8bc00 Author: Michael Weghorn <m.wegh...@posteo.de> Date: Mon May 20 16:25:09 2024 +0200 tdf#145735 avmedia qt: Use QtMultimedia for Qt 6 media playback . However, in order to preview images (that are e.g. shown in Impress when not in presentation mode) the LO GStreamer backend is used now. (That works fine, no UI interaction is needed for that.) Adjust QtPlayer::createFrameGrabber accordingly to return the LO default platform player/frame grabber implementation (which is the GStreamer one on Linux), see also MediaWindowImpl::createPlayer. Use the service to avoid having to link GStreamer libraries. However, allow to force the use of QtFrameGrabber by setting environment variable SAL_VCL_QT_USE_QT_FRAME_GRABBER. Change-Id: Ibe5c42adf6e8f699f33e5f089bd2f6076c3de4f7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184912 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/avmedia/source/qt6/QtPlayer.cxx b/avmedia/source/qt6/QtPlayer.cxx index 1be226b248dd..dc0dea9fb05a 100644 --- a/avmedia/source/qt6/QtPlayer.cxx +++ b/avmedia/source/qt6/QtPlayer.cxx @@ -17,6 +17,9 @@ #include <QtWidgets/QLabel> #include <QtWidgets/QLayout> +#include <com/sun/star/media/XManager.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <comphelper/processfactory.hxx> #include <cppuhelper/supportsservice.hxx> #include <sal/log.hxx> #include <rtl/string.hxx> @@ -30,6 +33,7 @@ #include <vcl/timer.hxx> #include <gstwindow.hxx> +#include <mediamisc.hxx> #include "QtFrameGrabber.hxx" #include "QtPlayer.hxx" @@ -245,12 +249,55 @@ uno::Reference<::media::XPlayerWindow> return xRet; } +namespace +{ +// see also MediaWindowImpl::createPlayer +uno::Reference<media::XFrameGrabber> createPlatformFrameGrabber(const OUString& rUrl) +{ + const uno::Reference<uno::XComponentContext>& xContext + = comphelper::getProcessComponentContext(); + try + { + uno::Reference<css::media::XManager> xManager( + xContext->getServiceManager()->createInstanceWithContext(AVMEDIA_MANAGER_SERVICE_NAME, + xContext), + uno::UNO_QUERY); + if (!xManager.is()) + return nullptr; + + uno::Reference<media::XPlayer> xPlayer = xManager->createPlayer(rUrl); + if (!xPlayer.is()) + return nullptr; + + return xPlayer->createFrameGrabber(); + } + catch (const uno::Exception&) + { + SAL_WARN("avmedia", "Exception in createPlatformFrameGrabber"); + } + + return nullptr; +} +} + uno::Reference<media::XFrameGrabber> SAL_CALL QtPlayer::createFrameGrabber() { osl::MutexGuard aGuard(m_aMutex); - rtl::Reference<QtFrameGrabber> xFrameGrabber = new QtFrameGrabber(m_xMediaPlayer->source()); - return xFrameGrabber; + // use the default platform frame grabber (GStreamer on Linux) by default + // instead of using QtFrameGrabber for now unless overriden by env variable, + // as QtFrameGrabber has issues (see e.g. tdf#166055) + static const bool bPreferQtFrameGrabber + = (getenv("SAL_VCL_QT_USE_QT_FRAME_GRABBER") != nullptr); + if (!bPreferQtFrameGrabber) + { + uno::Reference<media::XFrameGrabber> xFrameGrabber + = createPlatformFrameGrabber(toOUString(m_xMediaPlayer->source().url())); + if (xFrameGrabber.is()) + return xFrameGrabber; + } + + return new QtFrameGrabber(m_xMediaPlayer->source()); } OUString SAL_CALL QtPlayer::getImplementationName()