avmedia/Library_avmediagst.mk | 1 avmedia/source/gstreamer/gstplayer.cxx | 30 ++++++++++++++++++++++ avmedia/source/viewer/mediawindow_impl.cxx | 8 +++++ avmedia/source/viewer/mediawindow_impl.hxx | 1 slideshow/source/engine/shapes/viewmediashape.cxx | 14 +++++++++- svx/qa/unit/data/video-snapshot.pptx |binary svx/qa/unit/svdraw.cxx | 4 +- 7 files changed, 54 insertions(+), 4 deletions(-)
New commits: commit 6894da107db06c66356e52844c4a8d263e0a64d8 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Aug 26 10:24:39 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Aug 29 15:29:58 2022 +0200 tdf#149971 avmedia: implement video crop support in the gsteamer backend If a media shape had cropping defined, we already took that into account when presenting a preview for it, but not during video playback. The reason for this is that the preview may be set by a file importer (e.g. PPTX) explicitly, in which case the preview is a bitmap we get without any video processing. As a start, implement video crop for the gstreamer backend (used on Linux), and also pass in the media item (containing crop and other properties) both during the edit view (MediaWindowImpl) and presenting (ViewMediaShape). We pass in the whole media item, so in case later other filters (e.g. black-and-white) are wanted, we have all that info in the backends already. Other backends (avmediaMacAVF and avmediawin) are untouched so far. svx/qa/unit/data/video-snapshot.pptx is modified to have a yellow border when cropping is unimplemented, which is now not visible with the gtreamer backend, matching PowerPoint behavior. PPTX export was working out of the box already. (cherry picked from commit 916848d877a788d02e2e7c980872314839101798) Conflicts: avmedia/source/viewer/mediawindow_impl.cxx Change-Id: If26b7a4391bcffe9cbddd9933e1bab69be52924e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138969 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/avmedia/Library_avmediagst.mk b/avmedia/Library_avmediagst.mk index 699d0197b50e..93ad7514f94b 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 397fe8809d93..6884654b6be3 100644 --- a/avmedia/source/gstreamer/gstplayer.cxx +++ b/avmedia/source/gstreamer/gstplayer.cxx @@ -29,6 +29,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> @@ -36,6 +38,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" @@ -866,6 +870,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()); diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx index fcc06488e913..0a0e80dc0d3f 100644 --- a/avmedia/source/viewer/mediawindow_impl.cxx +++ b/avmedia/source/viewer/mediawindow_impl.cxx @@ -30,6 +30,7 @@ #include <sal/log.hxx> #include <comphelper/processfactory.hxx> #include <tools/diagnose_ex.h> +#include <comphelper/scopeguard.hxx> #include <tools/urlobj.hxx> #include <unotools/securityoptions.hxx> #include <vcl/bitmapex.hxx> @@ -307,6 +308,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 @@ -427,7 +431,9 @@ void MediaWindowImpl::onURLChanged() uno::Sequence<uno::Any> aArgs{ uno::Any(nParentWindowHandle), uno::Any(awt::Rectangle(aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height())), - uno::Any(reinterpret_cast<sal_IntPtr>(mpChildWindow.get())) + uno::Any(reinterpret_cast<sal_IntPtr>(mpChildWindow.get())), + // Media item contains media properties, e.g. cropping. + uno::Any(reinterpret_cast<sal_IntPtr>(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<MediaWindowControl> mpMediaWindowControl; std::unique_ptr<BitmapEx> mpEmptyBmpEx; std::unique_ptr<BitmapEx> 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 52a86be889d7..0b24b12b2812 100644 --- a/slideshow/source/engine/shapes/viewmediashape.cxx +++ b/slideshow/source/engine/shapes/viewmediashape.cxx @@ -36,6 +36,8 @@ #include <canvas/canvastools.hxx> #include <cppcanvas/canvas.hxx> #include <avmedia/mediawindow.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdomedia.hxx> #include <com/sun/star/awt/XWindow.hpp> #include <com/sun/star/beans/XPropertySet.hpp> @@ -441,10 +443,20 @@ namespace slideshow::internal aAWTRect.X = aAWTRect.Y = 0; + SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape); + auto pMediaObj = dynamic_cast<SdrMediaObj*>(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 66400c375cf1..58d01e7f8905 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -490,9 +490,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