summaryrefslogtreecommitdiff
path: root/avmedia/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2022-02-20 20:58:17 +0000
committerCaolán McNamara <caolanm@redhat.com>2022-02-21 09:37:35 +0100
commitf049c3884f7a376374ed6cffea6746ef35b00186 (patch)
tree26b2ac882432530a45113f7c4ed59473cea6f0c1 /avmedia/source
parent56c4445a8060d8ef6aec78f54ea28f4d7e5a8aa7 (diff)
gtk4: get XFrameGrabber to work
Change-Id: I737fd72d11b11d0c3592857113e422f29da76e77 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130223 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'avmedia/source')
-rw-r--r--avmedia/source/gtk/gtkplayer.cxx71
1 files changed, 40 insertions, 31 deletions
diff --git a/avmedia/source/gtk/gtkplayer.cxx b/avmedia/source/gtk/gtkplayer.cxx
index 098e8b3b6fe6..d75d7078ebd9 100644
--- a/avmedia/source/gtk/gtkplayer.cxx
+++ b/avmedia/source/gtk/gtkplayer.cxx
@@ -13,12 +13,14 @@
#include <cppuhelper/supportsservice.hxx>
#include <sal/log.hxx>
-#include <vcl/BitmapTools.hxx>
#include <rtl/string.hxx>
+#include <tools/link.hxx>
+#include <vcl/BitmapTools.hxx>
#include <vcl/graph.hxx>
#include <vcl/svapp.hxx>
#include <vcl/syschild.hxx>
#include <vcl/sysdata.hxx>
+#include <vcl/timer.hxx>
#include <gstwindow.hxx>
#include "gtkplayer.hxx"
@@ -237,6 +239,12 @@ 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));
}
@@ -297,40 +305,53 @@ public:
GtkFrameGrabber(GtkMediaStream* pStream)
: 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
{
- GtkWidget* pWindow = gtk_window_new();
- GtkWidget* pVideo = gtk_picture_new_for_paintable(GDK_PAINTABLE(m_pStream));
- gtk_window_set_child(GTK_WINDOW(pWindow), pVideo);
- gtk_widget_realize(pVideo);
- gtk_widget_map(pVideo);
-
- //bool bMuted = gtk_media_stream_get_muted(m_pStream);
- gtk_media_stream_set_muted(m_pStream, true);
- gtk_media_stream_set_volume(m_pStream, 0);
gint64 gst_position = llround(fMediaTime * 1000000);
gtk_media_stream_seek(m_pStream, gst_position);
- gtk_media_stream_play(m_pStream);
- // while (!gtk_media_stream_is_prepared(m_pStream))
- // Application::Yield();
+ Size aSize(gdk_paintable_get_intrinsic_width(GDK_PAINTABLE(m_pStream)),
+ gdk_paintable_get_intrinsic_height(GDK_PAINTABLE(m_pStream)));
- gtk_media_stream_pause(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);
- GdkPaintable* current_paintable = gdk_paintable_get_current_image(GDK_PAINTABLE(m_pStream));
+ gulong nSignalId = g_signal_connect(m_pStream, "invalidate-size",
+ G_CALLBACK(invalidate_size), &aTimer);
- // gtk_media_stream_set_muted(m_pStream, bMuted);
+ 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;
- Size aSize(200, 200);
cairo_surface_t* surface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.Width(), aSize.Height());
GtkSnapshot* snapshot = gtk_snapshot_new();
- gdk_paintable_snapshot(current_paintable, snapshot, aSize.Width(), aSize.Height());
+ gdk_paintable_snapshot(GDK_PAINTABLE(m_pStream), snapshot, aSize.Width(), aSize.Height());
GskRenderNode* node = gtk_snapshot_free_to_node(snapshot);
cairo_t* cr = cairo_create(surface);
@@ -338,14 +359,11 @@ public:
cairo_destroy(cr);
gsk_render_node_unref(node);
- g_object_unref(current_paintable);
std::unique_ptr<BitmapEx> xBitmap(vcl::bitmap::CreateFromCairoSurface(aSize, surface));
cairo_surface_destroy(surface);
- gtk_window_destroy(GTK_WINDOW(pWindow));
-
return Graphic(*xBitmap).GetXGraphic();
}
};
@@ -354,16 +372,7 @@ public:
uno::Reference<media::XFrameGrabber> SAL_CALL GtkPlayer::createFrameGrabber()
{
osl::MutexGuard aGuard(m_aMutex);
- rtl::Reference<GtkFrameGrabber> xFrameGrabber;
- SAL_WARN("avmedia.gtk", "TODO: createFrameGrabber");
-
- // const awt::Size aPrefSize(getPreferredPlayerWindowSize());
-
- xFrameGrabber.set(new GtkFrameGrabber(m_pStream));
-
- // if( ( aPrefSize.Width > 0 ) && ( aPrefSize.Height > 0 ) )
- // pFrameGrabber = FrameGrabber::create( maURL );
-
+ rtl::Reference<GtkFrameGrabber> xFrameGrabber(new GtkFrameGrabber(m_pStream));
return xFrameGrabber;
}