summaryrefslogtreecommitdiff
path: root/avmedia
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-08-26 10:24:39 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-08-26 11:48:41 +0200
commit916848d877a788d02e2e7c980872314839101798 (patch)
tree41b59d5cd2429765fe4d5d53ecd306a2a0f8003d /avmedia
parent2a7a576d19b9c212fd6f906f5e275fdf2266608e (diff)
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. Change-Id: If26b7a4391bcffe9cbddd9933e1bab69be52924e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138867 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'avmedia')
-rw-r--r--avmedia/Library_avmediagst.mk1
-rw-r--r--avmedia/source/gstreamer/gstplayer.cxx30
-rw-r--r--avmedia/source/viewer/mediawindow_impl.cxx8
-rw-r--r--avmedia/source/viewer/mediawindow_impl.hxx1
4 files changed, 39 insertions, 1 deletions
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 <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"
@@ -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<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 4bbad7889bb7..b74033e33749 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 <comphelper/diagnose_ex.hxx>
+#include <comphelper/scopeguard.hxx>
#include <tools/urlobj.hxx>
#include <unotools/securityoptions.hxx>
#include <vcl/bitmapex.hxx>
@@ -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<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