From 39e1e26a3907bd223f60554a14eb0f5ce93703ff Mon Sep 17 00:00:00 2001 From: Ali Abdallah Date: Sat, 8 Sep 2018 01:27:48 +0200 Subject: Added stat check to try to skip sparse files. Sparse files, especially sparse video files, cause high cpu and memory load when trying to get a thumbnail image out of them, using gst or ffmpeg plugins. For non sparse files, usually ((double)S_BLKSIZE * sb.st_blocks / sb.st_size) = 1.0, but this is not always true, for example on file systems that support compression, the ratio can be lower (ex. on ZFS), but not by too much for already compressed video and image files. We assume video files with ratio lower than 0.8 to be sparse and we avoid them. Video files with ratio higher than 0.8 usually have enough valid video frames, so getting a thumbnail out of them always succeeds. This commit should fix bug #12259. --- tumblerd/tumbler-registry.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'tumblerd') diff --git a/tumblerd/tumbler-registry.c b/tumblerd/tumbler-registry.c index 77bc74f..c1337af 100644 --- a/tumblerd/tumbler-registry.c +++ b/tumblerd/tumbler-registry.c @@ -1,6 +1,7 @@ /* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2009-2011 Jannis Pohlmann + * Copyright (c) 2018 Ali Abdallah * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -25,13 +26,16 @@ #include #include +#include + #include #include #include #include - +/* Float block size used in the stat struct */ +#define TUMBLER_STAT_BLKSIZE 512. static void tumbler_registry_finalize (GObject *object); static void tumbler_registry_remove_thumbnailer (const gchar *key, @@ -461,11 +465,37 @@ tumbler_registry_get_thumbnailer_array (TumblerRegistry *registry, /* iterate over all URIs */ for (n = 0; n < length; ++n) { + gchar *filename; + struct stat sb; + g_assert (TUMBLER_IS_FILE_INFO (infos[n])); /* reset */ file_size = 0; + filename = g_filename_from_uri (tumbler_file_info_get_uri (infos[n]), NULL, NULL); + + if (G_LIKELY(filename)) + { + stat (filename, &sb); + + g_free (filename); + + if (!S_ISREG (sb.st_mode)) + continue; + + if (((TUMBLER_STAT_BLKSIZE * sb.st_blocks) / sb.st_size) < 0.8) + { + g_debug ("'%s' is probably a sparse file, skipping\n", tumbler_file_info_get_uri (infos[n])); + continue; + } + } + else + { + g_warning ("Failed to get filename from uri for '%s', skipping\n", tumbler_file_info_get_uri (infos[n])); + continue; + } + /* determine the URI scheme and generate a hash key */ gfile = g_file_new_for_uri (tumbler_file_info_get_uri (infos[n])); scheme = g_file_get_uri_scheme (gfile); -- cgit v1.2.1