diff --git a/clapper_src/controls.js b/clapper_src/controls.js index b1486305..9445c56a 100644 --- a/clapper_src/controls.js +++ b/clapper_src/controls.js @@ -204,10 +204,8 @@ class ClapperControls extends Gtk.Box } if(checkButton.activeId < 0) { - /* Disabling video leaves last frame frozen, - * so we hide it by making it transparent */ - //if(checkButton.type === 'video') - // clapperWidget.player.widget.set_opacity(0); + if(checkButton.type === 'video') + clapperWidget.player.draw_black(true); return clapperWidget.player[ `set_${checkButton.type}_track_enabled` @@ -219,8 +217,8 @@ class ClapperControls extends Gtk.Box clapperWidget.player[setTrack](checkButton.activeId); clapperWidget.player[`${setTrack}_enabled`](true); - //if(checkButton.type === 'video' && !clapperWidget.player.widget.opacity) - // clapperWidget.player.widget.set_opacity(1); + if(checkButton.type === 'video') + clapperWidget.player.draw_black(false); } _handleVisualizationChange(checkButton) diff --git a/clapper_src/player.js b/clapper_src/player.js index 09426a08..2d12ee0a 100644 --- a/clapper_src/player.js +++ b/clapper_src/player.js @@ -14,7 +14,6 @@ class ClapperPlayer extends PlayerBase { super._init(); - this.state = GstPlayer.PlayerState.STOPPED; this.cursorInPlayer = false; this.is_local_file = false; this.seek_done = true; diff --git a/clapper_src/playerBase.js b/clapper_src/playerBase.js index ae4397ae..200a3bf5 100644 --- a/clapper_src/playerBase.js +++ b/clapper_src/playerBase.js @@ -39,6 +39,7 @@ class ClapperPlayerBase extends GstPlayer.Player + ' Do you have gstreamer-plugins-good-gtk4 installed?' )); } + gtkglsink.show_preroll_frame = false; let glsinkbin = Gst.ElementFactory.make('glsinkbin', null); glsinkbin.sink = gtkglsink; @@ -59,10 +60,11 @@ class ClapperPlayerBase extends GstPlayer.Player video_renderer: renderer }); - this.widget = gtkglsink.widget; + this.gtkglsink = gtkglsink; this.widget.vexpand = true; this.widget.hexpand = true; + this.state = GstPlayer.PlayerState.STOPPED; this.visualization_enabled = false; this.set_all_plugins_ranks(); @@ -72,6 +74,11 @@ class ClapperPlayerBase extends GstPlayer.Player settings.connect('changed', this._onSettingsKeyChanged.bind(this)); } + get widget() + { + return this.gtkglsink.widget; + } + set_and_bind_settings() { let settingsToSet = [ @@ -160,6 +167,14 @@ class ClapperPlayerBase extends GstPlayer.Player debug(`changed rank: ${oldRank} -> ${rank} for ${name}`); } + draw_black(isEnabled) + { + this.gtkglsink.ignore_textures = isEnabled; + + if(this.state !== GstPlayer.PlayerState.PLAYING) + this.widget.queue_render(); + } + _onSettingsKeyChanged(settings, key) { switch(key) { diff --git a/pkgs/flatpak/gstreamer-1.0/gst-plugins-good-gtk4glsink-render-black.patch b/pkgs/flatpak/gstreamer-1.0/gst-plugins-good-gtk4glsink-render-black.patch index 775bb71c..9df4356e 100644 --- a/pkgs/flatpak/gstreamer-1.0/gst-plugins-good-gtk4glsink-render-black.patch +++ b/pkgs/flatpak/gstreamer-1.0/gst-plugins-good-gtk4glsink-render-black.patch @@ -1,5 +1,399 @@ +From 55cd1534d09228f14bcea14848ef226b6d88edfd Mon Sep 17 00:00:00 2001 +From: Rafostar <40623528+Rafostar@users.noreply.github.com> +Date: Mon, 16 Nov 2020 13:32:50 +0100 +Subject: [PATCH 1/6] gtk(4): draw black before priv contexts are available + +--- + ext/gtk/gtkgstglwidget.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c -index 186144a1c..54563c36f 100644 +index 186144a1c..3d6fe05a2 100644 +--- a/ext/gtk/gtkgstglwidget.c ++++ b/ext/gtk/gtkgstglwidget.c +@@ -225,6 +225,14 @@ _draw_black (GstGLContext * context) + gl->Clear (GL_COLOR_BUFFER_BIT); + } + ++static inline void ++_draw_black_with_gdk (GdkGLContext * gdk_context) ++{ ++ GST_DEBUG ("rendering empty frame with gdk context %p", gdk_context); ++ glClearColor (0.0, 0.0, 0.0, 1.0); ++ glClear (GL_COLOR_BUFFER_BIT); ++} ++ + static gboolean + gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) + { +@@ -233,8 +241,13 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) + + GTK_GST_BASE_WIDGET_LOCK (widget); + +- if (!priv->context || !priv->other_context) ++ /* Draw black with GDK context when priv is not available yet. ++ GTK calls render with GDK context already active. */ ++ if (!priv->context || !priv->other_context) { ++ GdkGLContext *gdk_context = gtk_gl_area_get_context (widget); ++ _draw_black_with_gdk (gdk_context); + goto done; ++ } + + gst_gl_context_activate (priv->other_context, TRUE); + +-- +2.26.2 + + +From c477954dd41ff506b07fe89aa241769809efdeb8 Mon Sep 17 00:00:00 2001 +From: Rafostar <40623528+Rafostar@users.noreply.github.com> +Date: Mon, 16 Nov 2020 16:04:45 +0100 +Subject: [PATCH 2/6] gtk(4): draw black when not initiated + +--- + ext/gtk/gtkgstglwidget.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c +index 3d6fe05a2..d1422f8bb 100644 +--- a/ext/gtk/gtkgstglwidget.c ++++ b/ext/gtk/gtkgstglwidget.c +@@ -62,7 +62,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); + + struct _GtkGstGLWidgetPrivate + { +- gboolean initted; ++ gboolean initiated; + GstGLDisplay *display; + GdkGLContext *gdk_context; + GstGLContext *other_context; +@@ -159,7 +159,7 @@ gtk_gst_gl_widget_init_redisplay (GtkGstGLWidget * gst_widget) + priv->overlay_compositor = + gst_gl_overlay_compositor_new (priv->other_context); + +- priv->initted = TRUE; ++ priv->initiated = TRUE; + } + + static void +@@ -251,10 +251,10 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) + + gst_gl_context_activate (priv->other_context, TRUE); + +- if (!priv->initted) +- gtk_gst_gl_widget_init_redisplay (GTK_GST_GL_WIDGET (widget)); ++ if (!priv->initiated || !base_widget->negotiated) { ++ if (!priv->initiated) ++ gtk_gst_gl_widget_init_redisplay (GTK_GST_GL_WIDGET (widget)); + +- if (!priv->initted || !base_widget->negotiated) { + _draw_black (priv->other_context); + goto done; + } +-- +2.26.2 + + +From eb407306f30e13e7a6ada116e8b4b5812da67b72 Mon Sep 17 00:00:00 2001 +From: Rafostar <40623528+Rafostar@users.noreply.github.com> +Date: Mon, 16 Nov 2020 22:13:46 +0100 +Subject: [PATCH 3/6] gtk(4): add ignore textures property for glsink + +--- + ext/gtk/gstgtkbasesink.c | 18 ++++++++++++++++++ + ext/gtk/gstgtkbasesink.h | 10 +++++++--- + ext/gtk/gtkgstbasewidget.c | 14 ++++++++++++++ + ext/gtk/gtkgstbasewidget.h | 1 + + ext/gtk/gtkgstglwidget.c | 3 ++- + 5 files changed, 42 insertions(+), 4 deletions(-) + +diff --git a/ext/gtk/gstgtkbasesink.c b/ext/gtk/gstgtkbasesink.c +index ea11bec40..666bbef54 100644 +--- a/ext/gtk/gstgtkbasesink.c ++++ b/ext/gtk/gstgtkbasesink.c +@@ -39,6 +39,7 @@ GST_DEBUG_CATEGORY (gst_debug_gtk_base_sink); + #define DEFAULT_PAR_N 0 + #define DEFAULT_PAR_D 1 + #define DEFAULT_IGNORE_ALPHA TRUE ++#define DEFAULT_IGNORE_TEXTURES FALSE + + static void gst_gtk_base_sink_finalize (GObject * object); + static void gst_gtk_base_sink_set_property (GObject * object, guint prop_id, +@@ -70,6 +71,7 @@ enum + PROP_FORCE_ASPECT_RATIO, + PROP_PIXEL_ASPECT_RATIO, + PROP_IGNORE_ALPHA, ++ PROP_IGNORE_TEXTURES, + }; + + #define gst_gtk_base_sink_parent_class parent_class +@@ -123,6 +125,11 @@ gst_gtk_base_sink_class_init (GstGtkBaseSinkClass * klass) + DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + #endif + ++ g_object_class_install_property (gobject_class, PROP_IGNORE_TEXTURES, ++ g_param_spec_boolean ("ignore-textures", "Ignore Textures", ++ "When enabled, textures will be ignored and not drawn", ++ DEFAULT_IGNORE_TEXTURES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); ++ + gobject_class->finalize = gst_gtk_base_sink_finalize; + + gstelement_class->change_state = gst_gtk_base_sink_change_state; +@@ -143,6 +150,7 @@ gst_gtk_base_sink_init (GstGtkBaseSink * gtk_sink) + gtk_sink->par_n = DEFAULT_PAR_N; + gtk_sink->par_d = DEFAULT_PAR_D; + gtk_sink->ignore_alpha = DEFAULT_IGNORE_ALPHA; ++ gtk_sink->ignore_textures = DEFAULT_IGNORE_TEXTURES; + } + + static void +@@ -202,6 +210,10 @@ gst_gtk_base_sink_get_widget (GstGtkBaseSink * gtk_sink) + "ignore-alpha", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + #endif + ++ gtk_sink->bind_ignore_textures = ++ g_object_bind_property (gtk_sink, "ignore-textures", gtk_sink->widget, ++ "ignore-textures", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); ++ + /* back pointer */ + gtk_gst_base_widget_set_element (GTK_GST_BASE_WIDGET (gtk_sink->widget), + GST_ELEMENT (gtk_sink)); +@@ -242,6 +254,9 @@ gst_gtk_base_sink_get_property (GObject * object, guint prop_id, + case PROP_IGNORE_ALPHA: + g_value_set_boolean (value, gtk_sink->ignore_alpha); + break; ++ case PROP_IGNORE_TEXTURES: ++ g_value_set_boolean (value, gtk_sink->ignore_textures); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -265,6 +280,9 @@ gst_gtk_base_sink_set_property (GObject * object, guint prop_id, + case PROP_IGNORE_ALPHA: + gtk_sink->ignore_alpha = g_value_get_boolean (value); + break; ++ case PROP_IGNORE_TEXTURES: ++ gtk_sink->ignore_textures = g_value_get_boolean (value); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +diff --git a/ext/gtk/gstgtkbasesink.h b/ext/gtk/gstgtkbasesink.h +index f2668fabc..a13729f7b 100644 +--- a/ext/gtk/gstgtkbasesink.h ++++ b/ext/gtk/gstgtkbasesink.h +@@ -1,6 +1,7 @@ + /* + * GStreamer + * Copyright (C) 2015 Matthew Waters ++ * Copyright (C) 2020 Rafał Dzięgiel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public +@@ -61,13 +62,16 @@ struct _GstGtkBaseSink + gboolean force_aspect_ratio; + GBinding *bind_aspect_ratio; + +- gint par_n; +- gint par_d; ++ gint par_n; ++ gint par_d; + GBinding *bind_pixel_aspect_ratio; + +- gboolean ignore_alpha; ++ gboolean ignore_alpha; + GBinding *bind_ignore_alpha; + ++ gboolean ignore_textures; ++ GBinding *bind_ignore_textures; ++ + GtkWidget *window; + gulong window_destroy_id; + }; +diff --git a/ext/gtk/gtkgstbasewidget.c b/ext/gtk/gtkgstbasewidget.c +index 5335478cb..91fc1105f 100644 +--- a/ext/gtk/gtkgstbasewidget.c ++++ b/ext/gtk/gtkgstbasewidget.c +@@ -34,6 +34,7 @@ GST_DEBUG_CATEGORY (gst_debug_gtk_base_widget); + #define DEFAULT_PAR_N 0 + #define DEFAULT_PAR_D 1 + #define DEFAULT_IGNORE_ALPHA TRUE ++#define DEFAULT_IGNORE_TEXTURES FALSE + + enum + { +@@ -41,6 +42,7 @@ enum + PROP_FORCE_ASPECT_RATIO, + PROP_PIXEL_ASPECT_RATIO, + PROP_IGNORE_ALPHA, ++ PROP_IGNORE_TEXTURES, + }; + + static void +@@ -108,6 +110,9 @@ gtk_gst_base_widget_set_property (GObject * object, guint prop_id, + case PROP_IGNORE_ALPHA: + gtk_widget->ignore_alpha = g_value_get_boolean (value); + break; ++ case PROP_IGNORE_TEXTURES: ++ gtk_widget->ignore_textures = g_value_get_boolean (value); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -130,6 +135,9 @@ gtk_gst_base_widget_get_property (GObject * object, guint prop_id, + case PROP_IGNORE_ALPHA: + g_value_set_boolean (value, gtk_widget->ignore_alpha); + break; ++ case PROP_IGNORE_TEXTURES: ++ g_value_set_boolean (value, gtk_widget->ignore_textures); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -468,6 +476,11 @@ gtk_gst_base_widget_class_init (GtkGstBaseWidgetClass * klass) + "When enabled, alpha will be ignored and converted to black", + DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + ++ g_object_class_install_property (gobject_klass, PROP_IGNORE_TEXTURES, ++ g_param_spec_boolean ("ignore-textures", "Ignore Textures", ++ "When enabled, textures will be ignored and not drawn", ++ DEFAULT_IGNORE_TEXTURES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); ++ + #if defined(BUILD_FOR_GTK4) + widget_klass->measure = gtk_gst_base_widget_measure; + #else +@@ -494,6 +507,7 @@ gtk_gst_base_widget_init (GtkGstBaseWidget * widget) + widget->par_n = DEFAULT_PAR_N; + widget->par_d = DEFAULT_PAR_D; + widget->ignore_alpha = DEFAULT_IGNORE_ALPHA; ++ widget->ignore_textures = DEFAULT_IGNORE_TEXTURES; + + gst_video_info_init (&widget->v_info); + gst_video_info_init (&widget->pending_v_info); +diff --git a/ext/gtk/gtkgstbasewidget.h b/ext/gtk/gtkgstbasewidget.h +index 640a1c742..651999a55 100644 +--- a/ext/gtk/gtkgstbasewidget.h ++++ b/ext/gtk/gtkgstbasewidget.h +@@ -57,6 +57,7 @@ struct _GtkGstBaseWidget + gint display_width; + gint display_height; + ++ gboolean ignore_textures; + gboolean negotiated; + GstBuffer *pending_buffer; + GstBuffer *buffer; +diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c +index d1422f8bb..1553a5255 100644 +--- a/ext/gtk/gtkgstglwidget.c ++++ b/ext/gtk/gtkgstglwidget.c +@@ -243,8 +243,9 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) + + /* Draw black with GDK context when priv is not available yet. + GTK calls render with GDK context already active. */ +- if (!priv->context || !priv->other_context) { ++ if (!priv->context || !priv->other_context || base_widget->ignore_textures) { + GdkGLContext *gdk_context = gtk_gl_area_get_context (widget); ++ + _draw_black_with_gdk (gdk_context); + goto done; + } +-- +2.26.2 + + +From ec8a37b4d7723af564d4e790ff38279c1e2ea531 Mon Sep 17 00:00:00 2001 +From: Rafostar <40623528+Rafostar@users.noreply.github.com> +Date: Tue, 17 Nov 2020 11:42:45 +0100 +Subject: [PATCH 4/6] gtk(4): do not reconnect signal handlers when already + connected + +--- + ext/gtk/gstgtkglsink.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/ext/gtk/gstgtkglsink.c b/ext/gtk/gstgtkglsink.c +index 3b0059906..2c92f8574 100644 +--- a/ext/gtk/gstgtkglsink.c ++++ b/ext/gtk/gstgtkglsink.c +@@ -186,15 +186,19 @@ gst_gtk_gl_sink_start (GstBaseSink * bsink) + gst_widget = GTK_GST_GL_WIDGET (base_sink->widget); + + #if !defined(BUILD_FOR_GTK4) +- /* Track the allocation size */ +- gtk_sink->size_allocate_sig_handler = +- g_signal_connect (gst_widget, "size-allocate", +- G_CALLBACK (_size_changed_cb), gtk_sink); ++ if (!gtk_sink->size_allocate_sig_handler) { ++ /* Track the allocation size */ ++ gtk_sink->size_allocate_sig_handler = ++ g_signal_connect (gst_widget, "size-allocate", ++ G_CALLBACK (_size_changed_cb), gtk_sink); ++ } + #endif + +- gtk_sink->widget_destroy_sig_handler = +- g_signal_connect (gst_widget, "destroy", G_CALLBACK (destroy_cb), +- gtk_sink); ++ if (!gtk_sink->widget_destroy_sig_handler) { ++ gtk_sink->widget_destroy_sig_handler = ++ g_signal_connect (gst_widget, "destroy", G_CALLBACK (destroy_cb), ++ gtk_sink); ++ } + + if (!gtk_gst_gl_widget_init_winsys (gst_widget)) { + GST_ELEMENT_ERROR (bsink, RESOURCE, NOT_FOUND, ("%s", +-- +2.26.2 + + +From fe243f7bff2b223fcbeaf2171f47bc4fce0aff78 Mon Sep 17 00:00:00 2001 +From: Rafostar <40623528+Rafostar@users.noreply.github.com> +Date: Tue, 17 Nov 2020 11:44:06 +0100 +Subject: [PATCH 5/6] gtk(4): use context passed to render vfunc for debug log + +--- + ext/gtk/gtkgstglwidget.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c +index 1553a5255..09d709091 100644 +--- a/ext/gtk/gtkgstglwidget.c ++++ b/ext/gtk/gtkgstglwidget.c +@@ -220,7 +220,7 @@ _draw_black (GstGLContext * context) + { + const GstGLFuncs *gl = context->gl_vtable; + +- gst_gl_insert_debug_marker (context, "no buffer. rendering black"); ++ gst_gl_insert_debug_marker (context, "rendering black"); + gl->ClearColor (0.0, 0.0, 0.0, 0.0); + gl->Clear (GL_COLOR_BUFFER_BIT); + } +@@ -244,9 +244,8 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) + /* Draw black with GDK context when priv is not available yet. + GTK calls render with GDK context already active. */ + if (!priv->context || !priv->other_context || base_widget->ignore_textures) { +- GdkGLContext *gdk_context = gtk_gl_area_get_context (widget); ++ _draw_black_with_gdk (context); + +- _draw_black_with_gdk (gdk_context); + goto done; + } + +-- +2.26.2 + + +From 78945426ee3976dc75d6761fd67b756af33c0302 Mon Sep 17 00:00:00 2001 +From: Rafostar <40623528+Rafostar@users.noreply.github.com> +Date: Tue, 17 Nov 2020 13:16:38 +0100 +Subject: [PATCH 6/6] gtk(4): always clear color to black + +--- + ext/gtk/gtkgstglwidget.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c +index 09d709091..638c80588 100644 --- a/ext/gtk/gtkgstglwidget.c +++ b/ext/gtk/gtkgstglwidget.c @@ -173,7 +173,7 @@ _redraw_texture (GtkGstGLWidget * gst_widget, guint tex) @@ -14,9 +408,12 @@ index 186144a1c..54563c36f 100644 @@ -221,7 +221,7 @@ _draw_black (GstGLContext * context) const GstGLFuncs *gl = context->gl_vtable; - gst_gl_insert_debug_marker (context, "no buffer. rendering black"); + gst_gl_insert_debug_marker (context, "rendering black"); - gl->ClearColor (0.0, 0.0, 0.0, 0.0); + gl->ClearColor (0.0, 0.0, 0.0, 1.0); gl->Clear (GL_COLOR_BUFFER_BIT); } +-- +2.26.2 + diff --git a/pkgs/flatpak/gstreamer-1.0/gst-plugins-good.json b/pkgs/flatpak/gstreamer-1.0/gst-plugins-good.json index ee2d53c9..672f8f8f 100644 --- a/pkgs/flatpak/gstreamer-1.0/gst-plugins-good.json +++ b/pkgs/flatpak/gstreamer-1.0/gst-plugins-good.json @@ -27,11 +27,11 @@ }, { "type": "patch", - "path": "gst-plugins-good-gtk4glsink-render-black.patch" + "path": "gst-plugins-good-gtk4-do-not-depend-on-destroy-signal-for-cleanup.patch" }, { "type": "patch", - "path": "gst-plugins-good-gtk4-do-not-depend-on-destroy-signal-for-cleanup.patch" + "path": "gst-plugins-good-gtk4glsink-render-black.patch" } ] }