summaryrefslogtreecommitdiff
path: root/avmedia/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2022-02-20 21:11:19 +0000
committerCaolán McNamara <caolanm@redhat.com>2022-02-21 09:37:49 +0100
commitb438854a0b5148880e455cbeeff14d4e3d825711 (patch)
tree195c9e40c94c05b34b05ec620d368595c754024f /avmedia/source
parentf049c3884f7a376374ed6cffea6746ef35b00186 (diff)
gtk4: get getPreferredPlayerWindowSize working
Change-Id: I5e5b02be6a902232c24120db513cdf3fc68b4421 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130224 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'avmedia/source')
-rw-r--r--avmedia/source/gtk/gtkplayer.cxx99
1 files changed, 55 insertions, 44 deletions
diff --git a/avmedia/source/gtk/gtkplayer.cxx b/avmedia/source/gtk/gtkplayer.cxx
index d75d7078ebd9..7ce488f231ec 100644
--- a/avmedia/source/gtk/gtkplayer.cxx
+++ b/avmedia/source/gtk/gtkplayer.cxx
@@ -231,6 +231,41 @@ sal_Int16 SAL_CALL GtkPlayer::getVolumeDB()
return m_nUnmutedVolume;
}
+namespace
+{
+void invalidate_size(GdkPaintable* /*paintable*/, Timer* pTimer) { pTimer->Stop(); }
+
+Size GetPreferredPlayerWindowSize(GdkPaintable* pStream)
+{
+ Size aSize(gdk_paintable_get_intrinsic_width(pStream),
+ gdk_paintable_get_intrinsic_height(pStream));
+
+ // This is pretty nasty, maybe for the XFrameGrabber case it could be
+ // possible to implement an XGraphic which can be updated when the
+ // information becomes available rather than explicitly wait for it here,
+ // but the getPreferredPlayerWindowSize problem would remain.
+ if (aSize.Width() == 0 && aSize.Height() == 0)
+ {
+ Timer aTimer("gtkplayer waiting to find out size");
+ aTimer.SetTimeout(3000);
+
+ gulong nSignalId
+ = g_signal_connect(pStream, "invalidate-size", G_CALLBACK(invalidate_size), &aTimer);
+
+ aTimer.Start();
+ while (aTimer.IsActive())
+ Application::Yield();
+
+ g_signal_handler_disconnect(pStream, nSignalId);
+
+ aSize = Size(gdk_paintable_get_intrinsic_width(pStream),
+ gdk_paintable_get_intrinsic_height(pStream));
+ }
+
+ return aSize;
+}
+}
+
awt::Size SAL_CALL GtkPlayer::getPreferredPlayerWindowSize()
{
osl::MutexGuard aGuard(m_aMutex);
@@ -239,14 +274,9 @@ awt::Size SAL_CALL GtkPlayer::getPreferredPlayerWindowSize()
if (m_pStream)
{
- double width;
- double height;
-
- gdk_paintable_compute_concrete_size(GDK_PAINTABLE(m_pStream), 0.0, 0.0, 100, 200, &width,
- &height);
-
- aSize.Width = gdk_paintable_get_intrinsic_width(GDK_PAINTABLE(m_pStream));
- aSize.Height = gdk_paintable_get_intrinsic_height(GDK_PAINTABLE(m_pStream));
+ Size aPrefSize = GetPreferredPlayerWindowSize(GDK_PAINTABLE(m_pStream));
+ aSize.Width = aPrefSize.Width();
+ aSize.Height = aPrefSize.Height();
}
return aSize;
@@ -299,19 +329,20 @@ namespace
{
class GtkFrameGrabber : public ::cppu::WeakImplHelper<css::media::XFrameGrabber>
{
+private:
+ awt::Size m_aSize;
GtkMediaStream* m_pStream;
public:
- GtkFrameGrabber(GtkMediaStream* pStream)
- : m_pStream(pStream)
+ GtkFrameGrabber(GtkMediaStream* pStream, const awt::Size& rSize)
+ : m_aSize(rSize)
+ , m_pStream(pStream)
{
g_object_ref(m_pStream);
}
virtual ~GtkFrameGrabber() override { g_object_unref(m_pStream); }
- static void invalidate_size(GdkPaintable* /*paintable*/, Timer* pTimer) { pTimer->Stop(); }
-
// XFrameGrabber
virtual css::uno::Reference<css::graphic::XGraphic>
SAL_CALL grabFrame(double fMediaTime) override
@@ -319,39 +350,11 @@ public:
gint64 gst_position = llround(fMediaTime * 1000000);
gtk_media_stream_seek(m_pStream, gst_position);
- Size aSize(gdk_paintable_get_intrinsic_width(GDK_PAINTABLE(m_pStream)),
- gdk_paintable_get_intrinsic_height(GDK_PAINTABLE(m_pStream)));
-
- // This is pretty nasty, maybe it could be possible to implement an
- // XGraphic which can be updated when the information becomes available
- // rather than explicitly wait for it here, but the
- // getPreferredPlayerWindowSize problem would remain.
- if (aSize.Width() == 0 && aSize.Height() == 0)
- {
- Timer aTimer("gtkplayer waiting to find out size");
- aTimer.SetTimeout(3000);
-
- gulong nSignalId = g_signal_connect(m_pStream, "invalidate-size",
- G_CALLBACK(invalidate_size), &aTimer);
-
- aTimer.Start();
- while (aTimer.IsActive())
- Application::Yield();
-
- g_signal_handler_disconnect(m_pStream, nSignalId);
-
- aSize = Size(gdk_paintable_get_intrinsic_width(GDK_PAINTABLE(m_pStream)),
- gdk_paintable_get_intrinsic_height(GDK_PAINTABLE(m_pStream)));
- }
-
- if (!aSize.Width() || !aSize.Height())
- return nullptr;
-
cairo_surface_t* surface
- = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.Width(), aSize.Height());
+ = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_aSize.Width, m_aSize.Height);
GtkSnapshot* snapshot = gtk_snapshot_new();
- gdk_paintable_snapshot(GDK_PAINTABLE(m_pStream), snapshot, aSize.Width(), aSize.Height());
+ gdk_paintable_snapshot(GDK_PAINTABLE(m_pStream), snapshot, m_aSize.Width, m_aSize.Height);
GskRenderNode* node = gtk_snapshot_free_to_node(snapshot);
cairo_t* cr = cairo_create(surface);
@@ -360,7 +363,8 @@ public:
gsk_render_node_unref(node);
- std::unique_ptr<BitmapEx> xBitmap(vcl::bitmap::CreateFromCairoSurface(aSize, surface));
+ std::unique_ptr<BitmapEx> xBitmap(
+ vcl::bitmap::CreateFromCairoSurface(Size(m_aSize.Width, m_aSize.Height), surface));
cairo_surface_destroy(surface);
@@ -372,7 +376,14 @@ public:
uno::Reference<media::XFrameGrabber> SAL_CALL GtkPlayer::createFrameGrabber()
{
osl::MutexGuard aGuard(m_aMutex);
- rtl::Reference<GtkFrameGrabber> xFrameGrabber(new GtkFrameGrabber(m_pStream));
+
+ rtl::Reference<GtkFrameGrabber> xFrameGrabber;
+
+ const awt::Size aPrefSize(getPreferredPlayerWindowSize());
+
+ if (aPrefSize.Width > 0 && aPrefSize.Height > 0)
+ xFrameGrabber.set(new GtkFrameGrabber(m_pStream, aPrefSize));
+
return xFrameGrabber;
}