Package: release.debian.org
Severity: normal
X-Debbugs-Cc: to...@packages.debian.org
Control: affects -1 + src:totem
User: release.debian....@packages.debian.org
Usertags: unblock

[ Reason ]
New upstream bugfix release, in particular fixing #986432

[ Impact ]
If not accepted, various bugs would be unfixed, notably:
- #986432 which makes totem unusable on 32-bit;
- totem#614 which can leak a lot of disk space in
  ~/.cache/totem/stream-buffer if I'm reading correctly

If the release team is unhappy with the size of this upstream bugfix 
release, then I think we should cherry-pick the fixes for at least those 
two bugs instead. But following upstream and getting the benefit of 
other distros' testing seems safer than doing our own thing.

[ Tests ]
Manually tested by watching some videos with and without 
TOTEM_USE_GST_GTKSINK=1 environment variable.

I tried streaming some videos over smb:// and http, but was unable to 
reproduce large temporary files appearing in 
~/.cache/totem/stream-buffer, so I cannot confirm that totem#614 is 
fixed.

Other distros are also shipping this version, e.g. it has been in Fedora 
41 and 42 for 20 days.

[ Risks ]
Key package, installed by our default desktop environment.

Adding support for falling back to gtksink is a larger change than I 
would normally expect in a stable-branch update, but it could be the 
difference between totem being usable or unusable on weaker hardware, 
and the code is not too complicated.

Similarly using GStreamer's convert-sample instead of open-coding it is 
a larger change than I would have expected, but it's a code deletion 
rather than addition, and I trust GStreamer to get this right more than 
I trust Totem.

We can revert any of these changes if they prove to be a problem.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing
      - debdiff is testing vs. experimental, what I'm proposing to
        upload to unstable is this plus a changelog entry.
        I filtered out translation updates, upstream CI changes,
        and the content of the patches that were dropped.
debdiff *.dsc | filterdiff -p1 -x.gitlab-ci.yml -x'debian/patches/*.patch' -x'po/*.po'

 NEWS                                              |   16 +
 data/appdata/org.gnome.Totem.appdata.xml.in.in    |   22 +
 data/mime-functions.sh                            |    2 
 debian/changelog                                  |   62 ++++
 debian/control                                    |    3 
 debian/patches/series                             |    9 
 meson.build                                       |   23 -
 po/LINGUAS                                        |    1 
 src/backend/bacon-video-widget.c                  |  134 ++++++++--
 src/backend/bacon-video-widget.h                  |    2 
 src/backend/meson.build                           |    4 
 src/gst/totem-gst-pixbuf-helpers.c                |  289 ----------------------
 src/icon-helpers.c                                |    2 
 src/plugins/open-directory/totem-open-directory.c |    8 
 src/plugins/pythonconsole/console.py              |    3 
 src/plugins/recent/totem-recent.c                 |    2 
 src/plugins/rotation/totem-rotation.c             |    7 
 src/plugins/save-file/totem-save-file.c           |    2 
 src/plugins/screenshot/totem-screenshot-plugin.c  |   47 ---
 src/totem-object.c                                |    9 
 src/totem-playlist.c                              |    2 
 src/totem-resources.c                             |   10 
 src/totem-resources.h                             |    3 
 src/totem-video-thumbnailer.c                     |   15 -
 src/totem.c                                       |    2 
 25 files changed, 277 insertions(+), 402 deletions(-)

diff -Nru totem-43.1/data/appdata/org.gnome.Totem.appdata.xml.in.in totem-43.2/data/appdata/org.gnome.Totem.appdata.xml.in.in
--- totem-43.1/data/appdata/org.gnome.Totem.appdata.xml.in.in	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/data/appdata/org.gnome.Totem.appdata.xml.in.in	2025-05-21 14:08:29.000000000 +0100
@@ -20,17 +20,18 @@
       and support for recording DVDs.
     </p>
   </description>
-  <url type="homepage">https://wiki.gnome.org/Apps/Videos</url>
+  <url type="homepage">https://apps.gnome.org/Totem/</url>
   <url type="bugtracker">https://gitlab.gnome.org/GNOME/totem/issues</url>
-  <url type="donation">https://www.gnome.org/friends/</url>
+  <url type="donation">https://www.gnome.org/donate/</url>
   <url type="translate">https://l10n.gnome.org/module/totem/</url>
   <url type="help">https://help.gnome.org/users/totem/stable/</url>
+  <url type="vcs-browser">https://gitlab.gnome.org/GNOME/totem</url>
   <screenshots>
     <screenshot type="default">
-      <image>https://gitlab.gnome.org/GNOME/totem/raw/HEAD/data/appdata/ss-player.png</image>
+      <image>https://gitlab.gnome.org/GNOME/totem/raw/gnome-43/data/appdata/ss-player.png</image>
     </screenshot>
     <screenshot>
-      <image>https://gitlab.gnome.org/GNOME/totem/raw/HEAD/data/appdata/ss-videos.png</image>
+      <image>https://gitlab.gnome.org/GNOME/totem/raw/gnome-43/data/appdata/ss-videos.png</image>
     </screenshot>
   </screenshots>
   <update_contact>had...@hadess.net</update_contact>
@@ -39,6 +40,15 @@
   <translation type="gettext">totem</translation>
   <launchable type="desktop-id">@APPLICATION_ID@.desktop</launchable>
   <releases>
+    <release version="43.2" date="2025-05-21">
+      <description>
+        <p>
+          This new 43.2 version includes the use of gtksink as a video output
+          when native OpenGL support is not available, as well as many thumbnailer
+          related bug fixes, and translation updates.
+        </p>
+      </description>
+    </release>
     <release version="43.1" date="2024-10-22">
       <description>
         <p>
@@ -113,4 +123,8 @@
     <kudo>UserDocs</kudo>
   </kudos>
   <content_rating type="oars-1.1" />
+  <branding>
+    <color type="primary" scheme_preference="light">#f8e45c</color>
+    <color type="primary" scheme_preference="dark">#613583</color>
+  </branding>
 </component>
diff -Nru totem-43.1/data/mime-functions.sh totem-43.2/data/mime-functions.sh
--- totem-43.1/data/mime-functions.sh	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/data/mime-functions.sh	2025-05-21 14:08:29.000000000 +0100
@@ -8,7 +8,7 @@
 
 get_video_mimetypes ()
 {
-	MIMETYPES=`grep -v '^#' $1 | grep -v x-content/ | grep -v audio | grep -v "application/x-flac" | grep -v "text/google-video-pointer" | grep -v "application/x-quicktime-media-link" | grep -v "application/smil" | grep -v "application/smil+xml" | grep -v "application/x-smil" | grep -v "application/xspf+xml" | grep -v -E 'application/[a-z-]*ogg'`
+	MIMETYPES=`grep -v '^#' $1 | grep -v x-content/ | grep -v audio | grep -v "application/x-flac" | grep -v "text/google-video-pointer" | grep -v "application/x-quicktime-media-link" | grep -v -E 'application/.*smil.*' | grep -v "application/xspf+xml" | grep -v "mpegurl" | grep -v -E 'application/[a-z-]*ogg'`
 	MIMETYPES="$MIMETYPES audio/x-pn-realaudio"
 }
 
diff -Nru totem-43.1/debian/changelog totem-43.2/debian/changelog
--- totem-43.1/debian/changelog	2025-05-05 20:28:32.000000000 +0100
+++ totem-43.2/debian/changelog	2025-06-11 11:01:40.000000000 +0100
@@ -1,3 +1,65 @@
+totem (43.2-2) experimental; urgency=medium
+
+  * Team upload
+  * Summarize upstream changes in previous changelog entry
+  * d/control: Increase libportal build-dependency to 0.7, now required
+    upstream due to totem!390.
+    This version is already present in trixie, but not in bookworm.
+  * d/control: Explicitly build-depend on libepoxy-dev, required by the
+    GL check in totem!379
+
+ -- Simon McVittie <s...@debian.org>  Wed, 11 Jun 2025 11:01:40 +0100
+
+totem (43.2-1) experimental; urgency=medium
+
+  * New upstream release
+    - Fix a crash on startup on 32-bit architectures
+      (Closes: #986432, totem!393 upstream)
+    - Fix memory leaks, one of which could have the side-effect of leaking
+      large amounts of disk space in ~/.cache/totem/stream-buffer
+      (totem#614, totem!409 upstream)
+    - Make the main video widget take keyboard focus when playback starts,
+      so that keyboard shortcuts like spacebar to pause work as expected
+      (totem!420 upstream)
+    - Don't crash the whole application if libportal fails to initialize:
+      use xdp_portal_initable_new() instead, which has error reporting
+      (totem!390 upstream)
+    - Match the window to the application ID so that Wayland compositors
+      will show the correct icon
+      (totem!391 upstream)
+    - Automatically fall back to plain GTK video sink if environment
+      variable TOTEM_USE_GST_GTKSINK=1 is set, if the GL driver is too old
+      to work, or if the GL driver name indicates software rendering
+      (totem!379 upstream)
+    - Use GStreamer playbin's convert-sample feature instead of
+      reimplementing equivalent functionality locally
+      (totem!261 upstream)
+    - Exclude m3u playlists from thumbnailing: they are not a video format,
+      and loading them from a sandbox with no network access will usually
+      fail anyway
+      (totem#626 upstream)
+    - Avoid a duplicate MIME-type registration for application/x-smil, etc.
+      (totem#635 upstream)
+    - Allow one thumbnailing process per CPU
+      (totem!399 upstream)
+    - Fix a deprecation warning in the pythonconsole plugin
+      (totem!400 upstream)
+    - Stop using a private gnome-shell API to show a "camera flash" effect
+      when taking screenshots: unprivileged apps are no longer allowed to
+      call into this API, so it had no practical effect
+      (totem!371 upstream)
+    - AppStream metadata improvements
+      + update URLs
+      + pin screenshots to the gnome-43 branch so they will not become
+        misleading if the UI changes in the main branch
+      + add branding colours
+    - Fix build system warnings
+    - Translation updates
+  * Remove all patches except d/p/Mark-lint-checks-as-part-of-a-suite.patch,
+    applied in new release
+
+ -- Jeremy BĂ­cha <jbi...@ubuntu.com>  Fri, 06 Jun 2025 13:20:12 -0400
+
 totem (43.1-6) unstable; urgency=medium
 
   * Team upload
diff -Nru totem-43.1/debian/control totem-43.2/debian/control
--- totem-43.1/debian/control	2025-05-05 20:28:32.000000000 +0100
+++ totem-43.2/debian/control	2025-06-11 11:01:40.000000000 +0100
@@ -19,6 +19,7 @@
                libatk1.0-dev,
                libbluetooth-dev [linux-any],
                libcairo2-dev,
+               libepoxy-dev,
                libgdk-pixbuf-2.0-dev,
                libgirepository1.0-dev,
                libglib2.0-dev (>= 2.72.0),
@@ -29,7 +30,7 @@
                libgtk-3-dev,
                libhandy-1-dev (>= 1.5.90),
                libpeas-dev,
-               libportal-gtk3-dev,
+               libportal-gtk3-dev (>= 0.7),
                librsvg2-dev,
                libtotem-plparser-dev,
                libx11-dev (>= 2:1.8),
diff -Nru totem-43.1/debian/patches/series totem-43.2/debian/patches/series
--- totem-43.1/debian/patches/series	2025-05-05 20:28:32.000000000 +0100
+++ totem-43.2/debian/patches/series	2025-06-11 11:01:40.000000000 +0100
@@ -1,10 +1 @@
 Mark-lint-checks-as-part-of-a-suite.patch
-plugins-remove-apple-trailers-plugin.patch
-plugins-Remove-vimeo-plug-in.patch
-Update-POTFILES.in.patch
-Update-POTFILES.in-1.patch
-data-Add-new-canonical-mime-type-for-AVI-files.patch
-Fix-totem-thumbnailer-fail-due-to-OpenBLAS-pthread-e.patch
-thumbnailer-Bump-memory-usage-limit.patch
-use-appstreamcli.patch
-Fix-Thumbnailer-Gstreamer-threading.patch
diff -Nru totem-43.1/meson.build totem-43.2/meson.build
--- totem-43.1/meson.build	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/meson.build	2025-05-21 14:08:29.000000000 +0100
@@ -1,6 +1,6 @@
 project(
   'totem', 'c',
-  version: '43.1',
+  version: '43.2',
   license: 'GPL2+ with exception',
   default_options: 'buildtype=debugoptimized',
   meson_version: '>= 0.57.0'
@@ -126,17 +126,18 @@
 glib_req_version = '>= 2.72.0'
 gtk_req_version = '>= 3.22.0'
 hdy_req_version = '>= 1.5.0'
-gst_req_version = '>= 1.6.0'
+gst_req_version = '>= 1.21.1'
 grilo_req_version = '>= 0.3.0'
 peas_req_version = '>= 1.1.0'
 totem_plparser_req_version = '>= 3.26.5'
+libportal_req_version = '>= 0.7'
 
 glib_dep =  dependency('glib-2.0', version: glib_req_version)
 gobject_dep =  dependency('gobject-2.0', version: glib_req_version)
 gmodule_dep = dependency('gmodule-2.0', version: glib_req_version)
 gio_dep = dependency('gio-2.0', version: '>= 2.43.4')
 gtk_dep = dependency('gtk+-3.0', version: gtk_req_version)
-targets = gtk_dep.get_pkgconfig_variable('targets')
+targets = gtk_dep.get_variable(pkgconfig : 'targets')
 if targets.split(' ').contains('x11')
   x11_dep = dependency('x11', version: '>= 1.8')
 else
@@ -144,9 +145,9 @@
 endif
 hdy_dep = dependency('libhandy-1', version: hdy_req_version)
 gst_dep = dependency('gstreamer-1.0', version: gst_req_version)
-gst_tag_dep = dependency('gstreamer-tag-1.0', version: '>= 0.11.93')
-gst_video_dep = dependency('gstreamer-video-1.0')
-gst_pbutils_dep = dependency('gstreamer-pbutils-1.0')
+gst_tag_dep = dependency('gstreamer-tag-1.0', version: gst_req_version)
+gst_video_dep = dependency('gstreamer-video-1.0', version: gst_req_version)
+gst_pbutils_dep = dependency('gstreamer-pbutils-1.0', version: gst_req_version)
 peas_dep = dependency('libpeas-1.0', version: peas_req_version)
 peas_gtk_dep = dependency('libpeas-gtk-1.0', version: peas_req_version)
 totem_plparser_dep = dependency('totem-plparser', version: totem_plparser_req_version)
@@ -208,7 +209,7 @@
 endif
 
 # libportal support
-libportal_dep = dependency('libportal-gtk3', required: get_option('libportal'))
+libportal_dep = dependency('libportal-gtk3', version: libportal_req_version, required: get_option('libportal'))
 have_libportal = libportal_dep.found()
 
 configure_file(
@@ -220,7 +221,7 @@
 i18n = import('i18n')
 pkg = import('pkgconfig')
 
-po_dir = join_paths(meson.source_root(), 'po')
+po_dir = join_paths(meson.project_source_root(), 'po')
 
 top_inc = include_directories('.')
 
@@ -245,21 +246,21 @@
   totem_minor_version != 'rc')
 if is_stable
   meson.add_dist_script(
-    find_program('check-news.sh').path(),
+    find_program('check-news.sh').full_path(),
     '@0@'.format(meson.project_version()),
     'NEWS',
     'data/appdata/org.gnome.Totem.appdata.xml.in.in'
   )
 else
   meson.add_dist_script(
-    find_program('check-news.sh').path(),
+    find_program('check-news.sh').full_path(),
     '@0@'.format(meson.project_version()),
     'NEWS',
   )
 endif
 
 meson.add_dist_script(
-  find_program('remove-flatpak-dist.sh').path()
+  find_program('remove-flatpak-dist.sh').full_path()
 )
 
 message('Totem was configured with the following options:')
diff -Nru totem-43.1/NEWS totem-43.2/NEWS
--- totem-43.1/NEWS	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/NEWS	2025-05-21 14:08:29.000000000 +0100
@@ -1,5 +1,21 @@
 New features and significant updates in version...
 
+Major changes in 43.2:
+- Implement a gtksink video output fallback if native OpenGL support is
+  not available.
+- Fix a lot of thumbnailing failures caused by memory hungry video decoders
+- Hide the rotate menu items if rotation is not supported
+- Fix some AVI files not being associated correctly
+- Fix widget focus when starting video playback
+- Fix left-over files when streaming a video and the player is closed
+- Fix window not being matched to the application under Wayland
+- Stop using gnome-shell to flash the screenshot area, that stopped
+  working a long time ago
+- Stop thumbnailing m3u playlists
+- Remove obsolete plugins (apple-trailers, vimeo)
+- Fix a number of possible crashers
+- Translation updates
+
 Major changes in 43.1:
 - Fix scroll-by-page GTK setting breaking slider
 - Fix a number of MPRIS playback controls not working correctly
diff -Nru totem-43.1/po/LINGUAS totem-43.2/po/LINGUAS
--- totem-43.1/po/LINGUAS	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/po/LINGUAS	2025-05-21 14:08:29.000000000 +0100
@@ -90,6 +90,7 @@
 tr
 ug
 uk
+uz
 vi
 wa
 xh
diff -Nru totem-43.1/src/backend/bacon-video-widget.c totem-43.2/src/backend/bacon-video-widget.c
--- totem-43.1/src/backend/bacon-video-widget.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/backend/bacon-video-widget.c	2025-05-21 14:08:29.000000000 +0100
@@ -63,6 +63,9 @@
 /* for the cover metadata info */
 #include <gst/tag/tag.h>
 
+/* for detecting GL vendor/renderer */
+#include <epoxy/gl.h>
+
 /* system */
 #include <unistd.h>
 #include <time.h>
@@ -192,6 +195,7 @@
   gint64                       current_time;
   gdouble                      current_position;
   gboolean                     is_live;
+  gboolean                     use_gl;
 
   GstTagList                  *tagcache;
   GstTagList                  *audiotags;
@@ -282,6 +286,7 @@
 
 static void bacon_video_widget_finalize (GObject * object);
 
+static void bvw_init_video_sink (BaconVideoWidget *bvw);
 static void bvw_reconfigure_fill_timeout (BaconVideoWidget *bvw, guint msecs);
 static void bvw_stop_play_pipeline (BaconVideoWidget * bvw);
 static GError* bvw_error_from_gst_error (BaconVideoWidget *bvw, GstMessage *m);
@@ -433,6 +438,8 @@
 
   GTK_WIDGET_CLASS (parent_class)->realize (widget);
 
+  bvw_init_video_sink (bvw);
+
   window = gtk_widget_get_window (widget);
   display = gdk_window_get_display (window);
   bvw->hand_cursor = gdk_cursor_new_for_display (display, GDK_HAND2);
@@ -3882,9 +3889,12 @@
   bvw->buffering_left = -1;
   bvw_reconfigure_fill_timeout (bvw, 0);
   g_signal_emit (bvw, bvw_signals[SIGNAL_BUFFERING], 0, 100.0);
-  g_object_set (bvw->video_sink,
-                "rotate-method", GST_VIDEO_ORIENTATION_AUTO,
-                NULL);
+
+  if (bvw->use_gl)
+    g_object_set (bvw->video_sink,
+                  "rotate-method", GST_VIDEO_ORIENTATION_AUTO,
+                  NULL);
+
   GST_DEBUG ("stopped");
 }
 
@@ -4493,6 +4503,9 @@
 {
   g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
 
+  if (!bvw->use_gl)
+    return;
+
   GST_DEBUG ("Rotating to %s (%f degrees) from %s",
 	     g_enum_to_string (BVW_TYPE_ROTATION, rotation),
 	     rotation * 90.0,
@@ -4518,6 +4531,22 @@
   return bvw->rotation;
 }
 
+/**
+ * bacon_video_widget_use_gl:
+ * @bvw: a #BaconVideoWidget
+ *
+ * Returns whether gl is used.
+ *
+ * Return value: %TRUE if gl is used, %FALSE otherwise
+ **/
+gboolean
+bacon_video_widget_use_gl (BaconVideoWidget *bvw)
+{
+  g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), FALSE);
+
+  return bvw->use_gl;
+}
+
 /* Search for the color balance channel corresponding to type and return it. */
 static GstColorBalanceChannel *
 bvw_get_color_balance_channel (GstColorBalance * color_balance,
@@ -5492,12 +5521,7 @@
 static void
 bacon_video_widget_init (BaconVideoWidget *bvw)
 {
-  GstElement *audio_sink = NULL;
   gchar *version_str;
-  GstPlayFlags flags;
-  GstElement *glsinkbin, *audio_bin;
-  GstPad *audio_pad;
-  char *template;
 
   gtk_widget_set_can_focus (GTK_WIDGET (bvw), TRUE);
 
@@ -5538,19 +5562,84 @@
 			 GDK_BUTTON_RELEASE_MASK |
 			 GDK_KEY_PRESS_MASK);
   gtk_widget_init_template (GTK_WIDGET (bvw));
+}
+
+static inline gboolean
+bvw_gl_check (GtkWidget *widget)
+{
+  static gsize gl_works = 0;
+
+  if (is_feature_enabled ("TOTEM_USE_GST_GTKSINK")) {
+    return FALSE;
+  }
+
+  if (g_once_init_enter (&gl_works)) {
+    GError *error = NULL;
+    gsize works = 1;
+    GdkGLContext *context;
+    GdkWindow *window;
+
+    if ((window = gtk_widget_get_window (widget)) &&
+        (context = gdk_window_create_gl_context (window, &error))) {
+      const gchar *vendor, *renderer;
+
+      gdk_gl_context_make_current (context);
+
+      vendor = (const gchar *) glGetString (GL_VENDOR);
+      renderer = (const gchar *) glGetString (GL_RENDERER);
+
+      GST_INFO ("GL Vendor: %s, renderer: %s", vendor, renderer);
+
+      if (g_str_has_prefix (renderer, "llvmpipe") ||
+          g_str_has_prefix (renderer, "softpipe"))
+        GST_INFO ("Detected software GL rasterizer, falling back to gtksink");
+      else
+        works = 2;
+
+      gdk_gl_context_clear_current ();
+    }
+
+    if (error) {
+      GST_WARNING ("Could not window to create GL context, %s", error->message);
+      g_error_free (error);
+    }
+
+    g_once_init_leave (&gl_works, works);
+  }
+
+  return (gl_works > 1);
+}
+
+static void
+bvw_init_video_sink (BaconVideoWidget *bvw)
+{
+  GstElement *audio_sink = NULL;
+  GstPlayFlags flags;
+  GstElement *glsinkbin = NULL;
+  GstElement *audio_bin;
+  GstPad *audio_pad;
+  char *template;
+
+  bvw->use_gl = bvw_gl_check (GTK_WIDGET (bvw));
 
   /* Instantiate all the fallible plugins */
   bvw->play = element_make_or_warn ("playbin", "play");
   bvw->audio_pitchcontrol = element_make_or_warn ("scaletempo", "scaletempo");
-  bvw->video_sink = element_make_or_warn ("gtkglsink", "video-sink");
-  glsinkbin = element_make_or_warn ("glsinkbin", "glsinkbin");
+
+  if (bvw->use_gl) {
+    bvw->video_sink = element_make_or_warn ("gtkglsink", "video-sink");
+    glsinkbin = element_make_or_warn ("glsinkbin", "glsinkbin");
+  } else {
+    bvw->video_sink = element_make_or_warn ("gtksink", "video-sink");
+  }
+
   audio_sink = element_make_or_warn ("autoaudiosink", "audio-sink");
 
   if (!bvw->play ||
       !bvw->audio_pitchcontrol ||
       !bvw->video_sink ||
       !audio_sink ||
-      !glsinkbin) {
+      (bvw->use_gl && !glsinkbin)) {
     if (bvw->video_sink)
       g_object_ref_sink (bvw->video_sink);
     if (audio_sink)
@@ -5595,23 +5684,34 @@
   if (is_feature_enabled ("FPS_DISPLAY")) {
     GstElement *fps;
     fps = gst_element_factory_make ("fpsdisplaysink", "fpsdisplaysink");
-    g_object_set (glsinkbin, "sink", fps, NULL);
+
+    if (bvw->use_gl)
+      g_object_set (glsinkbin, "sink", fps, NULL);
+    else
+      g_object_set (bvw->play, "video-sink", fps, NULL);
+
     g_object_set (fps, "video-sink", bvw->video_sink, NULL);
   } else {
-    g_object_set (glsinkbin, "sink", bvw->video_sink, NULL);
+    if (bvw->use_gl)
+      g_object_set (glsinkbin, "sink", bvw->video_sink, NULL);
+    else
+      g_object_set (bvw->play, "video-sink", bvw->video_sink, NULL);
   }
+
   g_object_get (bvw->video_sink, "widget", &bvw->video_widget, NULL);
   gtk_widget_show (bvw->video_widget);
   gtk_stack_add_named (GTK_STACK (bvw->stack), bvw->video_widget, "video");
   g_object_unref (bvw->video_widget);
   gtk_stack_set_visible_child_name (GTK_STACK (bvw->stack), "video");
 
-  g_object_set (bvw->video_sink,
-                "rotate-method", GST_VIDEO_ORIENTATION_AUTO,
-                NULL);
+  if (bvw->use_gl)
+    g_object_set (bvw->video_sink,
+                  "rotate-method", GST_VIDEO_ORIENTATION_AUTO,
+                  NULL);
 
   /* And tell playbin */
-  g_object_set (bvw->play, "video-sink", glsinkbin, NULL);
+  if (bvw->use_gl)
+    g_object_set (bvw->play, "video-sink", glsinkbin, NULL);
 
   /* Link the audiopitch element */
   bvw->audio_capsfilter =
diff -Nru totem-43.1/src/backend/bacon-video-widget.h totem-43.2/src/backend/bacon-video-widget.h
--- totem-43.1/src/backend/bacon-video-widget.h	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/backend/bacon-video-widget.h	2025-05-21 14:08:29.000000000 +0100
@@ -282,6 +282,8 @@
 void bacon_video_widget_set_rotation		 (BaconVideoWidget *bvw,
 						  BvwRotation       rotation);
 BvwRotation bacon_video_widget_get_rotation	 (BaconVideoWidget *bvw);
+gboolean bacon_video_widget_use_gl	         (BaconVideoWidget *bvw);
+
 
 int bacon_video_widget_get_video_property        (BaconVideoWidget *bvw,
 						  BvwVideoProperty type);
diff -Nru totem-43.1/src/backend/meson.build totem-43.2/src/backend/meson.build
--- totem-43.1/src/backend/meson.build	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/backend/meson.build	2025-05-21 14:08:29.000000000 +0100
@@ -2,7 +2,7 @@
 
 gst_inspect = find_program(
   'gst-inspect-1.0',
-  join_paths(gst_dep.get_pkgconfig_variable('toolsdir'), 'gst-inspect-1.0'),
+  join_paths(gst_dep.get_variable(pkgconfig : 'toolsdir'), 'gst-inspect-1.0'),
   required: false
 )
 
@@ -23,6 +23,7 @@
 gst_good_plugins = [
   'autoaudiosink',
   'scaletempo',
+  'gtksink',
   'gtkglsink',
   'glsinkbin'
 ]
@@ -73,6 +74,7 @@
   libtotem_time_helpers_dep,
   gtk_dep,
   gmodule_dep,
+  dependency('epoxy'),
 ]
 
 libbacon_video_widget_cflags = common_flags + warn_flags + [
diff -Nru totem-43.1/src/gst/totem-gst-pixbuf-helpers.c totem-43.2/src/gst/totem-gst-pixbuf-helpers.c
--- totem-43.1/src/gst/totem-gst-pixbuf-helpers.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/gst/totem-gst-pixbuf-helpers.c	2025-05-21 14:08:29.000000000 +0100
@@ -47,290 +47,12 @@
   gst_sample_unref (GST_SAMPLE (data));
 }
 
-static gboolean
-caps_are_raw (const GstCaps * caps)
-{
-  guint i, len;
-
-  len = gst_caps_get_size (caps);
-
-  for (i = 0; i < len; i++) {
-    GstStructure *st = gst_caps_get_structure (caps, i);
-    if (gst_structure_has_name (st, "video/x-raw"))
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-static gboolean
-create_element (const gchar * factory_name, GstElement ** element,
-    GError ** err)
-{
-  *element = gst_element_factory_make (factory_name, NULL);
-  if (*element)
-    return TRUE;
-
-  if (err && *err == NULL) {
-    *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN,
-        "cannot create element '%s' - please check your GStreamer installation",
-        factory_name);
-  }
-
-  return FALSE;
-}
-
-static GstElement *
-build_convert_frame_pipeline (FrameCaptureType capture_type,
-    GstElement ** src_element,
-    GstElement ** sink_element, const GstCaps * from_caps,
-    const GstCaps * to_caps, GError ** err)
-{
-  GstElement *csp = NULL, *vscale = NULL;
-  GstElement *src = NULL, *sink = NULL, *dl = NULL, *pipeline;
-  GError *error = NULL;
-  gboolean ret;
-
-  if (!caps_are_raw (to_caps))
-    goto no_pipeline;
-
-  /* videoscale is here to correct for the pixel-aspect-ratio for us */
-  GST_DEBUG ("creating elements");
-  if (!create_element ("appsrc", &src, &error) ||
-      !create_element ("appsink", &sink, &error))
-    goto no_elements;
-  if (capture_type == FRAME_CAPTURE_TYPE_RAW) {
-      if (!create_element ("videoconvert", &csp, &error) ||
-          !create_element ("videoscale", &vscale, &error))
-        goto no_elements;
-   } else {
-     if (!create_element ("glcolorconvert", &csp, &error) ||
-         !create_element ("glcolorscale", &vscale, &error) ||
-         !create_element ("gldownload", &dl, &error))
-       goto no_elements;
-   }
-
-  pipeline = gst_pipeline_new ("videoconvert-pipeline");
-  if (pipeline == NULL)
-    goto no_pipeline;
-
-  /* Add black borders if necessary to keep the DAR */
-  if (g_object_class_find_property (G_OBJECT_GET_CLASS (vscale), "add-borders"))
-    g_object_set (vscale, "add-borders", TRUE, NULL);
-
-  GST_DEBUG ("adding elements");
-  gst_bin_add_many (GST_BIN (pipeline), src, csp, vscale, sink, dl, NULL);
-
-  /* set caps */
-  g_object_set (src, "caps", from_caps, NULL);
-  g_object_set (sink, "caps", to_caps, NULL);
-
-  if (dl)
-    ret = gst_element_link_many (src, csp, vscale, dl, sink, NULL);
-  else
-    ret = gst_element_link_many (src, csp, vscale, sink, NULL);
-  if (!ret)
-    goto link_failed;
-
-  g_object_set (src, "emit-signals", TRUE, NULL);
-  g_object_set (sink, "emit-signals", TRUE, NULL);
-
-  *src_element = src;
-  *sink_element = sink;
-
-  return pipeline;
-  /* ERRORS */
-no_elements:
-  {
-    if (src)
-      gst_object_unref (src);
-    if (csp)
-      gst_object_unref (csp);
-    if (vscale)
-      gst_object_unref (vscale);
-    if (dl)
-      gst_object_unref (dl);
-    if (sink)
-      gst_object_unref (sink);
-    GST_ERROR ("Could not convert video frame: %s", error->message);
-    if (err)
-      *err = error;
-    else
-      g_error_free (error);
-    return NULL;
-  }
-no_pipeline:
-  {
-    gst_object_unref (src);
-    gst_object_unref (csp);
-    gst_object_unref (vscale);
-    g_clear_pointer (&dl, gst_object_unref);
-    gst_object_unref (sink);
-
-    GST_ERROR ("Could not convert video frame: no pipeline (unknown error)");
-    if (err)
-      *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
-          "Could not convert video frame: no pipeline (unknown error)");
-    return NULL;
-  }
-link_failed:
-  {
-    gst_object_unref (pipeline);
-
-    GST_ERROR ("Could not convert video frame: failed to link elements");
-    if (err)
-      *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
-          "Could not convert video frame: failed to link elements");
-    return NULL;
-  }
-}
-
-/**
- * totem_gst_video_convert_sample:
- * @capture_type: capture type
- * @sample: a #GstSample
- * @to_caps: the #GstCaps to convert to
- * @timeout: the maximum amount of time allowed for the processing.
- * @error: pointer to a #GError. Can be %NULL.
- *
- * Converts a raw video buffer into the specified output caps.
- *
- * The output caps can be any raw video formats or any image formats (jpeg, png, ...).
- *
- * The width, height and pixel-aspect-ratio can also be specified in the output caps.
- *
- * Returns: The converted #GstSample, or %NULL if an error happened (in which case @err
- * will point to the #GError).
- */
-static GstSample *
-totem_gst_video_convert_sample (FrameCaptureType capture_type,
-				GstSample * sample, const GstCaps * to_caps,
-				GstClockTime timeout, GError ** error)
-{
-  GstMessage *msg;
-  GstBuffer *buf;
-  GstSample *result = NULL;
-  GError *err = NULL;
-  GstBus *bus;
-  GstCaps *from_caps, *to_caps_copy = NULL;
-  GstFlowReturn ret;
-  GstElement *pipeline, *src, *sink;
-  guint i, n;
-
-  g_return_val_if_fail (sample != NULL, NULL);
-  g_return_val_if_fail (to_caps != NULL, NULL);
-
-  buf = gst_sample_get_buffer (sample);
-  g_return_val_if_fail (buf != NULL, NULL);
-
-  from_caps = gst_sample_get_caps (sample);
-  g_return_val_if_fail (from_caps != NULL, NULL);
-
-  to_caps_copy = gst_caps_new_empty ();
-  n = gst_caps_get_size (to_caps);
-  for (i = 0; i < n; i++) {
-    GstStructure *s = gst_caps_get_structure (to_caps, i);
-
-    s = gst_structure_copy (s);
-    gst_structure_remove_field (s, "framerate");
-    gst_caps_append_structure (to_caps_copy, s);
-  }
-
-  pipeline =
-      build_convert_frame_pipeline (capture_type, &src, &sink, from_caps,
-      to_caps_copy, &err);
-  if (!pipeline)
-    goto no_pipeline;
-
-  /* now set the pipeline to the paused state, after we push the buffer into
-   * appsrc, this should preroll the converted buffer in appsink */
-  GST_DEBUG ("running conversion pipeline to caps %" GST_PTR_FORMAT,
-      to_caps_copy);
-  if (gst_element_set_state (pipeline,
-          GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE)
-    goto state_change_failed;
-
-  /* feed buffer in appsrc */
-  GST_DEBUG ("feeding buffer %p, size %" G_GSIZE_FORMAT ", caps %"
-      GST_PTR_FORMAT, buf, gst_buffer_get_size (buf), from_caps);
-  g_signal_emit_by_name (src, "push-buffer", buf, &ret);
-
-  /* now see what happens. We either got an error somewhere or the pipeline
-   * prerolled */
-  bus = gst_element_get_bus (pipeline);
-  msg = gst_bus_timed_pop_filtered (bus,
-      timeout, GST_MESSAGE_ERROR | GST_MESSAGE_ASYNC_DONE);
-
-  if (msg) {
-    switch (GST_MESSAGE_TYPE (msg)) {
-      case GST_MESSAGE_ASYNC_DONE:
-      {
-        /* we're prerolled, get the frame from appsink */
-        g_signal_emit_by_name (sink, "pull-preroll", &result);
-
-        if (result) {
-          GST_DEBUG ("conversion successful: result = %p", result);
-        } else {
-          GST_ERROR ("prerolled but no result frame?!");
-        }
-        break;
-      }
-      case GST_MESSAGE_ERROR:{
-        gchar *dbg = NULL;
-
-        gst_message_parse_error (msg, &err, &dbg);
-        if (err) {
-          GST_ERROR ("Could not convert video frame: %s", err->message);
-          GST_DEBUG ("%s [debug: %s]", err->message, GST_STR_NULL (dbg));
-          if (error)
-            *error = err;
-          else
-            g_error_free (err);
-        }
-        g_free (dbg);
-        break;
-      }
-      default:{
-        g_return_val_if_reached (NULL);
-      }
-    }
-    gst_message_unref (msg);
-  } else {
-    GST_ERROR ("Could not convert video frame: timeout during conversion");
-    if (error)
-      *error = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
-          "Could not convert video frame: timeout during conversion");
-  }
-
-  gst_element_set_state (pipeline, GST_STATE_NULL);
-  gst_object_unref (bus);
-  gst_object_unref (pipeline);
-  gst_caps_unref (to_caps_copy);
-
-  return result;
-
-  /* ERRORS */
-no_pipeline:
-state_change_failed:
-  {
-    gst_caps_unref (to_caps_copy);
-
-    if (error)
-      *error = err;
-    else
-      g_error_free (err);
-
-    return NULL;
-  }
-}
-
 GdkPixbuf *
 totem_gst_playbin_get_frame (GstElement *play, GError **error)
 {
   FrameCaptureType capture_type;
   GstStructure *s;
   GstSample *sample = NULL;
-  GstSample *last_sample = NULL;
   guint bpp;
   GdkPixbuf *pixbuf = NULL;
   GstCaps *to_caps, *sample_caps;
@@ -359,19 +81,12 @@
       NULL);
 
   /* get frame */
-  g_object_get (G_OBJECT (play), "sample", &last_sample, NULL);
-  if (!last_sample) {
-    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                         "Failed to retrieve video frame");
-    return NULL;
-  }
-  sample = totem_gst_video_convert_sample (capture_type, last_sample, to_caps, 25 * GST_SECOND, error);
-  gst_sample_unref (last_sample);
+  g_signal_emit_by_name (play, "convert-sample", to_caps, &sample);
   gst_caps_unref (to_caps);
 
   if (!sample) {
     g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                         "Failed to convert video frame");
+                         "Failed to retrieve or convert video frame");
     return NULL;
   }
 
diff -Nru totem-43.1/src/icon-helpers.c totem-43.2/src/icon-helpers.c
--- totem-43.1/src/icon-helpers.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/icon-helpers.c	2025-05-21 14:08:29.000000000 +0100
@@ -30,7 +30,7 @@
 #define GNOME_DESKTOP_USE_UNSTABLE_API 1
 #include <libgnome-desktop/gnome-desktop-thumbnail.h>
 
-#define DEFAULT_MAX_THREADS   1
+#define DEFAULT_MAX_THREADS   g_get_num_processors ()
 #define THUMB_SEARCH_SIZE     256
 #define THUMB_SEARCH_HEIGHT   THUMB_SEARCH_SIZE
 #define SOURCES_MAX_HEIGHT    64
diff -Nru totem-43.1/src/plugins/open-directory/totem-open-directory.c totem-43.2/src/plugins/open-directory/totem-open-directory.c
--- totem-43.1/src/plugins/open-directory/totem-open-directory.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/plugins/open-directory/totem-open-directory.c	2025-05-21 14:08:29.000000000 +0100
@@ -135,11 +135,17 @@
 	GMenu *menu;
 	GMenuItem *item;
 	char *mrl;
+	g_autoptr(GError) error = NULL;
 
 	pi->totem = g_object_get_data (G_OBJECT (plugin), "object");
-	pi->portal = xdp_portal_new ();
+	pi->portal = xdp_portal_initable_new (&error);
 	pi->cancellable = g_cancellable_new ();
 
+	if (error) {
+		g_warning ("Failed to create XdpPortal instance: %s", error->message);
+		return;
+	}
+
 	g_signal_connect (pi->totem,
 			  "file-opened",
 			  G_CALLBACK (totem_open_directory_file_opened),
diff -Nru totem-43.1/src/plugins/pythonconsole/console.py totem-43.2/src/plugins/pythonconsole/console.py
--- totem-43.1/src/plugins/pythonconsole/console.py	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/plugins/pythonconsole/console.py	2025-05-21 14:08:29.000000000 +0100
@@ -291,7 +291,8 @@
             except SyntaxError:
                 exec(command, self.namespace) # pylint: disable=W0122
         except: # pylint: disable=W0702
-            if hasattr(sys, 'last_type') and sys.last_type == SystemExit: # pylint: disable=E1101
+            last_type, = sys.exc_info()
+            if last_type == SystemExit:
                 self.destroy()
             else:
                 traceback.print_exc()
diff -Nru totem-43.1/src/plugins/recent/totem-recent.c totem-43.2/src/plugins/recent/totem-recent.c
--- totem-43.1/src/plugins/recent/totem-recent.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/plugins/recent/totem-recent.c	2025-05-21 14:08:29.000000000 +0100
@@ -80,7 +80,7 @@
 	}
 
 	data.app_name = g_strdup (g_get_application_name ());
-	data.app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL);
+	data.app_exec = g_strdup ("totem %u");
 	data.groups = groups;
 	if (gtk_recent_manager_add_full (pi->recent_manager,
 					 uri, &data) == FALSE) {
diff -Nru totem-43.1/src/plugins/rotation/totem-rotation.c totem-43.2/src/plugins/rotation/totem-rotation.c
--- totem-43.1/src/plugins/rotation/totem-rotation.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/plugins/rotation/totem-rotation.c	2025-05-21 14:08:29.000000000 +0100
@@ -219,6 +219,11 @@
 
 	pi->totem = g_object_get_data (G_OBJECT (plugin), "object");
 	pi->bvw = totem_object_get_video_widget (pi->totem);
+
+	/* rotate-method is not supported by gtksink */
+	if (!bacon_video_widget_use_gl (BACON_VIDEO_WIDGET (pi->bvw)))
+		return;
+
 	pi->cancellable = g_cancellable_new ();
 
 	g_signal_connect (pi->totem,
@@ -290,5 +295,5 @@
 	g_action_map_remove_action (G_ACTION_MAP (pi->totem), "rotate-right");
 
 	pi->totem = NULL;
-	pi->bvw = NULL;
+	g_clear_object (&pi->bvw);
 }
diff -Nru totem-43.1/src/plugins/save-file/totem-save-file.c totem-43.2/src/plugins/save-file/totem-save-file.c
--- totem-43.1/src/plugins/save-file/totem-save-file.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/plugins/save-file/totem-save-file.c	2025-05-21 14:08:29.000000000 +0100
@@ -477,7 +477,7 @@
 	}
 
 	pi->totem = NULL;
-	pi->bvw = NULL;
+	g_clear_object (&pi->bvw);
 
 	g_clear_pointer (&pi->mrl, g_free);
 	g_clear_pointer (&pi->cache_mrl, g_free);
diff -Nru totem-43.1/src/plugins/screenshot/totem-screenshot-plugin.c totem-43.2/src/plugins/screenshot/totem-screenshot-plugin.c
--- totem-43.1/src/plugins/screenshot/totem-screenshot-plugin.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/plugins/screenshot/totem-screenshot-plugin.c	2025-05-21 14:08:29.000000000 +0100
@@ -152,51 +152,6 @@
 	g_object_unref (save_file);
 }
 
-static void
-flash_area_done_cb (GObject *source_object,
-		    GAsyncResult *res,
-		    gpointer user_data)
-{
-	GVariant *variant;
-
-	variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, NULL);
-	if (variant != NULL)
-		g_variant_unref (variant);
-}
-
-static void
-flash_area (GtkWidget *widget)
-{
-	GDBusProxy *proxy;
-	GdkWindow *window;
-	int x, y, w, h;
-
-	window = gtk_widget_get_window (widget);
-	gdk_window_get_origin (window, &x, &y);
-	w = gdk_window_get_width (window);
-	h = gdk_window_get_height (window);
-
-	proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-					       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
-					       G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
-					       G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-					       NULL,
-					       "org.gnome.Shell",
-					       "/org/gnome/Shell/Screenshot",
-					       "org.gnome.Shell.Screenshot",
-					       NULL, NULL);
-	if (proxy == NULL)
-		g_warning ("no proxy");
-
-	g_dbus_proxy_call (proxy, "org.gnome.Shell.Screenshot.FlashArea",
-			   g_variant_new ("(iiii)", x, y, w, h),
-			   G_DBUS_CALL_FLAGS_NO_AUTO_START,
-			   -1,
-			   NULL,
-			   flash_area_done_cb,
-			   NULL);
-}
-
 static char *
 escape_video_name (const char *orig)
 {
@@ -224,8 +179,6 @@
 		return;
 	}
 
-	flash_area (GTK_WIDGET (pi->bvw));
-
 	pixbuf = bacon_video_widget_get_current_frame (pi->bvw);
 	if (pixbuf == NULL) {
 		totem_object_show_error (pi->totem, _("Videos could not get a screenshot of the video."), _("This is not supposed to happen; please file a bug report."));
diff -Nru totem-43.1/src/totem.c totem-43.2/src/totem.c
--- totem-43.1/src/totem.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/totem.c	2025-05-21 14:08:29.000000000 +0100
@@ -47,7 +47,7 @@
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 	textdomain (GETTEXT_PACKAGE);
 
-	g_set_prgname ("totem");
+	g_set_prgname (APPLICATION_ID);
 #if DEVELOPMENT_VERSION
 	g_set_application_name (_("Videos Preview"));
 #else
diff -Nru totem-43.1/src/totem-object.c totem-43.2/src/totem-object.c
--- totem-43.1/src/totem-object.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/totem-object.c	2025-05-21 14:08:29.000000000 +0100
@@ -268,8 +268,6 @@
 
 	totem_callback_connect (totem);
 
-	gtk_widget_grab_focus (GTK_WIDGET (totem->bvw));
-
 	/* The prefs after the video widget is connected */
 	totem->prefs = totem_preferences_dialog_new (totem);
 	gtk_window_set_transient_for (GTK_WINDOW (totem->prefs), GTK_WINDOW(totem->win));
@@ -1077,6 +1075,8 @@
 		gtk_widget_show (totem->subtitles_button);
 		gtk_widget_hide (totem->add_button);
 		gtk_widget_hide (totem->main_menu_button);
+
+		gtk_widget_grab_focus (GTK_WIDGET (totem->bvw));
 		show_popup (totem);
 	} else if (g_strcmp0 (page_id, "grilo") == 0) {
 		totem_grilo_start (TOTEM_GRILO (totem->grilo));
@@ -1379,8 +1379,11 @@
 	if (totem == NULL)
 		exit (0);
 
-	if (totem->bvw)
+	if (totem->bvw) {
 		totem_object_save_size (totem);
+		bacon_video_widget_close (totem->bvw);
+		g_clear_object (&totem->bvw);
+	}
 
 	if (totem->win != NULL) {
 		gtk_widget_hide (totem->win);
diff -Nru totem-43.1/src/totem-playlist.c totem-43.2/src/totem-playlist.c
--- totem-43.1/src/totem-playlist.c	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/totem-playlist.c	2025-05-21 14:08:29.000000000 +0100
@@ -1744,7 +1744,7 @@
 	 * hence the "steal" in the API name */
 	gtk_list_store_set (GTK_LIST_STORE (playlist->model),
 			    &iter,
-			    STARTTIME_COL, 0,
+			    STARTTIME_COL, (gint64) 0,
 			    -1);
 
 	return starttime;
diff -Nru totem-43.1/src/totem-resources.c totem-43.2/src/totem-resources.c
--- totem-43.1/src/totem-resources.c	2025-06-11 11:27:22.000000000 +0100
+++ totem-43.2/src/totem-resources.c	2025-05-21 14:08:29.000000000 +0100
@@ -49,7 +49,7 @@
 static gboolean finished = TRUE;
 
 static void
-set_resource_limits (const char *input)
+set_resource_limits (const char *input, gboolean verbose)
 {
 #ifdef G_OS_UNIX
 	struct rlimit limit;
@@ -81,6 +81,10 @@
 	limit.rlim_cur = MAX_HELPER_SECONDS;
 	limit.rlim_max = MAX_HELPER_SECONDS;
 	setrlimit (RLIMIT_CPU, &limit);
+
+	if (verbose)
+		g_message ("Setting limit to %lu MB RAM usage and %d seconds CPU time",
+			   max / 1024 / 1024, MAX_HELPER_SECONDS);
 #else
 #warning unimplemented
 #endif
@@ -108,9 +112,9 @@
 }
 
 void
-totem_resources_monitor_start (const char *input, gint wall_clock_time)
+totem_resources_monitor_start (const char *input, gint wall_clock_time, gboolean verbose)
 {
-	set_resource_limits (input);
+	set_resource_limits (input, verbose);
 
 	if (wall_clock_time < 0)
 		return;
diff -Nru totem-43.1/src/totem-resources.h totem-43.2/src/totem-resources.h
--- totem-43.1/src/totem-resources.h	2024-10-22 17:04:07.000000000 +0100
+++ totem-43.2/src/totem-resources.h	2025-05-21 14:08:29.000000000 +0100
@@ -28,6 +28,7 @@
 #include <glib.h>
 
 void totem_resources_monitor_start	(const char *input,
-					 gint wall_clock_time);
+					 gint wall_clock_time,
+					 gboolean verbose);
 void totem_resources_monitor_stop	(void);
 
diff -Nru totem-43.1/src/totem-video-thumbnailer.c totem-43.2/src/totem-video-thumbnailer.c
--- totem-43.1/src/totem-video-thumbnailer.c	2025-06-11 11:27:22.000000000 +0100
+++ totem-43.2/src/totem-video-thumbnailer.c	2025-05-21 14:08:29.000000000 +0100
@@ -377,6 +377,9 @@
 	return async_received;
 }
 
+/* Manually set number of worker threads for decoders in order to reduce memory
+ * usage on setups with many cores, see
+ * https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4423 */
 static void
 element_setup_cb (GstElement * playbin, GstElement * element, gpointer udata)
 {
@@ -637,14 +640,8 @@
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 	textdomain (GETTEXT_PACKAGE);
 
-	/* Limit the number of BLAS threads to avoid reaching our RLIMIT_DATA
-	 * address space max size safeguard for the thumbnailer.
-	 * This as GStreamer plugins call into OpenBLAS for linear algebra
-	 * which automatically spawns as many threads as there are CPU cores
-	 * and allocates static buffers for each of them.
-	 * Thus our 512MB address space limit is too short for the video
-	 * file size plus the currently 128 MB per OpenBLAS thread
-	 * when we reach 4 CPU cores. */
+	/* Limit the number of OpenBLAS threads to avoid reaching our RLIMIT_DATA
+	 * address space max size safeguard for the thumbnailer. */
 	g_setenv("OMP_NUM_THREADS", "1", TRUE);
 
 	/* Call before the global thread pool is setup */
@@ -695,7 +692,7 @@
 	PRINT_PROGRESS (6.0);
 
 	if (time_limit != FALSE)
-		totem_resources_monitor_start (input, 0);
+		totem_resources_monitor_start (input, 0, verbose);
 
 	PROGRESS_DEBUG("About to open video file");
 

Reply via email to