summaryrefslogtreecommitdiffstats
path: root/avmedia/source/gstreamer
diff options
context:
space:
mode:
Diffstat (limited to 'avmedia/source/gstreamer')
-rw-r--r--avmedia/source/gstreamer/gstframegrabber.cxx21
-rw-r--r--avmedia/source/gstreamer/gstmanager.cxx2
-rw-r--r--avmedia/source/gstreamer/gstplayer.cxx99
-rw-r--r--avmedia/source/gstreamer/gstplayer.hxx1
-rw-r--r--avmedia/source/gstreamer/gstwindow.cxx5
-rw-r--r--avmedia/source/gstreamer/gstwindow.hxx2
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 {