diff options
Diffstat (limited to 'avmedia/source/gstreamer')
-rw-r--r-- | avmedia/source/gstreamer/gstframegrabber.cxx | 21 | ||||
-rw-r--r-- | avmedia/source/gstreamer/gstmanager.cxx | 2 | ||||
-rw-r--r-- | avmedia/source/gstreamer/gstplayer.cxx | 99 | ||||
-rw-r--r-- | avmedia/source/gstreamer/gstplayer.hxx | 1 | ||||
-rw-r--r-- | avmedia/source/gstreamer/gstwindow.cxx | 5 | ||||
-rw-r--r-- | avmedia/source/gstreamer/gstwindow.hxx | 2 |
6 files changed, 85 insertions, 45 deletions
diff --git a/avmedia/source/gstreamer/gstframegrabber.cxx b/avmedia/source/gstreamer/gstframegrabber.cxx index ece799d87530..d8f96bd5e568 100644 --- a/avmedia/source/gstreamer/gstframegrabber.cxx +++ b/avmedia/source/gstreamer/gstframegrabber.cxx @@ -31,8 +31,7 @@ #include <string> -constexpr OUStringLiteral AVMEDIA_GST_FRAMEGRABBER_IMPLEMENTATIONNAME = u"com.sun.star.comp.avmedia.FrameGrabber_GStreamer"; -constexpr OUStringLiteral AVMEDIA_GST_FRAMEGRABBER_SERVICENAME = u"com.sun.star.media.FrameGrabber_GStreamer"; +constexpr OUString AVMEDIA_GST_FRAMEGRABBER_SERVICENAME = u"com.sun.star.media.FrameGrabber_GStreamer"_ustr; using namespace ::com::sun::star; @@ -50,11 +49,9 @@ void FrameGrabber::disposePipeline() FrameGrabber::FrameGrabber( std::u16string_view rURL ) { - gchar *pPipelineStr; - pPipelineStr = g_strdup_printf( - "uridecodebin uri=%s ! videoconvert ! videoscale ! appsink " - "name=sink caps=\"video/x-raw,format=RGB,pixel-aspect-ratio=1/1\"", - OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ).getStr() ); + const char pPipelineStr[] = + "uridecodebin name=source ! videoconvert ! videoscale ! appsink " + "name=sink caps=\"video/x-raw,format=RGB,pixel-aspect-ratio=1/1\""; GError *pError = nullptr; mpPipeline = gst_parse_launch( pPipelineStr, &pError ); @@ -65,6 +62,12 @@ FrameGrabber::FrameGrabber( std::u16string_view rURL ) } if( mpPipeline ) { + + if (GstElement *pUriDecode = gst_bin_get_by_name(GST_BIN(mpPipeline), "source")) + g_object_set(pUriDecode, "uri", OUStringToOString(rURL, RTL_TEXTENCODING_UTF8).getStr(), nullptr); + else + g_warning("Missing 'source' element in gstreamer pipeline"); + // pre-roll switch( gst_element_set_state( mpPipeline, GST_STATE_PAUSED ) ) { case GST_STATE_CHANGE_FAILURE: @@ -146,7 +149,7 @@ uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMe pData = aMapInfo.data; int nStride = GST_ROUND_UP_4( nWidth * 3 ); - BitmapEx aBmp = vcl::bitmap::CreateFromData(pData, nWidth, nHeight, nStride, vcl::PixelFormat::N24_BPP); + BitmapEx aBmp = vcl::bitmap::CreateFromData(pData, nWidth, nHeight, nStride, /*nBitsPerPixel*/24); gst_buffer_unmap( pBuf, &aMapInfo ); xRet = Graphic( aBmp ).GetXGraphic(); @@ -157,7 +160,7 @@ uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMe OUString SAL_CALL FrameGrabber::getImplementationName( ) { - return AVMEDIA_GST_FRAMEGRABBER_IMPLEMENTATIONNAME; + return u"com.sun.star.comp.avmedia.FrameGrabber_GStreamer"_ustr; } sal_Bool SAL_CALL FrameGrabber::supportsService( const OUString& ServiceName ) diff --git a/avmedia/source/gstreamer/gstmanager.cxx b/avmedia/source/gstreamer/gstmanager.cxx index 1803b5880bc1..54d23541676e 100644 --- a/avmedia/source/gstreamer/gstmanager.cxx +++ b/avmedia/source/gstreamer/gstmanager.cxx @@ -50,7 +50,7 @@ uno::Reference< media::XPlayer > SAL_CALL Manager::createPlayer( const OUString& OUString SAL_CALL Manager::getImplementationName( ) { - return "com.sun.star.comp.avmedia.Manager_GStreamer"; + return "com.sun.star.comp.media.Manager_GStreamer"; } sal_Bool SAL_CALL Manager::supportsService( const OUString& ServiceName ) 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 diff --git a/avmedia/source/gstreamer/gstplayer.hxx b/avmedia/source/gstreamer/gstplayer.hxx index a82dac3f2b39..2694ac00ce7e 100644 --- a/avmedia/source/gstreamer/gstplayer.hxx +++ b/avmedia/source/gstreamer/gstplayer.hxx @@ -86,7 +86,6 @@ private: bool mbFakeVideo; gdouble mnUnmutedVolume; - bool mbPlayPending; bool mbMuted; bool mbLooping; bool mbInitialized; diff --git a/avmedia/source/gstreamer/gstwindow.cxx b/avmedia/source/gstreamer/gstwindow.cxx index 5f7958e723c3..2d9aec0418b3 100644 --- a/avmedia/source/gstreamer/gstwindow.cxx +++ b/avmedia/source/gstreamer/gstwindow.cxx @@ -22,10 +22,9 @@ #include <cppuhelper/supportsservice.hxx> #include "gstwindow.hxx" -#include "gstplayer.hxx" -constexpr OUStringLiteral AVMEDIA_GST_WINDOW_IMPLEMENTATIONNAME = u"com.sun.star.comp.avmedia.Window_GStreamer"; -constexpr OUStringLiteral AVMEDIA_GST_WINDOW_SERVICENAME = u"com.sun.star.media.Window_GStreamer"; +constexpr OUString AVMEDIA_GST_WINDOW_IMPLEMENTATIONNAME = u"com.sun.star.comp.avmedia.Window_GStreamer"_ustr; +constexpr OUString AVMEDIA_GST_WINDOW_SERVICENAME = u"com.sun.star.media.Window_GStreamer"_ustr; using namespace ::com::sun::star; diff --git a/avmedia/source/gstreamer/gstwindow.hxx b/avmedia/source/gstreamer/gstwindow.hxx index c9d633d5434f..ff8a7cc91566 100644 --- a/avmedia/source/gstreamer/gstwindow.hxx +++ b/avmedia/source/gstreamer/gstwindow.hxx @@ -19,10 +19,10 @@ #pragma once -#include "gstcommon.hxx" #include <cppuhelper/implbase.hxx> #include <cppuhelper/interfacecontainer.h> +#include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/media/XPlayerWindow.hpp> namespace avmedia::gstreamer { |