avmedia/source/gtk/gtkplayer.cxx |   94 +++++++++++++++++++++++----------------
 1 file changed, 57 insertions(+), 37 deletions(-)

New commits:
commit b438854a0b5148880e455cbeeff14d4e3d825711
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sun Feb 20 21:11:19 2022 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Feb 21 09:37:49 2022 +0100

    gtk4: get getPreferredPlayerWindowSize working
    
    Change-Id: I5e5b02be6a902232c24120db513cdf3fc68b4421
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130224
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

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;
 }
 
commit f049c3884f7a376374ed6cffea6746ef35b00186
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sun Feb 20 20:58:17 2022 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Feb 21 09:37:35 2022 +0100

    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 <caol...@redhat.com>

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;
 }
 

Reply via email to