diff --git a/avmedia/Library_avmediagst.mk b/avmedia/Library_avmediagst.mk index 923c474280b4..fcbaeebbc7ee 100644 --- a/avmedia/Library_avmediagst.mk +++ b/avmedia/Library_avmediagst.mk @@ -33,6 +33,7 @@ $(eval $(call gb_Library_use_libraries,avmediagst,\ salhelper \ tl \ vcl \ + avmedia \ )) $(eval $(call gb_Library_add_exception_objects,avmediagst,\ diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx index 49a3a3351ccf..7d7602b5b3eb 100644 --- a/avmedia/source/gstreamer/gstplayer.cxx +++ b/avmedia/source/gstreamer/gstplayer.cxx @@ -30,6 +30,8 @@ #include #include +#include + #include #include #include @@ -37,6 +39,8 @@ #include #include #include +#include +#include #include "gstplayer.hxx" #include "gstframegrabber.hxx" @@ -889,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(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()); diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx index 4bbad7889bb7..b74033e33749 100644 --- a/avmedia/source/viewer/mediawindow_impl.cxx +++ b/avmedia/source/viewer/mediawindow_impl.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -298,6 +299,9 @@ void MediaWindowImpl::updateMediaItem( MediaItem& rItem ) const void MediaWindowImpl::executeMediaItem( const MediaItem& rItem ) { + mpItem = &rItem; + comphelper::ScopeGuard g([this] { this->mpItem = nullptr; }); + const AVMediaSetMask nMaskSet = rItem.getMaskSet(); // set URL first @@ -418,7 +422,9 @@ void MediaWindowImpl::onURLChanged() uno::Sequence aArgs{ uno::Any(nParentWindowHandle), uno::Any(awt::Rectangle(aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height())), - uno::Any(reinterpret_cast(mpChildWindow.get())) + uno::Any(reinterpret_cast(mpChildWindow.get())), + // Media item contains media properties, e.g. cropping. + uno::Any(reinterpret_cast(mpItem)) }; try diff --git a/avmedia/source/viewer/mediawindow_impl.hxx b/avmedia/source/viewer/mediawindow_impl.hxx index 8bceebb08d15..aa95fde22444 100644 --- a/avmedia/source/viewer/mediawindow_impl.hxx +++ b/avmedia/source/viewer/mediawindow_impl.hxx @@ -150,6 +150,7 @@ private: VclPtr mpMediaWindowControl; std::unique_ptr mpEmptyBmpEx; std::unique_ptr mpAudioBmpEx; + const MediaItem* mpItem = nullptr; }; }} // end namespace avmedia::priv diff --git a/slideshow/source/engine/shapes/viewmediashape.cxx b/slideshow/source/engine/shapes/viewmediashape.cxx index f9257c3a5448..4c5b9f51f8f6 100644 --- a/slideshow/source/engine/shapes/viewmediashape.cxx +++ b/slideshow/source/engine/shapes/viewmediashape.cxx @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include @@ -442,10 +444,20 @@ namespace slideshow::internal aAWTRect.X = aAWTRect.Y = 0; + SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape); + auto pMediaObj = dynamic_cast(pObj); + const avmedia::MediaItem* pMediaItem = nullptr; + if (pMediaObj) + { + pMediaItem = &pMediaObj->getMediaProperties(); + } + uno::Sequence< uno::Any > aArgs{ uno::Any(nParentWindowHandle), uno::Any(aAWTRect), - uno::Any(reinterpret_cast< sal_IntPtr >( mpMediaWindow.get() )) + uno::Any(reinterpret_cast< sal_IntPtr >( mpMediaWindow.get() )), + // Media item contains media properties, e.g. cropping. + uno::Any(reinterpret_cast< sal_IntPtr >( pMediaItem )) }; mxPlayerWindow.set( mxPlayer->createPlayerWindow( aArgs ) ); diff --git a/svx/qa/unit/data/video-snapshot.pptx b/svx/qa/unit/data/video-snapshot.pptx index a212f105200f..76f7c0d503e6 100644 Binary files a/svx/qa/unit/data/video-snapshot.pptx and b/svx/qa/unit/data/video-snapshot.pptx differ diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx index a2bee4a8d30d..dacf558c5f7f 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -502,9 +502,9 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testVideoSnapshot) // Without the accompanying fix in place, this test would have failed with: // - Expected: rgba[ff0000ff] // - Actual : rgba[000000ff] - // i.e. the preview was black, not red; since we seeked 3 secs into the video, while PowerPoint + // i.e. the preview was black, not ~red; since we seeked 3 secs into the video, while PowerPoint // doesn't do that. - CPPUNIT_ASSERT_EQUAL(Color(0xff, 0x0, 0x0), rBitmap.GetPixelColor(0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(0xfe, 0x0, 0x0), rBitmap.GetPixelColor(0, 0)); // Without the accompanying fix in place, this test would have failed with: // - Expected: 321