diff options
Diffstat (limited to 'avmedia/source/gstreamer/gstplayer.cxx')
-rw-r--r-- | avmedia/source/gstreamer/gstplayer.cxx | 99 |
1 files changed, 69 insertions, 30 deletions
diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx index b28be1678207..1a91a689299e 100644 --- a/avmedia/source/gstreamer/gstplayer.cxx +++ b/avmedia/source/gstreamer/gstplayer.cxx @@ -30,6 +30,8 @@ #include <vector> #include <math.h> +#include <com/sun/star/text/GraphicCrop.hpp> + #include <cppuhelper/supportsservice.hxx> #include <sal/log.hxx> #include <rtl/string.hxx> @@ -37,6 +39,8 @@ #include <vcl/svapp.hxx> #include <vcl/syschild.hxx> #include <vcl/sysdata.hxx> +#include <vcl/graph.hxx> +#include <avmedia/mediaitem.hxx> #include "gstplayer.hxx" #include "gstframegrabber.hxx" @@ -46,8 +50,6 @@ #include <gst/pbutils/missing-plugins.h> #include <gst/pbutils/pbutils.h> -constexpr OUStringLiteral AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME = u"com.sun.star.comp.avmedia.Player_GStreamer"; -constexpr OUStringLiteral AVMEDIA_GST_PLAYER_SERVICENAME = u"com.sun.star.media.Player_GStreamer"; #define AVVERSION "gst 1.0: " using namespace ::com::sun::star; @@ -95,7 +97,7 @@ private: DECL_STATIC_LINK(MissingPluginInstaller, launchUi, void*, void); - std::mutex mutex_; + std::recursive_mutex mutex_; std::set<OString> reported_; std::map<OString, std::set<rtl::Reference<Player>>> queued_; rtl::Reference<MissingPluginInstallerThread> currentThread_; @@ -242,13 +244,15 @@ IMPL_STATIC_LINK(MissingPluginInstaller, launchUi, void *, p, void) } -struct TheMissingPluginInstaller: - public rtl::Static<MissingPluginInstaller, TheMissingPluginInstaller> -{}; +MissingPluginInstaller& TheMissingPluginInstaller() +{ + static MissingPluginInstaller theInstaller; + return theInstaller; +} void MissingPluginInstallerThread::execute() { - MissingPluginInstaller & inst = TheMissingPluginInstaller::get(); + MissingPluginInstaller & inst = TheMissingPluginInstaller(); for (;;) { std::vector<OString> details; { @@ -285,7 +289,6 @@ Player::Player() : mbUseGtkSink( false ), mbFakeVideo (false ), mnUnmutedVolume( 0 ), - mbPlayPending ( false ), mbMuted( false ), mbLooping( false ), mbInitialized( false ), @@ -328,7 +331,7 @@ Player::~Player() void SAL_CALL Player::disposing() { - TheMissingPluginInstaller::get().detach(this); + TheMissingPluginInstaller().detach(this); ::osl::MutexGuard aGuard(m_aMutex); @@ -385,7 +388,6 @@ void Player::processMessage( GstMessage *message ) switch( GST_MESSAGE_TYPE( message ) ) { case GST_MESSAGE_EOS: gst_element_set_state( mpPlaybin, GST_STATE_READY ); - mbPlayPending = false; if (mbLooping) start(); break; @@ -401,9 +403,6 @@ void Player::processMessage( GstMessage *message ) { gst_video_overlay_expose(mpXOverlay); } - - if (mbPlayPending) - mbPlayPending = ((newstate == GST_STATE_READY) || (newstate == GST_STATE_PAUSED)); } break; default: @@ -447,6 +446,28 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message ) "error: '" << error->message << "' debug: '" << error_debug << "'"); } + else if ( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_WARNING ) + { + GError* error; + gchar* error_debug; + + gst_message_parse_warning( message, &error, &error_debug ); + SAL_WARN( + "avmedia.gstreamer", + "warning: '" << error->message << "' debug: '" + << error_debug << "'"); + } + else if ( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_INFO ) + { + GError* error; + gchar* error_debug; + + gst_message_parse_info( message, &error, &error_debug ); + SAL_WARN( + "avmedia.gstreamer", + "info: '" << error->message << "' debug: '" + << error_debug << "'"); + } #endif if (!mbUseGtkSink) @@ -512,7 +533,7 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message ) maSizeCondition.set(); } } else if (gst_is_missing_plugin_message(message)) { - TheMissingPluginInstaller::get().report(this, message); + TheMissingPluginInstaller().report(this, message); if( mnWidth == 0 ) { // an error occurred, set condition so that OOo thread doesn't wait for us maSizeCondition.set(); @@ -532,7 +553,6 @@ void Player::preparePlaybin( std::u16string_view rURL, GstElement *pSink ) if (mpPlaybin != nullptr) { gst_element_set_state( mpPlaybin, GST_STATE_NULL ); - mbPlayPending = false; g_object_unref( mpPlaybin ); } @@ -597,7 +617,6 @@ bool Player::create( const OUString& rURL ) preparePlaybin( rURL, gst_element_factory_make( "fakesink", nullptr ) ); gst_element_set_state( mpPlaybin, GST_STATE_PAUSED ); - mbPlayPending = false; bRet = true; } @@ -610,7 +629,6 @@ bool Player::create( const OUString& rURL ) return bRet; } - void SAL_CALL Player::start() { ::osl::MutexGuard aGuard(m_aMutex); @@ -619,10 +637,10 @@ void SAL_CALL Player::start() if( mbInitialized && mpPlaybin != nullptr ) { gst_element_set_state( mpPlaybin, GST_STATE_PLAYING ); - mbPlayPending = true; } -} + SAL_INFO( "avmedia.gstreamer", AVVERSION "start " << mpPlaybin ); +} void SAL_CALL Player::stop() { @@ -632,29 +650,24 @@ void SAL_CALL Player::stop() if( mpPlaybin ) gst_element_set_state( mpPlaybin, GST_STATE_PAUSED ); - mbPlayPending = false; SAL_INFO( "avmedia.gstreamer", AVVERSION "stop " << mpPlaybin ); } - sal_Bool SAL_CALL Player::isPlaying() { ::osl::MutexGuard aGuard(m_aMutex); - bool bRet = mbPlayPending; + bool bRet = false; - // return whether the pipeline is in PLAYING STATE or not - if( !mbPlayPending && mbInitialized && mpPlaybin ) + // return whether the pipeline target is PLAYING STATE or not + if (mbInitialized && mpPlaybin) { - bRet = GST_STATE( mpPlaybin ) == GST_STATE_PLAYING; + bRet = GST_STATE_TARGET(mpPlaybin) == GST_STATE_PLAYING; } - SAL_INFO( "avmedia.gstreamer", AVVERSION "isPlaying " << bRet ); - return bRet; } - double SAL_CALL Player::getDuration() { ::osl::MutexGuard aGuard(m_aMutex); @@ -880,6 +893,32 @@ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( co g_object_set(G_OBJECT(mpPlaybin), "video-sink", pVideosink, nullptr); g_object_set(G_OBJECT(mpPlaybin), "force-aspect-ratio", FALSE, nullptr); + if ((rArguments.getLength() >= 4) && (rArguments[3] >>= pIntPtr) && pIntPtr) + { + auto pItem = reinterpret_cast<const avmedia::MediaItem*>(pIntPtr); + Graphic aGraphic = pItem->getGraphic(); + const text::GraphicCrop& rCrop = pItem->getCrop(); + if (!aGraphic.IsNone() && (rCrop.Bottom > 0 || rCrop.Left > 0 || rCrop.Right > 0 || rCrop.Top > 0)) + { + // The media item has a non-empty cropping set. Try to crop the video accordingly. + Size aPref = aGraphic.GetPrefSize(); + Size aPixel = aGraphic.GetSizePixel(); + tools::Long nLeft = aPixel.getWidth() * rCrop.Left / aPref.getWidth(); + tools::Long nTop = aPixel.getHeight() * rCrop.Top / aPref.getHeight(); + tools::Long nRight = aPixel.getWidth() * rCrop.Right / aPref.getWidth(); + tools::Long nBottom = aPixel.getHeight() * rCrop.Bottom / aPref.getHeight(); + GstElement* pVideoFilter = gst_element_factory_make("videocrop", nullptr); + if (pVideoFilter) + { + g_object_set(G_OBJECT(pVideoFilter), "left", nLeft, nullptr); + g_object_set(G_OBJECT(pVideoFilter), "top", nTop, nullptr); + g_object_set(G_OBJECT(pVideoFilter), "right", nRight, nullptr); + g_object_set(G_OBJECT(pVideoFilter), "bottom", nBottom, nullptr); + g_object_set(G_OBJECT(mpPlaybin), "video-filter", pVideoFilter, nullptr); + } + } + } + if (!mbUseGtkSink) { mnWindowID = pEnvData->GetWindowHandle(pParentWindow->ImplGetFrame()); @@ -910,7 +949,7 @@ uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber() OUString SAL_CALL Player::getImplementationName() { - return AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME; + return u"com.sun.star.comp.avmedia.Player_GStreamer"_ustr; } @@ -922,7 +961,7 @@ sal_Bool SAL_CALL Player::supportsService( const OUString& ServiceName ) uno::Sequence< OUString > SAL_CALL Player::getSupportedServiceNames() { - return { AVMEDIA_GST_PLAYER_SERVICENAME }; + return { u"com.sun.star.media.Player_GStreamer"_ustr }; } } // namespace |